| author | wenzelm | 
| Sun, 08 Jun 2008 14:29:09 +0200 | |
| changeset 27090 | 2f45c1b1b05d | 
| parent 26086 | 3c243098b64a | 
| child 28262 | aa7ca36d67fd | 
| permissions | -rw-r--r-- | 
| 23164 | 1 | (* Title: HOL/int_arith1.ML | 
| 2 | ID: $Id$ | |
| 3 | Authors: Larry Paulson and Tobias Nipkow | |
| 4 | ||
| 5 | Simprocs and decision procedure for linear arithmetic. | |
| 6 | *) | |
| 7 | ||
| 8 | structure Int_Numeral_Base_Simprocs = | |
| 9 | struct | |
| 10 | fun prove_conv tacs ctxt (_: thm list) (t, u) = | |
| 11 | if t aconv u then NONE | |
| 12 | else | |
| 13 | let val eq = HOLogic.mk_Trueprop (HOLogic.mk_eq (t, u)) | |
| 14 | in SOME (Goal.prove ctxt [] [] eq (K (EVERY tacs))) end | |
| 15 | ||
| 16 | fun prove_conv_nohyps tacs sg = prove_conv tacs sg []; | |
| 17 | ||
| 18 | fun prep_simproc (name, pats, proc) = | |
| 19 | Simplifier.simproc (the_context()) name pats proc; | |
| 20 | ||
| 25919 
8b1c0d434824
joined theories IntDef, Numeral, IntArith to theory Int
 haftmann parents: 
25481diff
changeset | 21 |   fun is_numeral (Const(@{const_name Int.number_of}, _) $ w) = true
 | 
| 23164 | 22 | | is_numeral _ = false | 
| 23 | ||
| 24 | fun simplify_meta_eq f_number_of_eq f_eq = | |
| 25 | mk_meta_eq ([f_eq, f_number_of_eq] MRS trans) | |
| 26 | ||
| 27 | (*reorientation simprules using ==, for the following simproc*) | |
| 23881 | 28 |   val meta_zero_reorient = @{thm zero_reorient} RS eq_reflection
 | 
| 29 |   val meta_one_reorient = @{thm one_reorient} RS eq_reflection
 | |
| 25481 | 30 |   val meta_number_of_reorient = @{thm number_of_reorient} RS eq_reflection
 | 
