146 EQUAL => int_ord (Int.sign i, Int.sign j) |
147 EQUAL => int_ord (Int.sign i, Int.sign j) |
147 | ord => ord); |
148 | ord => ord); |
148 |
149 |
149 (*This resembles Term_Ord.term_ord, but it puts binary numerals before other |
150 (*This resembles Term_Ord.term_ord, but it puts binary numerals before other |
150 non-atomic terms.*) |
151 non-atomic terms.*) |
151 local open Term |
152 local open Term |
152 in |
153 in |
153 fun numterm_ord (Abs (_, T, t), Abs(_, U, u)) = |
154 fun numterm_ord (t, u) = |
154 (case numterm_ord (t, u) of EQUAL => Term_Ord.typ_ord (T, U) | ord => ord) |
155 case (try HOLogic.dest_number t, try HOLogic.dest_number u) of |
155 | numterm_ord |
156 (SOME (_, i), SOME (_, j)) => num_ord (i, j) |
156 (Const(@{const_name Int.number_of}, _) $ v, Const(@{const_name Int.number_of}, _) $ w) = |
157 | (SOME _, NONE) => LESS |
157 num_ord (HOLogic.dest_numeral v, HOLogic.dest_numeral w) |
158 | (NONE, SOME _) => GREATER |
158 | numterm_ord (Const(@{const_name Int.number_of}, _) $ _, _) = LESS |
159 | _ => ( |
159 | numterm_ord (_, Const(@{const_name Int.number_of}, _) $ _) = GREATER |
160 case (t, u) of |
160 | numterm_ord (t, u) = |
161 (Abs (_, T, t), Abs(_, U, u)) => |
161 (case int_ord (size_of_term t, size_of_term u) of |
162 (prod_ord numterm_ord Term_Ord.typ_ord ((t, T), (u, U))) |
162 EQUAL => |
163 | _ => ( |
|
164 case int_ord (size_of_term t, size_of_term u) of |
|
165 EQUAL => |
163 let val (f, ts) = strip_comb t and (g, us) = strip_comb u in |
166 let val (f, ts) = strip_comb t and (g, us) = strip_comb u in |
164 (case Term_Ord.hd_ord (f, g) of EQUAL => numterms_ord (ts, us) | ord => ord) |
167 (prod_ord Term_Ord.hd_ord numterms_ord ((f, ts), (g, us))) |
165 end |
168 end |
166 | ord => ord) |
169 | ord => ord)) |
167 and numterms_ord (ts, us) = list_ord numterm_ord (ts, us) |
170 and numterms_ord (ts, us) = list_ord numterm_ord (ts, us) |
168 end; |
171 end; |
169 |
172 |
170 fun numtermless tu = (numterm_ord tu = LESS); |
173 fun numtermless tu = (numterm_ord tu = LESS); |
171 |
174 |
172 val num_ss = HOL_basic_ss |> Simplifier.set_termless numtermless; |
175 val num_ss = HOL_basic_ss |> Simplifier.set_termless numtermless; |
173 |
176 |
174 (*Maps 0 to Numeral0 and 1 to Numeral1 so that arithmetic isn't complicated by the abstract 0 and 1.*) |
177 (*Maps 1 to Numeral1 so that arithmetic isn't complicated by the abstract 1.*) |
175 val numeral_syms = [@{thm numeral_0_eq_0} RS sym, @{thm numeral_1_eq_1} RS sym]; |
178 val numeral_syms = [@{thm numeral_1_eq_1} RS sym]; |
176 |
179 |
177 (*Simplify Numeral0+n, n+Numeral0, Numeral1*n, n*Numeral1, 1*x, x*1, x/1 *) |
180 (*Simplify 0+n, n+0, Numeral1*n, n*Numeral1, 1*x, x*1, x/1 *) |
178 val add_0s = @{thms add_0s}; |
181 val add_0s = @{thms add_0s}; |
179 val mult_1s = @{thms mult_1s mult_1_left mult_1_right divide_1}; |
182 val mult_1s = @{thms mult_1s mult_1_left mult_1_right divide_1}; |
180 |
183 |
181 (* For post-simplification of the rhs of simproc-generated rules *) |
184 (* For post-simplification of the rhs of simproc-generated rules *) |
182 val post_simps = |
185 val post_simps = |
183 [@{thm numeral_0_eq_0}, @{thm numeral_1_eq_1}, |
186 [@{thm numeral_1_eq_1}, |
184 @{thm add_0_left}, @{thm add_0_right}, |
187 @{thm add_0_left}, @{thm add_0_right}, |
185 @{thm mult_zero_left}, @{thm mult_zero_right}, |
188 @{thm mult_zero_left}, @{thm mult_zero_right}, |
186 @{thm mult_1_left}, @{thm mult_1_right}, |
189 @{thm mult_1_left}, @{thm mult_1_right}, |
187 @{thm mult_minus1}, @{thm mult_minus1_right}] |
190 @{thm mult_minus1}, @{thm mult_minus1_right}] |
188 |
191 |
193 val inverse_1s = [@{thm inverse_numeral_1}]; |
196 val inverse_1s = [@{thm inverse_numeral_1}]; |
194 val divide_1s = [@{thm divide_numeral_1}]; |
197 val divide_1s = [@{thm divide_numeral_1}]; |
195 |
198 |
196 (*To perform binary arithmetic. The "left" rewriting handles patterns |
199 (*To perform binary arithmetic. The "left" rewriting handles patterns |
197 created by the Numeral_Simprocs, such as 3 * (5 * x). *) |
200 created by the Numeral_Simprocs, such as 3 * (5 * x). *) |
198 val simps = [@{thm numeral_0_eq_0} RS sym, @{thm numeral_1_eq_1} RS sym, |
201 val simps = |
199 @{thm add_number_of_left}, @{thm mult_number_of_left}] @ |
202 [@{thm numeral_1_eq_1} RS sym] @ |
200 @{thms arith_simps} @ @{thms rel_simps}; |
203 @{thms add_numeral_left} @ |
201 |
204 @{thms add_neg_numeral_left} @ |
|
205 @{thms mult_numeral_left} @ |
|
206 @{thms arith_simps} @ @{thms rel_simps}; |
|
207 |
202 (*Binary arithmetic BUT NOT ADDITION since it may collapse adjacent terms |
208 (*Binary arithmetic BUT NOT ADDITION since it may collapse adjacent terms |
203 during re-arrangement*) |
209 during re-arrangement*) |
204 val non_add_simps = |
210 val non_add_simps = |
205 subtract Thm.eq_thm [@{thm add_number_of_left}, @{thm number_of_add} RS sym] simps; |
211 subtract Thm.eq_thm |
|
212 (@{thms add_numeral_left} @ |
|
213 @{thms add_neg_numeral_left} @ |
|
214 @{thms numeral_plus_numeral} @ |
|
215 @{thms add_neg_numeral_simps}) simps; |
206 |
216 |
207 (*To evaluate binary negations of coefficients*) |
217 (*To evaluate binary negations of coefficients*) |
208 val minus_simps = [@{thm numeral_m1_eq_minus_1} RS sym, @{thm number_of_minus} RS sym] @ |
218 val minus_simps = [@{thm minus_zero}, @{thm minus_one}, @{thm minus_numeral}, @{thm minus_neg_numeral}]; |
209 @{thms minus_bin_simps} @ @{thms pred_bin_simps}; |
|
210 |
219 |
211 (*To let us treat subtraction as addition*) |
220 (*To let us treat subtraction as addition*) |
212 val diff_simps = [@{thm diff_minus}, @{thm minus_add_distrib}, @{thm minus_minus}]; |
221 val diff_simps = [@{thm diff_minus}, @{thm minus_add_distrib}, @{thm minus_minus}]; |
213 |
222 |
214 (*To let us treat division as multiplication*) |
223 (*To let us treat division as multiplication*) |
363 THEN ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss2)) |
372 THEN ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss2)) |
364 THEN ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss3)) |
373 THEN ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss3)) |
365 |
374 |
366 (* simp_thms are necessary because some of the cancellation rules below |
375 (* simp_thms are necessary because some of the cancellation rules below |
367 (e.g. mult_less_cancel_left) introduce various logical connectives *) |
376 (e.g. mult_less_cancel_left) introduce various logical connectives *) |
368 val numeral_simp_ss = HOL_basic_ss addsimps |
377 val numeral_simp_ss = HOL_basic_ss addsimps simps @ @{thms simp_thms} |
369 [@{thm eq_number_of_eq}, @{thm less_number_of}, @{thm le_number_of}] @ simps |
|
370 @ @{thms simp_thms} |
|
371 fun numeral_simp_tac ss = ALLGOALS (simp_tac (Simplifier.inherit_context ss numeral_simp_ss)) |
378 fun numeral_simp_tac ss = ALLGOALS (simp_tac (Simplifier.inherit_context ss numeral_simp_ss)) |
372 val simplify_meta_eq = Arith_Data.simplify_meta_eq |
379 val simplify_meta_eq = Arith_Data.simplify_meta_eq |
373 ([@{thm Nat.add_0}, @{thm Nat.add_0_right}] @ post_simps) |
380 ([@{thm Nat.add_0}, @{thm Nat.add_0_right}] @ post_simps) |
374 val prove_conv = Arith_Data.prove_conv |
381 val prove_conv = Arith_Data.prove_conv |
375 end |
382 end |
423 fun divide_cancel_numeral_factor ss ct = DivideCancelNumeralFactor.proc ss (term_of ct) |
430 fun divide_cancel_numeral_factor ss ct = DivideCancelNumeralFactor.proc ss (term_of ct) |
424 |
431 |
425 val field_cancel_numeral_factors = |
432 val field_cancel_numeral_factors = |
426 map (prep_simproc @{theory}) |
433 map (prep_simproc @{theory}) |
427 [("field_eq_cancel_numeral_factor", |
434 [("field_eq_cancel_numeral_factor", |
428 ["(l::'a::{field,number_ring}) * m = n", |
435 ["(l::'a::field) * m = n", |
429 "(l::'a::{field,number_ring}) = m * n"], |
436 "(l::'a::field) = m * n"], |
430 K EqCancelNumeralFactor.proc), |
437 K EqCancelNumeralFactor.proc), |
431 ("field_cancel_numeral_factor", |
438 ("field_cancel_numeral_factor", |
432 ["((l::'a::{field_inverse_zero,number_ring}) * m) / n", |
439 ["((l::'a::field_inverse_zero) * m) / n", |
433 "(l::'a::{field_inverse_zero,number_ring}) / (m * n)", |
440 "(l::'a::field_inverse_zero) / (m * n)", |
434 "((number_of v)::'a::{field_inverse_zero,number_ring}) / (number_of w)"], |
441 "((numeral v)::'a::field_inverse_zero) / (numeral w)", |
|
442 "((numeral v)::'a::field_inverse_zero) / (neg_numeral w)", |
|
443 "((neg_numeral v)::'a::field_inverse_zero) / (numeral w)", |
|
444 "((neg_numeral v)::'a::field_inverse_zero) / (neg_numeral w)"], |
435 K DivideCancelNumeralFactor.proc)] |
445 K DivideCancelNumeralFactor.proc)] |
436 |
446 |
437 |
447 |
438 (** Declarations for ExtractCommonTerm **) |
448 (** Declarations for ExtractCommonTerm **) |
439 |
449 |
676 @{cpat "((?a::(?'a::{field, ord}))/ ?b) = ?c"}], |
686 @{cpat "((?a::(?'a::{field, ord}))/ ?b) = ?c"}], |
677 name = "ord_frac_simproc", proc = proc3, identifier = []} |
687 name = "ord_frac_simproc", proc = proc3, identifier = []} |
678 |
688 |
679 val ths = [@{thm "mult_numeral_1"}, @{thm "mult_numeral_1_right"}, |
689 val ths = [@{thm "mult_numeral_1"}, @{thm "mult_numeral_1_right"}, |
680 @{thm "divide_Numeral1"}, |
690 @{thm "divide_Numeral1"}, |
681 @{thm "divide_zero"}, @{thm "divide_Numeral0"}, |
691 @{thm "divide_zero"}, @{thm divide_zero_left}, |
682 @{thm "divide_divide_eq_left"}, |
692 @{thm "divide_divide_eq_left"}, |
683 @{thm "times_divide_eq_left"}, @{thm "times_divide_eq_right"}, |
693 @{thm "times_divide_eq_left"}, @{thm "times_divide_eq_right"}, |
684 @{thm "times_divide_times_eq"}, |
694 @{thm "times_divide_times_eq"}, |
685 @{thm "divide_divide_eq_right"}, |
695 @{thm "divide_divide_eq_right"}, |
686 @{thm "diff_minus"}, @{thm "minus_divide_left"}, |
696 @{thm "diff_minus"}, @{thm "minus_divide_left"}, |
687 @{thm "Numeral1_eq1_nat"}, @{thm "add_divide_distrib"} RS sym, |
697 @{thm "add_divide_distrib"} RS sym, |
688 @{thm field_divide_inverse} RS sym, @{thm inverse_divide}, |
698 @{thm field_divide_inverse} RS sym, @{thm inverse_divide}, |
689 Conv.fconv_rule (Conv.arg_conv (Conv.arg1_conv (Conv.rewr_conv (mk_meta_eq @{thm mult_commute})))) |
699 Conv.fconv_rule (Conv.arg_conv (Conv.arg1_conv (Conv.rewr_conv (mk_meta_eq @{thm mult_commute})))) |
690 (@{thm field_divide_inverse} RS sym)] |
700 (@{thm field_divide_inverse} RS sym)] |
691 |
701 |
692 in |
702 in |