src/HOL/Tools/int_arith.ML
changeset 31068 f591144b0f17
parent 31024 0fdf666e08bf
child 31082 54a442b2d727
     1.1 --- a/src/HOL/Tools/int_arith.ML	Fri May 08 08:01:09 2009 +0200
     1.2 +++ b/src/HOL/Tools/int_arith.ML	Fri May 08 09:48:07 2009 +0200
     1.3 @@ -1,420 +1,15 @@
     1.4 -(* Authors: Larry Paulson and Tobias Nipkow
     1.5 -
     1.6 -Simprocs and decision procedure for numerals and linear arithmetic.
     1.7 -*)
     1.8 -
     1.9 -structure Int_Numeral_Simprocs =
    1.10 -struct
    1.11 -
    1.12 -(** Utilities **)
    1.13 -
    1.14 -fun mk_number T n = HOLogic.number_of_const T $ HOLogic.mk_numeral n;
    1.15 -
    1.16 -fun find_first_numeral past (t::terms) =
    1.17 -        ((snd (HOLogic.dest_number t), rev past @ terms)
    1.18 -         handle TERM _ => find_first_numeral (t::past) terms)
    1.19 -  | find_first_numeral past [] = raise TERM("find_first_numeral", []);
    1.20 -
    1.21 -val mk_plus = HOLogic.mk_binop @{const_name HOL.plus};
    1.22 -
    1.23 -fun mk_minus t = 
    1.24 -  let val T = Term.fastype_of t
    1.25 -  in Const (@{const_name HOL.uminus}, T --> T) $ t end;
    1.26 -
    1.27 -(*Thus mk_sum[t] yields t+0; longer sums don't have a trailing zero*)
    1.28 -fun mk_sum T []        = mk_number T 0
    1.29 -  | mk_sum T [t,u]     = mk_plus (t, u)
    1.30 -  | mk_sum T (t :: ts) = mk_plus (t, mk_sum T ts);
    1.31 -
    1.32 -(*this version ALWAYS includes a trailing zero*)
    1.33 -fun long_mk_sum T []        = mk_number T 0
    1.34 -  | long_mk_sum T (t :: ts) = mk_plus (t, mk_sum T ts);
    1.35 -
    1.36 -val dest_plus = HOLogic.dest_bin @{const_name HOL.plus} Term.dummyT;
    1.37 -
    1.38 -(*decompose additions AND subtractions as a sum*)
    1.39 -fun dest_summing (pos, Const (@{const_name HOL.plus}, _) $ t $ u, ts) =
    1.40 -        dest_summing (pos, t, dest_summing (pos, u, ts))
    1.41 -  | dest_summing (pos, Const (@{const_name HOL.minus}, _) $ t $ u, ts) =
    1.42 -        dest_summing (pos, t, dest_summing (not pos, u, ts))
    1.43 -  | dest_summing (pos, t, ts) =
    1.44 -        if pos then t::ts else mk_minus t :: ts;
    1.45 -
    1.46 -fun dest_sum t = dest_summing (true, t, []);
    1.47 -
    1.48 -val mk_diff = HOLogic.mk_binop @{const_name HOL.minus};
    1.49 -val dest_diff = HOLogic.dest_bin @{const_name HOL.minus} Term.dummyT;
    1.50 -
    1.51 -val mk_times = HOLogic.mk_binop @{const_name HOL.times};
    1.52 -
    1.53 -fun one_of T = Const(@{const_name HOL.one},T);
    1.54 -
    1.55 -(* build product with trailing 1 rather than Numeral 1 in order to avoid the
    1.56 -   unnecessary restriction to type class number_ring
    1.57 -   which is not required for cancellation of common factors in divisions.
    1.58 -*)
    1.59 -fun mk_prod T = 
    1.60 -  let val one = one_of T
    1.61 -  fun mk [] = one
    1.62 -    | mk [t] = t
    1.63 -    | mk (t :: ts) = if t = one then mk ts else mk_times (t, mk ts)
    1.64 -  in mk end;
    1.65 -
    1.66 -(*This version ALWAYS includes a trailing one*)
    1.67 -fun long_mk_prod T []        = one_of T
    1.68 -  | long_mk_prod T (t :: ts) = mk_times (t, mk_prod T ts);
    1.69 -
    1.70 -val dest_times = HOLogic.dest_bin @{const_name HOL.times} Term.dummyT;
    1.71 -
    1.72 -fun dest_prod t =
    1.73 -      let val (t,u) = dest_times t
    1.74 -      in dest_prod t @ dest_prod u end
    1.75 -      handle TERM _ => [t];
    1.76 -
    1.77 -(*DON'T do the obvious simplifications; that would create special cases*)
    1.78 -fun mk_coeff (k, t) = mk_times (mk_number (Term.fastype_of t) k, t);
    1.79 -
    1.80 -(*Express t as a product of (possibly) a numeral with other sorted terms*)
    1.81 -fun dest_coeff sign (Const (@{const_name HOL.uminus}, _) $ t) = dest_coeff (~sign) t
    1.82 -  | dest_coeff sign t =
    1.83 -    let val ts = sort TermOrd.term_ord (dest_prod t)
    1.84 -        val (n, ts') = find_first_numeral [] ts
    1.85 -                          handle TERM _ => (1, ts)
    1.86 -    in (sign*n, mk_prod (Term.fastype_of t) ts') end;
    1.87 -
    1.88 -(*Find first coefficient-term THAT MATCHES u*)
    1.89 -fun find_first_coeff past u [] = raise TERM("find_first_coeff", [])
    1.90 -  | find_first_coeff past u (t::terms) =
    1.91 -        let val (n,u') = dest_coeff 1 t
    1.92 -        in if u aconv u' then (n, rev past @ terms)
    1.93 -                         else find_first_coeff (t::past) u terms
    1.94 -        end
    1.95 -        handle TERM _ => find_first_coeff (t::past) u terms;
    1.96 -
    1.97 -(*Fractions as pairs of ints. Can't use Rat.rat because the representation
    1.98 -  needs to preserve negative values in the denominator.*)
    1.99 -fun mk_frac (p, q) = if q = 0 then raise Div else (p, q);
   1.100 -
   1.101 -(*Don't reduce fractions; sums must be proved by rule add_frac_eq.
   1.102 -  Fractions are reduced later by the cancel_numeral_factor simproc.*)
   1.103 -fun add_frac ((p1, q1), (p2, q2)) = (p1 * q2 + p2 * q1, q1 * q2);
   1.104 -
   1.105 -val mk_divide = HOLogic.mk_binop @{const_name HOL.divide};
   1.106 -
   1.107 -(*Build term (p / q) * t*)
   1.108 -fun mk_fcoeff ((p, q), t) =
   1.109 -  let val T = Term.fastype_of t
   1.110 -  in mk_times (mk_divide (mk_number T p, mk_number T q), t) end;
   1.111 -
   1.112 -(*Express t as a product of a fraction with other sorted terms*)
   1.113 -fun dest_fcoeff sign (Const (@{const_name HOL.uminus}, _) $ t) = dest_fcoeff (~sign) t
   1.114 -  | dest_fcoeff sign (Const (@{const_name HOL.divide}, _) $ t $ u) =
   1.115 -    let val (p, t') = dest_coeff sign t
   1.116 -        val (q, u') = dest_coeff 1 u
   1.117 -    in (mk_frac (p, q), mk_divide (t', u')) end
   1.118 -  | dest_fcoeff sign t =
   1.119 -    let val (p, t') = dest_coeff sign t
   1.120 -        val T = Term.fastype_of t
   1.121 -    in (mk_frac (p, 1), mk_divide (t', one_of T)) end;
   1.122 -
   1.123 -
   1.124 -(** New term ordering so that AC-rewriting brings numerals to the front **)
   1.125 -
   1.126 -(*Order integers by absolute value and then by sign. The standard integer
   1.127 -  ordering is not well-founded.*)
   1.128 -fun num_ord (i,j) =
   1.129 -  (case int_ord (abs i, abs j) of
   1.130 -    EQUAL => int_ord (Int.sign i, Int.sign j) 
   1.131 -  | ord => ord);
   1.132 -
   1.133 -(*This resembles TermOrd.term_ord, but it puts binary numerals before other
   1.134 -  non-atomic terms.*)
   1.135 -local open Term 
   1.136 -in 
   1.137 -fun numterm_ord (Abs (_, T, t), Abs(_, U, u)) =
   1.138 -      (case numterm_ord (t, u) of EQUAL => TermOrd.typ_ord (T, U) | ord => ord)
   1.139 -  | numterm_ord
   1.140 -     (Const(@{const_name Int.number_of}, _) $ v, Const(@{const_name Int.number_of}, _) $ w) =
   1.141 -     num_ord (HOLogic.dest_numeral v, HOLogic.dest_numeral w)
   1.142 -  | numterm_ord (Const(@{const_name Int.number_of}, _) $ _, _) = LESS
   1.143 -  | numterm_ord (_, Const(@{const_name Int.number_of}, _) $ _) = GREATER
   1.144 -  | numterm_ord (t, u) =
   1.145 -      (case int_ord (size_of_term t, size_of_term u) of
   1.146 -        EQUAL =>
   1.147 -          let val (f, ts) = strip_comb t and (g, us) = strip_comb u in
   1.148 -            (case TermOrd.hd_ord (f, g) of EQUAL => numterms_ord (ts, us) | ord => ord)
   1.149 -          end
   1.150 -      | ord => ord)
   1.151 -and numterms_ord (ts, us) = list_ord numterm_ord (ts, us)
   1.152 -end;
   1.153 -
   1.154 -fun numtermless tu = (numterm_ord tu = LESS);
   1.155 -
   1.156 -val num_ss = HOL_ss settermless numtermless;
   1.157 -
   1.158 -(*Maps 0 to Numeral0 and 1 to Numeral1 so that arithmetic isn't complicated by the abstract 0 and 1.*)
   1.159 -val numeral_syms = [@{thm numeral_0_eq_0} RS sym, @{thm numeral_1_eq_1} RS sym];
   1.160 -
   1.161 -(*Simplify Numeral0+n, n+Numeral0, Numeral1*n, n*Numeral1, 1*x, x*1, x/1 *)
   1.162 -val add_0s =  @{thms add_0s};
   1.163 -val mult_1s = @{thms mult_1s mult_1_left mult_1_right divide_1};
   1.164 -
   1.165 -(*Simplify inverse Numeral1, a/Numeral1*)
   1.166 -val inverse_1s = [@{thm inverse_numeral_1}];
   1.167 -val divide_1s = [@{thm divide_numeral_1}];
   1.168 -
   1.169 -(*To perform binary arithmetic.  The "left" rewriting handles patterns
   1.170 -  created by the Int_Numeral_Simprocs, such as 3 * (5 * x). *)
   1.171 -val simps = [@{thm numeral_0_eq_0} RS sym, @{thm numeral_1_eq_1} RS sym,
   1.172 -                 @{thm add_number_of_left}, @{thm mult_number_of_left}] @
   1.173 -                @{thms arith_simps} @ @{thms rel_simps};
   1.174 -
   1.175 -(*Binary arithmetic BUT NOT ADDITION since it may collapse adjacent terms
   1.176 -  during re-arrangement*)
   1.177 -val non_add_simps =
   1.178 -  subtract Thm.eq_thm [@{thm add_number_of_left}, @{thm number_of_add} RS sym] simps;
   1.179 -
   1.180 -(*To evaluate binary negations of coefficients*)
   1.181 -val minus_simps = [@{thm numeral_m1_eq_minus_1} RS sym, @{thm number_of_minus} RS sym] @
   1.182 -                   @{thms minus_bin_simps} @ @{thms pred_bin_simps};
   1.183 -
   1.184 -(*To let us treat subtraction as addition*)
   1.185 -val diff_simps = [@{thm diff_minus}, @{thm minus_add_distrib}, @{thm minus_minus}];
   1.186 -
   1.187 -(*To let us treat division as multiplication*)
   1.188 -val divide_simps = [@{thm divide_inverse}, @{thm inverse_mult_distrib}, @{thm inverse_inverse_eq}];
   1.189 -
   1.190 -(*push the unary minus down: - x * y = x * - y *)
   1.191 -val minus_mult_eq_1_to_2 =
   1.192 -    [@{thm mult_minus_left}, @{thm minus_mult_right}] MRS trans |> standard;
   1.193 -
   1.194 -(*to extract again any uncancelled minuses*)
   1.195 -val minus_from_mult_simps =
   1.196 -    [@{thm minus_minus}, @{thm mult_minus_left}, @{thm mult_minus_right}];
   1.197 -
   1.198 -(*combine unary minus with numeric literals, however nested within a product*)
   1.199 -val mult_minus_simps =
   1.200 -    [@{thm mult_assoc}, @{thm minus_mult_left}, minus_mult_eq_1_to_2];
   1.201 -
   1.202 -val norm_ss1 = num_ss addsimps numeral_syms @ add_0s @ mult_1s @
   1.203 -  diff_simps @ minus_simps @ @{thms add_ac}
   1.204 -val norm_ss2 = num_ss addsimps non_add_simps @ mult_minus_simps
   1.205 -val norm_ss3 = num_ss addsimps minus_from_mult_simps @ @{thms add_ac} @ @{thms mult_ac}
   1.206 +(* Author: Tobias Nipkow
   1.207  
   1.208 -structure CancelNumeralsCommon =
   1.209 -  struct
   1.210 -  val mk_sum            = mk_sum
   1.211 -  val dest_sum          = dest_sum
   1.212 -  val mk_coeff          = mk_coeff
   1.213 -  val dest_coeff        = dest_coeff 1
   1.214 -  val find_first_coeff  = find_first_coeff []
   1.215 -  val trans_tac         = K Arith_Data.trans_tac
   1.216 -
   1.217 -  fun norm_tac ss =
   1.218 -    ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss1))
   1.219 -    THEN ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss2))
   1.220 -    THEN ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss3))
   1.221 -
   1.222 -  val numeral_simp_ss = HOL_ss addsimps add_0s @ simps
   1.223 -  fun numeral_simp_tac ss = ALLGOALS (simp_tac (Simplifier.inherit_context ss numeral_simp_ss))
   1.224 -  val simplify_meta_eq = Arith_Data.simplify_meta_eq (add_0s @ mult_1s)
   1.225 -  end;
   1.226 -
   1.227 -
   1.228 -structure EqCancelNumerals = CancelNumeralsFun
   1.229 - (open CancelNumeralsCommon
   1.230 -  val prove_conv = Arith_Data.prove_conv
   1.231 -  val mk_bal   = HOLogic.mk_eq
   1.232 -  val dest_bal = HOLogic.dest_bin "op =" Term.dummyT
   1.233 -  val bal_add1 = @{thm eq_add_iff1} RS trans
   1.234 -  val bal_add2 = @{thm eq_add_iff2} RS trans
   1.235 -);
   1.236 -
   1.237 -structure LessCancelNumerals = CancelNumeralsFun
   1.238 - (open CancelNumeralsCommon
   1.239 -  val prove_conv = Arith_Data.prove_conv
   1.240 -  val mk_bal   = HOLogic.mk_binrel @{const_name HOL.less}
   1.241 -  val dest_bal = HOLogic.dest_bin @{const_name HOL.less} Term.dummyT
   1.242 -  val bal_add1 = @{thm less_add_iff1} RS trans
   1.243 -  val bal_add2 = @{thm less_add_iff2} RS trans
   1.244 -);
   1.245 -
   1.246 -structure LeCancelNumerals = CancelNumeralsFun
   1.247 - (open CancelNumeralsCommon
   1.248 -  val prove_conv = Arith_Data.prove_conv
   1.249 -  val mk_bal   = HOLogic.mk_binrel @{const_name HOL.less_eq}
   1.250 -  val dest_bal = HOLogic.dest_bin @{const_name HOL.less_eq} Term.dummyT
   1.251 -  val bal_add1 = @{thm le_add_iff1} RS trans
   1.252 -  val bal_add2 = @{thm le_add_iff2} RS trans
   1.253 -);
   1.254 -
   1.255 -val cancel_numerals =
   1.256 -  map Arith_Data.prep_simproc
   1.257 -   [("inteq_cancel_numerals",
   1.258 -     ["(l::'a::number_ring) + m = n",
   1.259 -      "(l::'a::number_ring) = m + n",
   1.260 -      "(l::'a::number_ring) - m = n",
   1.261 -      "(l::'a::number_ring) = m - n",
   1.262 -      "(l::'a::number_ring) * m = n",
   1.263 -      "(l::'a::number_ring) = m * n"],
   1.264 -     K EqCancelNumerals.proc),
   1.265 -    ("intless_cancel_numerals",
   1.266 -     ["(l::'a::{ordered_idom,number_ring}) + m < n",
   1.267 -      "(l::'a::{ordered_idom,number_ring}) < m + n",
   1.268 -      "(l::'a::{ordered_idom,number_ring}) - m < n",
   1.269 -      "(l::'a::{ordered_idom,number_ring}) < m - n",
   1.270 -      "(l::'a::{ordered_idom,number_ring}) * m < n",
   1.271 -      "(l::'a::{ordered_idom,number_ring}) < m * n"],
   1.272 -     K LessCancelNumerals.proc),
   1.273 -    ("intle_cancel_numerals",
   1.274 -     ["(l::'a::{ordered_idom,number_ring}) + m <= n",
   1.275 -      "(l::'a::{ordered_idom,number_ring}) <= m + n",
   1.276 -      "(l::'a::{ordered_idom,number_ring}) - m <= n",
   1.277 -      "(l::'a::{ordered_idom,number_ring}) <= m - n",
   1.278 -      "(l::'a::{ordered_idom,number_ring}) * m <= n",
   1.279 -      "(l::'a::{ordered_idom,number_ring}) <= m * n"],
   1.280 -     K LeCancelNumerals.proc)];
   1.281 -
   1.282 -
   1.283 -structure CombineNumeralsData =
   1.284 -  struct
   1.285 -  type coeff            = int
   1.286 -  val iszero            = (fn x => x = 0)
   1.287 -  val add               = op +
   1.288 -  val mk_sum            = long_mk_sum    (*to work for e.g. 2*x + 3*x *)
   1.289 -  val dest_sum          = dest_sum
   1.290 -  val mk_coeff          = mk_coeff
   1.291 -  val dest_coeff        = dest_coeff 1
   1.292 -  val left_distrib      = @{thm combine_common_factor} RS trans
   1.293 -  val prove_conv        = Arith_Data.prove_conv_nohyps
   1.294 -  val trans_tac         = K Arith_Data.trans_tac
   1.295 -
   1.296 -  fun norm_tac ss =
   1.297 -    ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss1))
   1.298 -    THEN ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss2))
   1.299 -    THEN ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss3))
   1.300 -
   1.301 -  val numeral_simp_ss = HOL_ss addsimps add_0s @ simps
   1.302 -  fun numeral_simp_tac ss = ALLGOALS (simp_tac (Simplifier.inherit_context ss numeral_simp_ss))
   1.303 -  val simplify_meta_eq = Arith_Data.simplify_meta_eq (add_0s @ mult_1s)
   1.304 -  end;
   1.305 -
   1.306 -structure CombineNumerals = CombineNumeralsFun(CombineNumeralsData);
   1.307 -
   1.308 -(*Version for fields, where coefficients can be fractions*)
   1.309 -structure FieldCombineNumeralsData =
   1.310 -  struct
   1.311 -  type coeff            = int * int
   1.312 -  val iszero            = (fn (p, q) => p = 0)
   1.313 -  val add               = add_frac
   1.314 -  val mk_sum            = long_mk_sum
   1.315 -  val dest_sum          = dest_sum
   1.316 -  val mk_coeff          = mk_fcoeff
   1.317 -  val dest_coeff        = dest_fcoeff 1
   1.318 -  val left_distrib      = @{thm combine_common_factor} RS trans
   1.319 -  val prove_conv        = Arith_Data.prove_conv_nohyps
   1.320 -  val trans_tac         = K Arith_Data.trans_tac
   1.321 -
   1.322 -  val norm_ss1a = norm_ss1 addsimps inverse_1s @ divide_simps
   1.323 -  fun norm_tac ss =
   1.324 -    ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss1a))
   1.325 -    THEN ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss2))
   1.326 -    THEN ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss3))
   1.327 -
   1.328 -  val numeral_simp_ss = HOL_ss addsimps add_0s @ simps @ [@{thm add_frac_eq}]
   1.329 -  fun numeral_simp_tac ss = ALLGOALS (simp_tac (Simplifier.inherit_context ss numeral_simp_ss))
   1.330 -  val simplify_meta_eq = Arith_Data.simplify_meta_eq (add_0s @ mult_1s @ divide_1s)
   1.331 -  end;
   1.332 -
   1.333 -structure FieldCombineNumerals = CombineNumeralsFun(FieldCombineNumeralsData);
   1.334 -
   1.335 -val combine_numerals =
   1.336 -  Arith_Data.prep_simproc
   1.337 -    ("int_combine_numerals", 
   1.338 -     ["(i::'a::number_ring) + j", "(i::'a::number_ring) - j"], 
   1.339 -     K CombineNumerals.proc);
   1.340 -
   1.341 -val field_combine_numerals =
   1.342 -  Arith_Data.prep_simproc
   1.343 -    ("field_combine_numerals", 
   1.344 -     ["(i::'a::{number_ring,field,division_by_zero}) + j",
   1.345 -      "(i::'a::{number_ring,field,division_by_zero}) - j"], 
   1.346 -     K FieldCombineNumerals.proc);
   1.347 -
   1.348 -(** Constant folding for multiplication in semirings **)
   1.349 -
   1.350 -(*We do not need folding for addition: combine_numerals does the same thing*)
   1.351 -
   1.352 -structure Semiring_Times_Assoc_Data : ASSOC_FOLD_DATA =
   1.353 -struct
   1.354 -  val assoc_ss = HOL_ss addsimps @{thms mult_ac}
   1.355 -  val eq_reflection = eq_reflection
   1.356 -  fun is_numeral (Const(@{const_name Int.number_of}, _) $ _) = true
   1.357 -    | is_numeral _ = false;
   1.358 -end;
   1.359 -
   1.360 -structure Semiring_Times_Assoc = Assoc_Fold (Semiring_Times_Assoc_Data);
   1.361 -
   1.362 -val assoc_fold_simproc =
   1.363 -  Arith_Data.prep_simproc
   1.364 -   ("semiring_assoc_fold", ["(a::'a::comm_semiring_1_cancel) * b"],
   1.365 -    K Semiring_Times_Assoc.proc);
   1.366 -
   1.367 -end;
   1.368 -
   1.369 -Addsimprocs Int_Numeral_Simprocs.cancel_numerals;
   1.370 -Addsimprocs [Int_Numeral_Simprocs.combine_numerals];
   1.371 -Addsimprocs [Int_Numeral_Simprocs.field_combine_numerals];
   1.372 -Addsimprocs [Int_Numeral_Simprocs.assoc_fold_simproc];
   1.373 -
   1.374 -(*examples:
   1.375 -print_depth 22;
   1.376 -set timing;
   1.377 -set trace_simp;
   1.378 -fun test s = (Goal s, by (Simp_tac 1));
   1.379 -
   1.380 -test "l + 2 + 2 + 2 + (l + 2) + (oo + 2) = (uu::int)";
   1.381 -
   1.382 -test "2*u = (u::int)";
   1.383 -test "(i + j + 12 + (k::int)) - 15 = y";
   1.384 -test "(i + j + 12 + (k::int)) - 5 = y";
   1.385 -
   1.386 -test "y - b < (b::int)";
   1.387 -test "y - (3*b + c) < (b::int) - 2*c";
   1.388 -
   1.389 -test "(2*x - (u*v) + y) - v*3*u = (w::int)";
   1.390 -test "(2*x*u*v + (u*v)*4 + y) - v*u*4 = (w::int)";
   1.391 -test "(2*x*u*v + (u*v)*4 + y) - v*u = (w::int)";
   1.392 -test "u*v - (x*u*v + (u*v)*4 + y) = (w::int)";
   1.393 -
   1.394 -test "(i + j + 12 + (k::int)) = u + 15 + y";
   1.395 -test "(i + j*2 + 12 + (k::int)) = j + 5 + y";
   1.396 -
   1.397 -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)";
   1.398 -
   1.399 -test "a + -(b+c) + b = (d::int)";
   1.400 -test "a + -(b+c) - b = (d::int)";
   1.401 -
   1.402 -(*negative numerals*)
   1.403 -test "(i + j + -2 + (k::int)) - (u + 5 + y) = zz";
   1.404 -test "(i + j + -3 + (k::int)) < u + 5 + y";
   1.405 -test "(i + j + 3 + (k::int)) < u + -6 + y";
   1.406 -test "(i + j + -12 + (k::int)) - 15 = y";
   1.407 -test "(i + j + 12 + (k::int)) - -15 = y";
   1.408 -test "(i + j + -12 + (k::int)) - -15 = y";
   1.409 -*)
   1.410 -
   1.411 -(*** decision procedure for linear arithmetic ***)
   1.412 -
   1.413 -(*---------------------------------------------------------------------------*)
   1.414 -(* Linear arithmetic                                                         *)
   1.415 -(*---------------------------------------------------------------------------*)
   1.416 -
   1.417 -(*
   1.418  Instantiation of the generic linear arithmetic package for int.
   1.419  *)
   1.420  
   1.421 -structure Int_Arith =
   1.422 +signature INT_ARITH =
   1.423 +sig
   1.424 +  val fast_int_arith_simproc: simproc
   1.425 +  val setup: Context.generic -> Context.generic
   1.426 +end
   1.427 +
   1.428 +structure Int_Arith : INT_ARITH =
   1.429  struct
   1.430  
   1.431  (* Update parameters of arithmetic prover *)
   1.432 @@ -491,9 +86,9 @@
   1.433  
   1.434  val nat_inj_thms = [@{thm zle_int} RS iffD2, @{thm int_int_eq} RS iffD2]
   1.435  
   1.436 -val int_numeral_base_simprocs = Int_Numeral_Simprocs.assoc_fold_simproc :: zero_one_idom_simproc
   1.437 -  :: Int_Numeral_Simprocs.combine_numerals
   1.438 -  :: Int_Numeral_Simprocs.cancel_numerals;
   1.439 +val numeral_base_simprocs = Numeral_Simprocs.assoc_fold_simproc :: zero_one_idom_simproc
   1.440 +  :: Numeral_Simprocs.combine_numerals
   1.441 +  :: Numeral_Simprocs.cancel_numerals;
   1.442  
   1.443  val setup =
   1.444    Lin_Arith.map_data (fn {add_mono_thms, mult_mono_thms, inj_thms, lessD, neqE, simpset} =>
   1.445 @@ -503,7 +98,7 @@
   1.446      lessD = lessD @ [@{thm zless_imp_add1_zle}],
   1.447      neqE = neqE,
   1.448      simpset = simpset addsimps add_rules
   1.449 -                      addsimprocs int_numeral_base_simprocs
   1.450 +                      addsimprocs numeral_base_simprocs
   1.451                        addcongs [if_weak_cong]}) #>
   1.452    arith_inj_const (@{const_name of_nat}, HOLogic.natT --> HOLogic.intT) #>
   1.453    arith_discrete @{type_name Int.int}