| 23164 | 31 | |
| 32 | (*reorientation simplification procedure: reorients (polymorphic) | |
| 25919 
8b1c0d434824
joined theories IntDef, Numeral, IntArith to theory Int
 haftmann parents: 
25481diff
changeset | 33 | 0 = x, 1 = x, nnn = x provided x isn't 0, 1 or a Int.*) | 
| 23164 | 34 | fun reorient_proc sg _ (_ $ t $ u) = | 
| 35 | case u of | |
| 25481 | 36 |         Const(@{const_name HOL.zero}, _) => NONE
 | 
| 23164 | 37 |       | Const(@{const_name HOL.one}, _) => NONE
 | 
| 25919 
8b1c0d434824
joined theories IntDef, Numeral, IntArith to theory Int
 haftmann parents: 
25481diff
changeset | 38 |       | Const(@{const_name Int.number_of}, _) $ _ => NONE
 | 
| 23164 | 39 | | _ => SOME (case t of | 
| 25481 | 40 |           Const(@{const_name HOL.zero}, _) => meta_zero_reorient
 | 
| 41 |         | Const(@{const_name HOL.one}, _) => meta_one_reorient
 | |
| 25919 
8b1c0d434824
joined theories IntDef, Numeral, IntArith to theory Int
 haftmann parents: 
25481diff
changeset | 42 |         | Const(@{const_name Int.number_of}, _) $ _ => meta_number_of_reorient)
 | 
| 23164 | 43 | |
| 44 | val reorient_simproc = | |
| 45 |       prep_simproc ("reorient_simproc", ["0=x", "1=x", "number_of w = x"], reorient_proc)
 | |
| 46 | ||
| 47 | end; | |
| 48 | ||
| 49 | ||
| 50 | Addsimprocs [Int_Numeral_Base_Simprocs.reorient_simproc]; | |
| 51 | ||
| 52 | ||
| 53 | structure Int_Numeral_Simprocs = | |
| 54 | struct | |
| 55 | ||
| 56 | (*Maps 0 to Numeral0 and 1 to Numeral1 so that arithmetic in Int_Numeral_Base_Simprocs | |
| 57 | isn't complicated by the abstract 0 and 1.*) | |
| 25481 | 58 | val numeral_syms = [@{thm numeral_0_eq_0} RS sym, @{thm numeral_1_eq_1} RS sym];
 | 
| 23164 | 59 | |
| 60 | (** New term ordering so that AC-rewriting brings numerals to the front **) | |
| 61 | ||
| 62 | (*Order integers by absolute value and then by sign. The standard integer | |
| 63 | ordering is not well-founded.*) | |
| 64 | fun num_ord (i,j) = | |
| 24630 
351a308ab58d
simplified type int (eliminated IntInf.int, integer);
 wenzelm parents: 
24266diff
changeset | 65 | (case int_ord (abs i, abs j) of | 
| 
351a308ab58d
simplified type int (eliminated IntInf.int, integer);
 wenzelm parents: 
24266diff
changeset | 66 | EQUAL => int_ord (Int.sign i, Int.sign j) | 
| 
351a308ab58d
simplified type int (eliminated IntInf.int, integer);
 wenzelm parents: 
24266diff
changeset | 67 | | ord => ord); | 
| 23164 | 68 | |
| 69 | (*This resembles Term.term_ord, but it puts binary numerals before other | |
| 70 | non-atomic terms.*) | |
| 71 | local open Term | |
| 72 | in | |
| 73 | fun numterm_ord (Abs (_, T, t), Abs(_, U, u)) = | |
| 74 | (case numterm_ord (t, u) of EQUAL => typ_ord (T, U) | ord => ord) | |
| 75 | | numterm_ord | |
| 25919 
8b1c0d434824
joined theories IntDef, Numeral, IntArith to theory Int
 haftmann parents: 
25481diff
changeset | 76 |      (Const(@{const_name Int.number_of}, _) $ v, Const(@{const_name Int.number_of}, _) $ w) =
 | 
| 23164 | 77 | num_ord (HOLogic.dest_numeral v, HOLogic.dest_numeral w) | 
| 25919 
8b1c0d434824
joined theories IntDef, Numeral, IntArith to theory Int
 haftmann parents: 
25481diff
changeset | 78 |   | numterm_ord (Const(@{const_name Int.number_of}, _) $ _, _) = LESS
 | 
| 
8b1c0d434824
joined theories IntDef, Numeral, IntArith to theory Int
 haftmann parents: 
25481diff
changeset | 79 |   | numterm_ord (_, Const(@{const_name Int.number_of}, _) $ _) = GREATER
 | 
| 23164 | 80 | | numterm_ord (t, u) = | 
| 81 | (case int_ord (size_of_term t, size_of_term u) of | |
| 82 | EQUAL => | |
| 83 | let val (f, ts) = strip_comb t and (g, us) = strip_comb u in | |
| 84 | (case hd_ord (f, g) of EQUAL => numterms_ord (ts, us) | ord => ord) | |
| 85 | end | |
| 86 | | ord => ord) | |
| 87 | and numterms_ord (ts, us) = list_ord numterm_ord (ts, us) | |
| 88 | end; | |
| 89 | ||
| 90 | fun numtermless tu = (numterm_ord tu = LESS); | |
| 91 | ||
| 92 | (*Defined in this file, but perhaps needed only for Int_Numeral_Base_Simprocs of type nat.*) | |
| 93 | val num_ss = HOL_ss settermless numtermless; | |
| 94 | ||
| 95 | ||
| 96 | (** Utilities **) | |
| 97 | ||
| 98 | fun mk_number T n = HOLogic.number_of_const T $ HOLogic.mk_numeral n; | |
| 99 | ||
| 100 | fun find_first_numeral past (t::terms) = | |
| 101 | ((snd (HOLogic.dest_number t), rev past @ terms) | |
| 102 | handle TERM _ => find_first_numeral (t::past) terms) | |
| 103 |   | find_first_numeral past [] = raise TERM("find_first_numeral", []);
 | |
| 104 | ||
| 105 | val mk_plus = HOLogic.mk_binop @{const_name HOL.plus};
 | |
| 106 | ||
| 107 | fun mk_minus t = | |
| 108 | let val T = Term.fastype_of t | |
| 23400 
a64b39e5809b
The simprocs "divide_cancel_factor" and "ring_eq_cancel_factor" no
 nipkow parents: 
23365diff
changeset | 109 |   in Const (@{const_name HOL.uminus}, T --> T) $ t end;
 | 
| 23164 | 110 | |
| 111 | (*Thus mk_sum[t] yields t+0; longer sums don't have a trailing zero*) | |
| 112 | fun mk_sum T [] = mk_number T 0 | |
| 113 | | mk_sum T [t,u] = mk_plus (t, u) | |
| 114 | | mk_sum T (t :: ts) = mk_plus (t, mk_sum T ts); | |
| 115 | ||
| 116 | (*this version ALWAYS includes a trailing zero*) | |
| 117 | fun long_mk_sum T [] = mk_number T 0 | |
| 118 | | long_mk_sum T (t :: ts) = mk_plus (t, mk_sum T ts); | |
| 119 | ||
| 120 | val dest_plus = HOLogic.dest_bin @{const_name HOL.plus} Term.dummyT;
 | |
| 121 | ||
| 122 | (*decompose additions AND subtractions as a sum*) | |
| 123 | fun dest_summing (pos, Const (@{const_name HOL.plus}, _) $ t $ u, ts) =
 | |
| 124 | dest_summing (pos, t, dest_summing (pos, u, ts)) | |
| 125 |   | dest_summing (pos, Const (@{const_name HOL.minus}, _) $ t $ u, ts) =
 | |
| 126 | dest_summing (pos, t, dest_summing (not pos, u, ts)) | |
| 127 | | dest_summing (pos, t, ts) = | |
| 128 | if pos then t::ts else mk_minus t :: ts; | |
| 129 | ||
| 130 | fun dest_sum t = dest_summing (true, t, []); | |
| 131 | ||
| 132 | val mk_diff = HOLogic.mk_binop @{const_name HOL.minus};
 | |
| 133 | val dest_diff = HOLogic.dest_bin @{const_name HOL.minus} Term.dummyT;
 | |
| 134 | ||
| 135 | val mk_times = HOLogic.mk_binop @{const_name HOL.times};
 | |
| 136 | ||
| 23400 
a64b39e5809b
The simprocs "divide_cancel_factor" and "ring_eq_cancel_factor" no
 nipkow parents: 
23365diff
changeset | 137 | fun one_of T = Const(@{const_name HOL.one},T);
 | 
| 
a64b39e5809b
The simprocs "divide_cancel_factor" and "ring_eq_cancel_factor" no
 nipkow parents: 
23365diff
changeset | 138 | |
| 
a64b39e5809b
The simprocs "divide_cancel_factor" and "ring_eq_cancel_factor" no
 nipkow parents: 
23365diff
changeset | 139 | (* build product with trailing 1 rather than Numeral 1 in order to avoid the | 
| 
a64b39e5809b
The simprocs "divide_cancel_factor" and "ring_eq_cancel_factor" no
 nipkow parents: 
23365diff
changeset | 140 | unnecessary restriction to type class number_ring | 
| 
a64b39e5809b
The simprocs "divide_cancel_factor" and "ring_eq_cancel_factor" no
 nipkow parents: 
23365diff
changeset | 141 | which is not required for cancellation of common factors in divisions. | 
| 
a64b39e5809b
The simprocs "divide_cancel_factor" and "ring_eq_cancel_factor" no
 nipkow parents: 
23365diff
changeset | 142 | *) | 
| 23164 | 143 | fun mk_prod T = | 
| 23400 
a64b39e5809b
The simprocs "divide_cancel_factor" and "ring_eq_cancel_factor" no
 nipkow parents: 
23365diff
changeset | 144 | let val one = one_of T | 
| 23164 | 145 | fun mk [] = one | 
| 146 | | mk [t] = t | |
| 147 | | mk (t :: ts) = if t = one then mk ts else mk_times (t, mk ts) | |
| 148 | in mk end; | |
| 149 | ||
| 150 | (*This version ALWAYS includes a trailing one*) | |
| 23400 
a64b39e5809b
The simprocs "divide_cancel_factor" and "ring_eq_cancel_factor" no
 nipkow parents: 
23365diff
changeset | 151 | fun long_mk_prod T [] = one_of T | 
| 23164 | 152 | | long_mk_prod T (t :: ts) = mk_times (t, mk_prod T ts); | 
| 153 | ||
| 154 | val dest_times = HOLogic.dest_bin @{const_name HOL.times} Term.dummyT;
 | |
| 155 | ||
| 156 | fun dest_prod t = | |
| 157 | let val (t,u) = dest_times t | |
| 23400 
a64b39e5809b
The simprocs "divide_cancel_factor" and "ring_eq_cancel_factor" no
 nipkow parents: 
23365diff
changeset | 158 | in dest_prod t @ dest_prod u end | 
| 23164 | 159 | handle TERM _ => [t]; | 
| 160 | ||
| 161 | (*DON'T do the obvious simplifications; that would create special cases*) | |
| 162 | fun mk_coeff (k, t) = mk_times (mk_number (Term.fastype_of t) k, t); | |
| 163 | ||
| 164 | (*Express t as a product of (possibly) a numeral with other sorted terms*) | |
| 165 | fun dest_coeff sign (Const (@{const_name HOL.uminus}, _) $ t) = dest_coeff (~sign) t
 | |
| 166 | | dest_coeff sign t = | |
| 167 | let val ts = sort Term.term_ord (dest_prod t) | |
| 168 | val (n, ts') = find_first_numeral [] ts | |
| 169 | handle TERM _ => (1, ts) | |
| 170 | in (sign*n, mk_prod (Term.fastype_of t) ts') end; | |
| 171 | ||
| 172 | (*Find first coefficient-term THAT MATCHES u*) | |
| 173 | fun find_first_coeff past u [] = raise TERM("find_first_coeff", [])
 | |
| 174 | | find_first_coeff past u (t::terms) = | |
| 175 | let val (n,u') = dest_coeff 1 t | |
| 23400 
a64b39e5809b
The simprocs "divide_cancel_factor" and "ring_eq_cancel_factor" no
 nipkow parents: 
23365diff
changeset | 176 | in if u aconv u' then (n, rev past @ terms) | 
| 
a64b39e5809b
The simprocs "divide_cancel_factor" and "ring_eq_cancel_factor" no
 nipkow parents: 
23365diff
changeset | 177 | else find_first_coeff (t::past) u terms | 
| 23164 | 178 | end | 
| 179 | handle TERM _ => find_first_coeff (t::past) u terms; | |
| 180 | ||
| 181 | (*Fractions as pairs of ints. Can't use Rat.rat because the representation | |
| 182 | needs to preserve negative values in the denominator.*) | |
| 24630 
351a308ab58d
simplified type int (eliminated IntInf.int, integer);
 wenzelm parents: 
24266diff
changeset | 183 | fun mk_frac (p, q) = if q = 0 then raise Div else (p, q); | 
| 23164 | 184 | |
| 185 | (*Don't reduce fractions; sums must be proved by rule add_frac_eq. | |
| 186 | Fractions are reduced later by the cancel_numeral_factor simproc.*) | |
| 24630 
351a308ab58d
simplified type int (eliminated IntInf.int, integer);
 wenzelm parents: 
24266diff
changeset | 187 | fun add_frac ((p1, q1), (p2, q2)) = (p1 * q2 + p2 * q1, q1 * q2); | 
| 23164 | 188 | |
| 189 | val mk_divide = HOLogic.mk_binop @{const_name HOL.divide};
 | |
| 190 | ||
| 191 | (*Build term (p / q) * t*) | |
| 192 | fun mk_fcoeff ((p, q), t) = | |
| 193 | let val T = Term.fastype_of t | |
| 23400 
a64b39e5809b
The simprocs "divide_cancel_factor" and "ring_eq_cancel_factor" no
 nipkow parents: 
23365diff
changeset | 194 | in mk_times (mk_divide (mk_number T p, mk_number T q), t) end; | 
| 23164 | 195 | |
| 196 | (*Express t as a product of a fraction with other sorted terms*) | |
| 197 | fun dest_fcoeff sign (Const (@{const_name HOL.uminus}, _) $ t) = dest_fcoeff (~sign) t
 | |
| 198 |   | dest_fcoeff sign (Const (@{const_name HOL.divide}, _) $ t $ u) =
 | |
| 199 | let val (p, t') = dest_coeff sign t | |
| 200 | val (q, u') = dest_coeff 1 u | |
| 23400 
a64b39e5809b
The simprocs "divide_cancel_factor" and "ring_eq_cancel_factor" no
 nipkow parents: 
23365diff
changeset | 201 | in (mk_frac (p, q), mk_divide (t', u')) end | 
| 23164 | 202 | | dest_fcoeff sign t = | 
| 203 | let val (p, t') = dest_coeff sign t | |
| 204 | val T = Term.fastype_of t | |
| 23400 
a64b39e5809b
The simprocs "divide_cancel_factor" and "ring_eq_cancel_factor" no
 nipkow parents: 
23365diff
changeset | 205 | in (mk_frac (p, 1), mk_divide (t', one_of T)) end; | 
| 23164 | 206 | |
| 207 | ||
| 23400 
a64b39e5809b
The simprocs "divide_cancel_factor" and "ring_eq_cancel_factor" no
 nipkow parents: 
23365diff
changeset | 208 | (*Simplify Numeral0+n, n+Numeral0, Numeral1*n, n*Numeral1, 1*x, x*1, x/1 *) | 
| 23164 | 209 | val add_0s = thms "add_0s"; | 
| 23400 
a64b39e5809b
The simprocs "divide_cancel_factor" and "ring_eq_cancel_factor" no
 nipkow parents: 
23365diff
changeset | 210 | val mult_1s = thms "mult_1s" @ [thm"mult_1_left", thm"mult_1_right", thm"divide_1"]; | 
| 23164 | 211 | |
| 212 | (*Simplify inverse Numeral1, a/Numeral1*) | |
| 213 | val inverse_1s = [@{thm inverse_numeral_1}];
 | |
| 214 | val divide_1s = [@{thm divide_numeral_1}];
 | |
| 215 | ||
| 216 | (*To perform binary arithmetic. The "left" rewriting handles patterns | |
| 217 | created by the Int_Numeral_Base_Simprocs, such as 3 * (5 * x). *) | |
| 25481 | 218 | val simps = [@{thm numeral_0_eq_0} RS sym, @{thm numeral_1_eq_1} RS sym,
 | 
| 219 |                  @{thm add_number_of_left}, @{thm mult_number_of_left}] @
 | |
| 220 |                 @{thms arith_simps} @ @{thms rel_simps};
 | |
| 23164 | 221 | |
| 222 | (*Binary arithmetic BUT NOT ADDITION since it may collapse adjacent terms | |
| 223 | during re-arrangement*) | |
| 224 | val non_add_simps = | |
| 25481 | 225 |   subtract Thm.eq_thm [@{thm add_number_of_left}, @{thm number_of_add} RS sym] simps;
 | 
| 23164 | 226 | |
| 227 | (*To evaluate binary negations of coefficients*) | |
| 26075 
815f3ccc0b45
added lemma lists {normalize,succ,pred,minus,add,mult}_bin_simps
 huffman parents: 
25919diff
changeset | 228 | val minus_simps = [@{thm numeral_m1_eq_minus_1} RS sym, @{thm number_of_minus} RS sym] @
 | 
| 
815f3ccc0b45
added lemma lists {normalize,succ,pred,minus,add,mult}_bin_simps
 huffman parents: 
25919diff
changeset | 229 |                    @{thms minus_bin_simps} @ @{thms pred_bin_simps};
 | 
| 23164 | 230 | |
| 231 | (*To let us treat subtraction as addition*) | |
| 232 | val diff_simps = [@{thm diff_minus}, @{thm minus_add_distrib}, @{thm minus_minus}];
 | |
| 233 | ||
| 234 | (*To let us treat division as multiplication*) | |
| 235 | val divide_simps = [@{thm divide_inverse}, @{thm inverse_mult_distrib}, @{thm inverse_inverse_eq}];
 | |
| 236 | ||
| 237 | (*push the unary minus down: - x * y = x * - y *) | |
| 238 | val minus_mult_eq_1_to_2 = | |
| 239 |     [@{thm minus_mult_left} RS sym, @{thm minus_mult_right}] MRS trans |> standard;
 | |
| 240 | ||
| 241 | (*to extract again any uncancelled minuses*) | |
| 242 | val minus_from_mult_simps = | |
| 243 |     [@{thm minus_minus}, @{thm minus_mult_left} RS sym, @{thm minus_mult_right} RS sym];
 | |
| 244 | ||
| 245 | (*combine unary minus with numeric literals, however nested within a product*) | |
| 246 | val mult_minus_simps = | |
| 247 |     [@{thm mult_assoc}, @{thm minus_mult_left}, minus_mult_eq_1_to_2];
 | |
| 248 | ||
| 249 | (*Apply the given rewrite (if present) just once*) | |
| 250 | fun trans_tac NONE = all_tac | |
| 251 | | trans_tac (SOME th) = ALLGOALS (rtac (th RS trans)); | |
| 252 | ||
| 253 | fun simplify_meta_eq rules = | |
| 254 | let val ss0 = HOL_basic_ss addeqcongs [eq_cong2] addsimps rules | |
| 255 | in fn ss => simplify (Simplifier.inherit_context ss ss0) o mk_meta_eq end | |
| 256 | ||
| 257 | structure CancelNumeralsCommon = | |
| 258 | struct | |
| 259 | val mk_sum = mk_sum | |
| 260 | val dest_sum = dest_sum | |
| 261 | val mk_coeff = mk_coeff | |
| 262 | val dest_coeff = dest_coeff 1 | |
| 263 | val find_first_coeff = find_first_coeff [] | |
| 264 | val trans_tac = fn _ => trans_tac | |
| 265 | ||
| 266 | val norm_ss1 = num_ss addsimps numeral_syms @ add_0s @ mult_1s @ | |
| 23881 | 267 |     diff_simps @ minus_simps @ @{thms add_ac}
 | 
| 23164 | 268 | val norm_ss2 = num_ss addsimps non_add_simps @ mult_minus_simps | 
| 23881 | 269 |   val norm_ss3 = num_ss addsimps minus_from_mult_simps @ @{thms add_ac} @ @{thms mult_ac}
 | 
| 23164 | 270 | fun norm_tac ss = | 
| 271 | ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss1)) | |
| 272 | THEN ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss2)) | |
| 273 | THEN ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss3)) | |
| 274 | ||
| 275 | val numeral_simp_ss = HOL_ss addsimps add_0s @ simps | |
| 276 | fun numeral_simp_tac ss = ALLGOALS (simp_tac (Simplifier.inherit_context ss numeral_simp_ss)) | |
| 277 | val simplify_meta_eq = simplify_meta_eq (add_0s @ mult_1s) | |
| 278 | end; | |
| 279 | ||
| 280 | ||
| 281 | structure EqCancelNumerals = CancelNumeralsFun | |
| 282 | (open CancelNumeralsCommon | |
| 283 | val prove_conv = Int_Numeral_Base_Simprocs.prove_conv | |
| 284 | val mk_bal = HOLogic.mk_eq | |
| 285 | val dest_bal = HOLogic.dest_bin "op =" Term.dummyT | |
| 25481 | 286 |   val bal_add1 = @{thm eq_add_iff1} RS trans
 | 
| 287 |   val bal_add2 = @{thm eq_add_iff2} RS trans
 | |
| 23164 | 288 | ); | 
| 289 | ||
| 290 | structure LessCancelNumerals = CancelNumeralsFun | |
| 291 | (open CancelNumeralsCommon | |
| 292 | val prove_conv = Int_Numeral_Base_Simprocs.prove_conv | |
| 23881 | 293 |   val mk_bal   = HOLogic.mk_binrel @{const_name HOL.less}
 | 
| 294 |   val dest_bal = HOLogic.dest_bin @{const_name HOL.less} Term.dummyT
 | |
| 25481 | 295 |   val bal_add1 = @{thm less_add_iff1} RS trans
 | 
| 296 |   val bal_add2 = @{thm less_add_iff2} RS trans
 | |
| 23164 | 297 | ); | 
| 298 | ||
| 299 | structure LeCancelNumerals = CancelNumeralsFun | |
| 300 | (open CancelNumeralsCommon | |
| 301 | val prove_conv = Int_Numeral_Base_Simprocs.prove_conv | |
| 23881 | 302 |   val mk_bal   = HOLogic.mk_binrel @{const_name HOL.less_eq}
 | 
| 303 |   val dest_bal = HOLogic.dest_bin @{const_name HOL.less_eq} Term.dummyT
 | |
| 25481 | 304 |   val bal_add1 = @{thm le_add_iff1} RS trans
 | 
| 305 |   val bal_add2 = @{thm le_add_iff2} RS trans
 | |
| 23164 | 306 | ); | 
| 307 | ||
| 308 | val cancel_numerals = | |
| 309 | map Int_Numeral_Base_Simprocs.prep_simproc | |
| 310 |    [("inteq_cancel_numerals",
 | |
| 311 | ["(l::'a::number_ring) + m = n", | |
| 312 | "(l::'a::number_ring) = m + n", | |
| 313 | "(l::'a::number_ring) - m = n", | |
| 314 | "(l::'a::number_ring) = m - n", | |
| 315 | "(l::'a::number_ring) * m = n", | |
| 316 | "(l::'a::number_ring) = m * n"], | |
| 317 | K EqCancelNumerals.proc), | |
| 318 |     ("intless_cancel_numerals",
 | |
| 319 |      ["(l::'a::{ordered_idom,number_ring}) + m < n",
 | |
| 320 |       "(l::'a::{ordered_idom,number_ring}) < m + n",
 | |
| 321 |       "(l::'a::{ordered_idom,number_ring}) - m < n",
 | |
| 322 |       "(l::'a::{ordered_idom,number_ring}) < m - n",
 | |
| 323 |       "(l::'a::{ordered_idom,number_ring}) * m < n",
 | |
| 324 |       "(l::'a::{ordered_idom,number_ring}) < m * n"],
 | |
| 325 | K LessCancelNumerals.proc), | |
| 326 |     ("intle_cancel_numerals",
 | |
| 327 |      ["(l::'a::{ordered_idom,number_ring}) + m <= n",
 | |
| 328 |       "(l::'a::{ordered_idom,number_ring}) <= m + n",
 | |
| 329 |       "(l::'a::{ordered_idom,number_ring}) - m <= n",
 | |
| 330 |       "(l::'a::{ordered_idom,number_ring}) <= m - n",
 | |
| 331 |       "(l::'a::{ordered_idom,number_ring}) * m <= n",
 | |
| 332 |       "(l::'a::{ordered_idom,number_ring}) <= m * n"],
 | |
| 333 | K LeCancelNumerals.proc)]; | |
| 334 | ||
| 335 | ||
| 336 | structure CombineNumeralsData = | |
| 337 | struct | |
| 24630 
351a308ab58d
simplified type int (eliminated IntInf.int, integer);
 wenzelm parents: 
24266diff
changeset | 338 | type coeff = int | 
| 
351a308ab58d
simplified type int (eliminated IntInf.int, integer);
 wenzelm parents: 
24266diff
changeset | 339 | val iszero = (fn x => x = 0) | 
| 
351a308ab58d
simplified type int (eliminated IntInf.int, integer);
 wenzelm parents: 
24266diff
changeset | 340 | val add = op + | 
| 23164 | 341 | val mk_sum = long_mk_sum (*to work for e.g. 2*x + 3*x *) | 
| 342 | val dest_sum = dest_sum | |
| 343 | val mk_coeff = mk_coeff | |
| 344 | val dest_coeff = dest_coeff 1 | |
| 25481 | 345 |   val left_distrib      = @{thm combine_common_factor} RS trans
 | 
| 23164 | 346 | val prove_conv = Int_Numeral_Base_Simprocs.prove_conv_nohyps | 
| 347 | val trans_tac = fn _ => trans_tac | |
| 348 | ||
| 349 | val norm_ss1 = num_ss addsimps numeral_syms @ add_0s @ mult_1s @ | |
| 23881 | 350 |     diff_simps @ minus_simps @ @{thms add_ac}
 | 
| 23164 | 351 | val norm_ss2 = num_ss addsimps non_add_simps @ mult_minus_simps | 
| 23881 | 352 |   val norm_ss3 = num_ss addsimps minus_from_mult_simps @ @{thms add_ac} @ @{thms mult_ac}
 | 
| 23164 | 353 | fun norm_tac ss = | 
| 354 | ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss1)) | |
| 355 | THEN ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss2)) | |
| 356 | THEN ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss3)) | |
| 357 | ||
| 358 | val numeral_simp_ss = HOL_ss addsimps add_0s @ simps | |
| 359 | fun numeral_simp_tac ss = ALLGOALS (simp_tac (Simplifier.inherit_context ss numeral_simp_ss)) | |
| 360 | val simplify_meta_eq = simplify_meta_eq (add_0s @ mult_1s) | |
| 361 | end; | |
| 362 | ||
| 363 | structure CombineNumerals = CombineNumeralsFun(CombineNumeralsData); | |
| 364 | ||
| 365 | (*Version for fields, where coefficients can be fractions*) | |
| 366 | structure FieldCombineNumeralsData = | |
| 367 | struct | |
| 24630 
351a308ab58d
simplified type int (eliminated IntInf.int, integer);
 wenzelm parents: 
