src/HOL/Tools/numeral_simprocs.ML
changeset 47108 2a1953f0d20d
parent 46497 89ccf66aa73d
child 49323 6dff6b1f5417
equal deleted inserted replaced
47107:35807a5d8dc2 47108:2a1953f0d20d
    64 fun one_of T = Const(@{const_name Groups.one}, T);
    64 fun one_of T = Const(@{const_name Groups.one}, T);
    65 
    65 
    66 (* build product with trailing 1 rather than Numeral 1 in order to avoid the
    66 (* build product with trailing 1 rather than Numeral 1 in order to avoid the
    67    unnecessary restriction to type class number_ring
    67    unnecessary restriction to type class number_ring
    68    which is not required for cancellation of common factors in divisions.
    68    which is not required for cancellation of common factors in divisions.
       
    69    UPDATE: this reasoning no longer applies (number_ring is gone)
    69 *)
    70 *)
    70 fun mk_prod T = 
    71 fun mk_prod T = 
    71   let val one = one_of T
    72   let val one = one_of T
    72   fun mk [] = one
    73   fun mk [] = one
    73     | mk [t] = t
    74     | mk [t] = t
   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
   697       addsimps ths addsimps @{thms simp_thms}
   707       addsimps ths addsimps @{thms simp_thms}
   698       addsimprocs field_cancel_numeral_factors
   708       addsimprocs field_cancel_numeral_factors
   699       addsimprocs [add_frac_frac_simproc, add_frac_num_simproc, ord_frac_simproc]
   709       addsimprocs [add_frac_frac_simproc, add_frac_num_simproc, ord_frac_simproc]
   700       |> Simplifier.add_cong @{thm "if_weak_cong"})
   710       |> Simplifier.add_cong @{thm "if_weak_cong"})
   701   then_conv
   711   then_conv
   702   Simplifier.rewrite (HOL_basic_ss addsimps
   712   Simplifier.rewrite (HOL_basic_ss addsimps [@{thm numeral_1_eq_1}])
   703     [@{thm numeral_1_eq_1},@{thm numeral_0_eq_0}] @ @{thms numerals(1-2)})
       
   704 
   713 
   705 end
   714 end
   706 
   715 
   707 end;
   716 end;
   708 
   717