File ‹Tools/int_arith.ML›
signature INT_ARITH =
sig
val zero_one_idom_simproc: simproc
end
structure Int_Arith : INT_ARITH =
struct
val zero_to_of_int_zero_simproc =
\<^simproc_setup>‹passive zero_to_of_int_zero ("0::'a::ring") =
‹fn _ => fn _ => fn ct =>
let val T = Thm.ctyp_of_cterm ct in
if Thm.typ_of T = \<^Type>‹int› then NONE
else SOME \<^instantiate>‹'a = T in lemma "0 ≡ of_int 0" by simp›
end››;
val one_to_of_int_one_simproc =
\<^simproc_setup>‹passive one_to_of_int_one ("1::'a::ring_1") =
‹fn _ => fn _ => fn ct =>
let val T = Thm.ctyp_of_cterm ct in
if Thm.typ_of T = \<^Type>‹int› then NONE
else SOME \<^instantiate>‹'a = T in lemma "1 ≡ of_int 1" by simp›
end››;
fun check \<^Const_>‹Groups.one \<^Type>‹int›› = false
| check \<^Const_>‹Groups.one _› = true
| check \<^Const_>‹Groups.zero _› = true
| check \<^Const_>‹HOL.eq _› = true
| check \<^Const_>‹times _› = true
| check \<^Const_>‹uminus _› = true
| check \<^Const_>‹minus _› = true
| check \<^Const_>‹plus _› = true
| check \<^Const_>‹less _› = true
| check \<^Const_>‹less_eq _› = true
| check (a $ b) = check a andalso check b
| check _ = false;
val conv_ss =
\<^context>
|> put_simpset HOL_basic_ss
|> fold (Simplifier.add_simp o (fn th => th RS sym))
@{thms of_int_add of_int_mult
of_int_diff of_int_minus of_int_less_iff
of_int_le_iff of_int_eq_iff}
|> Simplifier.add_proc zero_to_of_int_zero_simproc
|> Simplifier.add_proc one_to_of_int_one_simproc
|> simpset_of;
val zero_one_idom_simproc =
\<^simproc_setup>‹passive zero_one_idom
("(x::'a::ring_char_0) = y" | "(u::'b::linordered_idom) < v" | "(u::'b::linordered_idom) ≤ v") =
‹fn _ => fn ctxt => fn ct =>
if check (Thm.term_of ct)
then SOME (Simplifier.rewrite (put_simpset conv_ss ctxt) ct)
else NONE››
end;