24266diff
changeset | 368 | type coeff = int * int | 
| 
351a308ab58d
simplified type int (eliminated IntInf.int, integer);
 wenzelm parents: 
24266diff
changeset | 369 | val iszero = (fn (p, q) => p = 0) | 
| 23164 | 370 | val add = add_frac | 
| 371 | val mk_sum = long_mk_sum | |
| 372 | val dest_sum = dest_sum | |
| 373 | val mk_coeff = mk_fcoeff | |
| 374 | val dest_coeff = dest_fcoeff 1 | |
| 25481 | 375 |   val left_distrib      = @{thm combine_common_factor} RS trans
 | 
| 23164 | 376 | val prove_conv = Int_Numeral_Base_Simprocs.prove_conv_nohyps | 
| 377 | val trans_tac = fn _ => trans_tac | |
| 378 | ||
| 379 | val norm_ss1 = num_ss addsimps numeral_syms @ add_0s @ mult_1s @ | |
| 23881 | 380 |     inverse_1s @ divide_simps @ diff_simps @ minus_simps @ @{thms add_ac}
 | 
| 23164 | 381 | val norm_ss2 = num_ss addsimps non_add_simps @ mult_minus_simps | 
| 23881 | 382 |   val norm_ss3 = num_ss addsimps minus_from_mult_simps @ @{thms add_ac} @ @{thms mult_ac}
 | 
| 23164 | 383 | fun norm_tac ss = | 
| 384 | ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss1)) | |
| 385 | THEN ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss2)) | |
| 386 | THEN ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss3)) | |
| 387 | ||
| 388 |   val numeral_simp_ss = HOL_ss addsimps add_0s @ simps @ [@{thm add_frac_eq}]
 | |
| 389 | fun numeral_simp_tac ss = ALLGOALS (simp_tac (Simplifier.inherit_context ss numeral_simp_ss)) | |
| 390 | val simplify_meta_eq = simplify_meta_eq (add_0s @ mult_1s @ divide_1s) | |
| 391 | end; | |
| 392 | ||
| 393 | structure FieldCombineNumerals = CombineNumeralsFun(FieldCombineNumeralsData); | |
| 394 | ||
| 395 | val combine_numerals = | |
| 396 | Int_Numeral_Base_Simprocs.prep_simproc | |
| 397 |     ("int_combine_numerals", 
 | |
| 398 | ["(i::'a::number_ring) + j", "(i::'a::number_ring) - j"], | |
| 399 | K CombineNumerals.proc); | |
| 400 | ||
| 401 | val field_combine_numerals = | |
| 402 | Int_Numeral_Base_Simprocs.prep_simproc | |
| 403 |     ("field_combine_numerals", 
 | |
| 404 |      ["(i::'a::{number_ring,field,division_by_zero}) + j",
 | |
| 405 |       "(i::'a::{number_ring,field,division_by_zero}) - j"], 
 | |
| 406 | K FieldCombineNumerals.proc); | |
| 407 | ||
| 408 | end; | |
| 409 | ||
| 410 | Addsimprocs Int_Numeral_Simprocs.cancel_numerals; | |
| 411 | Addsimprocs [Int_Numeral_Simprocs.combine_numerals]; | |
| 412 | Addsimprocs [Int_Numeral_Simprocs.field_combine_numerals]; | |
| 413 | ||
| 414 | (*examples: | |
| 415 | print_depth 22; | |
| 416 | set timing; | |
| 417 | set trace_simp; | |
| 418 | fun test s = (Goal s, by (Simp_tac 1)); | |
| 419 | ||
| 420 | test "l + 2 + 2 + 2 + (l + 2) + (oo + 2) = (uu::int)"; | |
| 421 | ||
| 422 | test "2*u = (u::int)"; | |
| 423 | test "(i + j + 12 + (k::int)) - 15 = y"; | |
| 424 | test "(i + j + 12 + (k::int)) - 5 = y"; | |
| 425 | ||
| 426 | test "y - b < (b::int)"; | |
| 427 | test "y - (3*b + c) < (b::int) - 2*c"; | |
| 428 | ||
| 429 | test "(2*x - (u*v) + y) - v*3*u = (w::int)"; | |
| 430 | test "(2*x*u*v + (u*v)*4 + y) - v*u*4 = (w::int)"; | |
| 431 | test "(2*x*u*v + (u*v)*4 + y) - v*u = (w::int)"; | |
| 432 | test "u*v - (x*u*v + (u*v)*4 + y) = (w::int)"; | |
| 433 | ||
| 434 | test "(i + j + 12 + (k::int)) = u + 15 + y"; | |
| 435 | test "(i + j*2 + 12 + (k::int)) = j + 5 + y"; | |
| 436 | ||
| 437 | test "2*y + 3*z + 6*w + 2*y + 3*z + 2*u = 2*y' + 3*z' + 6*w' + 2*y' + 3*z' + u + (vv::int)"; | |
| 438 | ||
| 439 | test "a + -(b+c) + b = (d::int)"; | |
| 440 | test "a + -(b+c) - b = (d::int)"; | |
| 441 | ||
| 442 | (*negative numerals*) | |
| 443 | test "(i + j + -2 + (k::int)) - (u + 5 + y) = zz"; | |
| 444 | test "(i + j + -3 + (k::int)) < u + 5 + y"; | |
| 445 | test "(i + j + 3 + (k::int)) < u + -6 + y"; | |
| 446 | test "(i + j + -12 + (k::int)) - 15 = y"; | |
| 447 | test "(i + j + 12 + (k::int)) - -15 = y"; | |
| 448 | test "(i + j + -12 + (k::int)) - -15 = y"; | |
| 449 | *) | |
| 450 | ||
| 451 | ||
| 452 | (** Constant folding for multiplication in semirings **) | |
| 453 | ||
| 454 | (*We do not need folding for addition: combine_numerals does the same thing*) | |
| 455 | ||
| 456 | structure Semiring_Times_Assoc_Data : ASSOC_FOLD_DATA = | |
| 457 | struct | |
| 23881 | 458 |   val assoc_ss = HOL_ss addsimps @{thms mult_ac}
 | 
| 23164 | 459 | val eq_reflection = eq_reflection | 
| 460 | end; | |
| 461 | ||
| 462 | structure Semiring_Times_Assoc = Assoc_Fold (Semiring_Times_Assoc_Data); | |
| 463 | ||
| 464 | val assoc_fold_simproc = | |
| 465 | Int_Numeral_Base_Simprocs.prep_simproc | |
| 466 |    ("semiring_assoc_fold", ["(a::'a::comm_semiring_1_cancel) * b"],
 | |
| 467 | K Semiring_Times_Assoc.proc); | |
| 468 | ||
| 469 | Addsimprocs [assoc_fold_simproc]; | |
| 470 | ||
| 471 | ||
| 472 | ||
| 473 | ||
| 474 | (*** decision procedure for linear arithmetic ***) | |
| 475 | ||
| 476 | (*---------------------------------------------------------------------------*) | |
| 477 | (* Linear arithmetic *) | |
| 478 | (*---------------------------------------------------------------------------*) | |
| 479 | ||
| 480 | (* | |
| 481 | Instantiation of the generic linear arithmetic package for int. | |
| 482 | *) | |
| 483 | ||
| 484 | (* Update parameters of arithmetic prover *) | |
| 485 | local | |
| 486 | ||
| 24266 
bdb48fd8fbdd
extended linear arith capabilities with code by Amine
 nipkow parents: 
24196diff
changeset | 487 | (* reduce contradictory =/</<= to False *) | 
| 
bdb48fd8fbdd
extended linear arith capabilities with code by Amine
 nipkow parents: 
24196diff
changeset | 488 | |
| 
bdb48fd8fbdd
extended linear arith capabilities with code by Amine
 nipkow parents: 
24196diff
changeset | 489 | (* Evaluation of terms of the form "m R n" where R is one of "=", "<=" or "<", | 
| 
bdb48fd8fbdd
extended linear arith capabilities with code by Amine
 nipkow parents: 
24196diff
changeset | 490 | and m and n are ground terms over rings (roughly speaking). | 
| 
bdb48fd8fbdd
extended linear arith capabilities with code by Amine
 nipkow parents: 
24196diff
changeset | 491 | That is, m and n consist only of 1s combined with "+", "-" and "*". | 
| 
bdb48fd8fbdd
extended linear arith capabilities with code by Amine
 nipkow parents: 
24196diff
changeset | 492 | *) | 
| 
bdb48fd8fbdd
extended linear arith capabilities with code by Amine
 nipkow parents: 
24196diff
changeset | 493 | local | 
| 
bdb48fd8fbdd
extended linear arith capabilities with code by Amine
 nipkow parents: 
24196diff
changeset | 494 | val zeroth = (symmetric o mk_meta_eq) @{thm of_int_0};
 | 
| 
bdb48fd8fbdd
extended linear arith capabilities with code by Amine
 nipkow parents: 
24196diff
changeset | 495 | val lhss0 = [@{cpat "0::?'a::ring"}];
 | 
| 
bdb48fd8fbdd
extended linear arith capabilities with code by Amine
 nipkow parents: 
24196diff
changeset | 496 | fun proc0 phi ss ct = | 
| 
bdb48fd8fbdd
extended linear arith capabilities with code by Amine
 nipkow parents: 
24196diff
changeset | 497 | let val T = ctyp_of_term ct | 
| 
bdb48fd8fbdd
extended linear arith capabilities with code by Amine
 nipkow parents: 
24196diff
changeset | 498 |   in if typ_of T = @{typ int} then NONE else
 | 
| 
bdb48fd8fbdd
extended linear arith capabilities with code by Amine
 nipkow parents: 
24196diff
changeset | 499 | SOME (instantiate' [SOME T] [] zeroth) | 
| 
bdb48fd8fbdd
extended linear arith capabilities with code by Amine
 nipkow parents: 
24196diff
changeset | 500 | end; | 
| 
bdb48fd8fbdd
extended linear arith capabilities with code by Amine
 nipkow parents: 
24196diff
changeset | 501 | val zero_to_of_int_zero_simproc = | 
| 
bdb48fd8fbdd
extended linear arith capabilities with code by Amine
 nipkow parents: 
24196diff
changeset | 502 |   make_simproc {lhss = lhss0, name = "zero_to_of_int_zero_simproc",
 | 
| 
bdb48fd8fbdd
extended linear arith capabilities with code by Amine
 nipkow parents: 
24196diff
changeset | 503 | proc = proc0, identifier = []}; | 
| 
bdb48fd8fbdd
extended linear arith capabilities with code by Amine
 nipkow parents: 
24196diff
changeset | 504 | |
| 
bdb48fd8fbdd
extended linear arith capabilities with code by Amine
 nipkow parents: 
24196diff
changeset | 505 | val oneth = (symmetric o mk_meta_eq) @{thm of_int_1};
 | 
| 
bdb48fd8fbdd
extended linear arith capabilities with code by Amine
 nipkow parents: 
24196diff
changeset | 506 | val lhss1 = [@{cpat "1::?'a::ring_1"}];
 | 
| 
bdb48fd8fbdd
extended linear arith capabilities with code by Amine
 nipkow parents: 
24196diff
changeset | 507 | fun proc1 phi ss ct = | 
| 
bdb48fd8fbdd
extended linear arith capabilities with code by Amine
 nipkow parents: 
24196diff
changeset | 508 | let val T = ctyp_of_term ct | 
| 
bdb48fd8fbdd
extended linear arith capabilities with code by Amine
 nipkow parents: 
24196diff
changeset | 509 |   in if typ_of T = @{typ int} then NONE else
 | 
| 
bdb48fd8fbdd
extended linear arith capabilities with code by Amine
 nipkow parents: 
24196diff
changeset | 510 | SOME (instantiate' [SOME T] [] oneth) | 
| 
bdb48fd8fbdd
extended linear arith capabilities with code by Amine
 nipkow parents: 
24196diff
changeset | 511 | end; | 
| 
bdb48fd8fbdd
extended linear arith capabilities with code by Amine
 nipkow parents: 
24196diff
changeset | 512 | val one_to_of_int_one_simproc = | 
| 
bdb48fd8fbdd
extended linear arith capabilities with code by Amine
 nipkow parents: 
24196diff
changeset | 513 |   make_simproc {lhss = lhss1, name = "one_to_of_int_one_simproc",
 | 
| 
bdb48fd8fbdd
extended linear arith capabilities with code by Amine
 nipkow parents: 
24196diff
changeset | 514 | proc = proc1, identifier = []}; | 
| 
bdb48fd8fbdd
extended linear arith capabilities with code by Amine
 nipkow parents: 
24196diff
changeset | 515 | |
| 
bdb48fd8fbdd
extended linear arith capabilities with code by Amine
 nipkow parents: 
24196diff
changeset | 516 | val allowed_consts = | 
| 
bdb48fd8fbdd
extended linear arith capabilities with code by Amine
 nipkow parents: 
24196diff
changeset | 517 |   [@{const_name "op ="}, @{const_name "HOL.times"}, @{const_name "HOL.uminus"},
 | 
| 
bdb48fd8fbdd
extended linear arith capabilities with code by Amine
 nipkow parents: 
24196diff
changeset | 518 |    @{const_name "HOL.minus"}, @{const_name "HOL.plus"},
 | 
| 
bdb48fd8fbdd
extended linear arith capabilities with code by Amine
 nipkow parents: 
24196diff
changeset | 519 |    @{const_name "HOL.zero"}, @{const_name "HOL.one"}, @{const_name "HOL.less"},
 | 
| 
bdb48fd8fbdd
extended linear arith capabilities with code by Amine
 nipkow parents: 
24196diff
changeset | 520 |    @{const_name "HOL.less_eq"}];
 | 
| 
bdb48fd8fbdd
extended linear arith capabilities with code by Amine
 nipkow parents: 
24196diff
changeset | 521 | |
| 
bdb48fd8fbdd
extended linear arith capabilities with code by Amine
 nipkow parents: 
24196diff
changeset | 522 | fun check t = case t of | 
| 
bdb48fd8fbdd
extended linear arith capabilities with code by Amine
 nipkow parents: 
24196diff
changeset | 523 |    Const(s,t) => if s = @{const_name "HOL.one"} then not (t = @{typ int})
 | 
| 
bdb48fd8fbdd
extended linear arith capabilities with code by Amine
 nipkow parents: 
24196diff
changeset | 524 | else s mem_string allowed_consts | 
| 
bdb48fd8fbdd
extended linear arith capabilities with code by Amine
 nipkow parents: 
24196diff
changeset | 525 | | a$b => check a andalso check b | 
| 
bdb48fd8fbdd
extended linear arith capabilities with code by Amine
 nipkow parents: 
24196diff
changeset | 526 | | _ => false; | 
| 
bdb48fd8fbdd
extended linear arith capabilities with code by Amine
 nipkow parents: 
24196diff
changeset | 527 | |
| 
bdb48fd8fbdd
extended linear arith capabilities with code by Amine
 nipkow parents: 
24196diff
changeset | 528 | val conv = | 
| 
bdb48fd8fbdd
extended linear arith capabilities with code by Amine
 nipkow parents: 
24196diff
changeset | 529 | Simplifier.rewrite | 
| 
bdb48fd8fbdd
extended linear arith capabilities with code by Amine
 nipkow parents: 
24196diff
changeset | 530 | (HOL_basic_ss addsimps | 
| 
bdb48fd8fbdd
extended linear arith capabilities with code by Amine
 nipkow parents: 
24196diff
changeset | 531 |      ((map (fn th => th RS sym) [@{thm of_int_add}, @{thm of_int_mult},
 | 
| 
bdb48fd8fbdd
extended linear arith capabilities with code by Amine
 nipkow parents: 
24196diff
changeset | 532 |              @{thm of_int_diff},  @{thm of_int_minus}])@
 | 
| 
bdb48fd8fbdd
extended linear arith capabilities with code by Amine
 nipkow parents: 
24196diff
changeset | 533 |       [@{thm of_int_less_iff}, @{thm of_int_le_iff}, @{thm of_int_eq_iff}])
 | 
| 
bdb48fd8fbdd
extended linear arith capabilities with code by Amine
 nipkow parents: 
24196diff
changeset | 534 | addsimprocs [zero_to_of_int_zero_simproc,one_to_of_int_one_simproc]); | 
| 
bdb48fd8fbdd
extended linear arith capabilities with code by Amine
 nipkow parents: 
24196diff
changeset | 535 | |
| 
bdb48fd8fbdd
extended linear arith capabilities with code by Amine
 nipkow parents: 
24196diff
changeset | 536 | fun sproc phi ss ct = if check (term_of ct) then SOME (conv ct) else NONE | 
| 
bdb48fd8fbdd
extended linear arith capabilities with code by Amine
 nipkow parents: 
24196diff
changeset | 537 | val lhss' = | 
| 
bdb48fd8fbdd
extended linear arith capabilities with code by Amine
 nipkow parents: 
24196diff
changeset | 538 |   [@{cpat "(?x::?'a::ring_char_0) = (?y::?'a)"},
 | 
| 
bdb48fd8fbdd
extended linear arith capabilities with code by Amine
 nipkow parents: 
24196diff
changeset | 539 |    @{cpat "(?x::?'a::ordered_idom) < (?y::?'a)"},
 | 
| 
bdb48fd8fbdd
extended linear arith capabilities with code by Amine
 nipkow parents: 
24196diff
changeset | 540 |    @{cpat "(?x::?'a::ordered_idom) <= (?y::?'a)"}]
 | 
| 
bdb48fd8fbdd
extended linear arith capabilities with code by Amine
 nipkow parents: 
24196diff
changeset | 541 | in | 
| 
bdb48fd8fbdd
extended linear arith capabilities with code by Amine
 nipkow parents: 
24196diff
changeset | 542 | val zero_one_idom_simproc = | 
| 
bdb48fd8fbdd
extended linear arith capabilities with code by Amine
 nipkow parents: 
24196diff
changeset | 543 |   make_simproc {lhss = lhss' , name = "zero_one_idom_simproc",
 | 
| 
bdb48fd8fbdd
extended linear arith capabilities with code by Amine
 nipkow parents: 
24196diff
changeset | 544 | proc = sproc, identifier = []} | 
| 
bdb48fd8fbdd
extended linear arith capabilities with code by Amine
 nipkow parents: 
24196diff
changeset | 545 | end; | 
| 
bdb48fd8fbdd
extended linear arith capabilities with code by Amine
 nipkow parents: 
24196diff
changeset | 546 | |
| 23164 | 547 | val add_rules = | 
| 25481 | 548 |     simp_thms @ @{thms arith_simps} @ @{thms rel_simps} @ @{thms arith_special} @
 | 
| 23164 | 549 |     [@{thm neg_le_iff_le}, @{thm numeral_0_eq_0}, @{thm numeral_1_eq_1},
 | 
| 550 |      @{thm minus_zero}, @{thm diff_minus}, @{thm left_minus}, @{thm right_minus},
 | |
| 26086 
3c243098b64a
New simpler representation of numerals, using Bit0 and Bit1 instead of BIT, B0, and B1
 huffman parents: 
26075diff
changeset | 551 |      @{thm mult_zero_left}, @{thm mult_zero_right}, @{thm mult_Bit1}, @{thm mult_1_right},
 | 
| 23164 | 552 |      @{thm minus_mult_left} RS sym, @{thm minus_mult_right} RS sym,
 | 
| 553 |      @{thm minus_add_distrib}, @{thm minus_minus}, @{thm mult_assoc},
 | |
| 23365 | 554 |      @{thm of_nat_0}, @{thm of_nat_1}, @{thm of_nat_Suc}, @{thm of_nat_add},
 | 
| 555 |      @{thm of_nat_mult}, @{thm of_int_0}, @{thm of_int_1}, @{thm of_int_add},
 | |
| 556 |      @{thm of_int_mult}]
 | |
| 23164 | 557 | |
| 23365 | 558 | val nat_inj_thms = [@{thm zle_int} RS iffD2, @{thm int_int_eq} RS iffD2]
 | 
| 23164 | 559 | |
| 24266 
bdb48fd8fbdd
extended linear arith capabilities with code by Amine
 nipkow parents: 
24196diff
changeset | 560 | val Int_Numeral_Base_Simprocs = assoc_fold_simproc :: zero_one_idom_simproc | 
| 23164 | 561 | :: Int_Numeral_Simprocs.combine_numerals | 
| 562 | :: Int_Numeral_Simprocs.cancel_numerals; | |
| 563 | ||
| 564 | in | |
| 565 | ||
| 566 | val int_arith_setup = | |
| 24093 | 567 |   LinArith.map_data (fn {add_mono_thms, mult_mono_thms, inj_thms, lessD, neqE, simpset} =>
 | 
| 23164 | 568 |    {add_mono_thms = add_mono_thms,
 | 
| 569 |     mult_mono_thms = @{thm mult_strict_left_mono} :: @{thm mult_left_mono} :: mult_mono_thms,
 | |
| 570 | inj_thms = nat_inj_thms @ inj_thms, | |
| 25481 | 571 |     lessD = lessD @ [@{thm zless_imp_add1_zle}],
 | 
| 23164 | 572 | neqE = neqE, | 
| 573 | simpset = simpset addsimps add_rules | |
| 574 | addsimprocs Int_Numeral_Base_Simprocs | |
| 575 | addcongs [if_weak_cong]}) #> | |
| 24196 | 576 |   arith_inj_const (@{const_name of_nat}, HOLogic.natT --> HOLogic.intT) #>
 | 
| 25919 
8b1c0d434824
joined theories IntDef, Numeral, IntArith to theory Int
 haftmann parents: 
25481diff
changeset | 577 |   arith_discrete @{type_name Int.int}
 | 
| 23164 | 578 | |
| 579 | end; | |
| 580 | ||
| 581 | val fast_int_arith_simproc = | |
| 582 |   Simplifier.simproc @{theory}
 | |
| 583 | "fast_int_arith" | |
| 584 |      ["(m::'a::{ordered_idom,number_ring}) < n",
 | |
| 585 |       "(m::'a::{ordered_idom,number_ring}) <= n",
 | |
| 24093 | 586 |       "(m::'a::{ordered_idom,number_ring}) = n"] (K LinArith.lin_arith_simproc);
 | 
| 23164 | 587 | |
| 588 | Addsimprocs [fast_int_arith_simproc]; |