src/HOL/Integ/nat_simprocs.ML
changeset 19298 741b8138c2b3
parent 19294 871d7aea081a
child 19481 a6205c6203ea
equal deleted inserted replaced
19297:8f6e097d7b23 19298:741b8138c2b3
    49 (*this version ALWAYS includes a trailing zero*)
    49 (*this version ALWAYS includes a trailing zero*)
    50 fun long_mk_sum []        = HOLogic.zero
    50 fun long_mk_sum []        = HOLogic.zero
    51   | long_mk_sum (t :: ts) = mk_plus (t, mk_sum ts);
    51   | long_mk_sum (t :: ts) = mk_plus (t, mk_sum ts);
    52 
    52 
    53 val dest_plus = HOLogic.dest_bin "HOL.plus" HOLogic.natT;
    53 val dest_plus = HOLogic.dest_bin "HOL.plus" HOLogic.natT;
    54 
       
    55 (*Split up a sum into the list of its constituent terms, on the way removing any
       
    56   Sucs and counting them.*)
       
    57 fun dest_Suc_sum (Const ("Suc", _) $ t, (k,ts)) = dest_Suc_sum (t, (k+1,ts))
       
    58   | dest_Suc_sum (t, (k,ts)) = 
       
    59       let val (t1,t2) = dest_plus t
       
    60       in  dest_Suc_sum (t1, dest_Suc_sum (t2, (k,ts)))  end
       
    61       handle TERM _ => (k, t::ts);
       
    62 
       
    63 (*The Sucs found in the term are converted to a binary numeral*)
       
    64 fun dest_Sucs_sum t = 
       
    65   case dest_Suc_sum (t,(0,[])) of
       
    66       (0,ts) => ts
       
    67     | (k,ts) => mk_numeral k :: ts
       
    68 
    54 
    69 
    55 
    70 (** Other simproc items **)
    56 (** Other simproc items **)
    71 
    57 
    72 val trans_tac = Int_Numeral_Simprocs.trans_tac;
    58 val trans_tac = Int_Numeral_Simprocs.trans_tac;
   119                           else find_first_coeff (t::past) u terms
   105                           else find_first_coeff (t::past) u terms
   120         end
   106         end
   121         handle TERM _ => find_first_coeff (t::past) u terms;
   107         handle TERM _ => find_first_coeff (t::past) u terms;
   122 
   108 
   123 
   109 
       
   110 (*Split up a sum into the list of its constituent terms, on the way removing any
       
   111   Sucs and counting them.*)
       
   112 fun dest_Suc_sum (Const ("Suc", _) $ t, (k,ts)) = dest_Suc_sum (t, (k+1,ts))
       
   113   | dest_Suc_sum (t, (k,ts)) = 
       
   114       let val (t1,t2) = dest_plus t
       
   115       in  dest_Suc_sum (t1, dest_Suc_sum (t2, (k,ts)))  end
       
   116       handle TERM _ => (k, t::ts);
       
   117 
       
   118 (*Code for testing whether numerals are already used in the goal*)
       
   119 fun is_numeral (Const("Numeral.number_of", _) $ w) = true
       
   120   | is_numeral _ = false;
       
   121 
       
   122 fun prod_has_numeral t = exists is_numeral (dest_prod t);
       
   123 
       
   124 (*The Sucs found in the term are converted to a binary numeral. If relaxed is false,
       
   125   an exception is raised unless the original expression contains at least one
       
   126   numeral in a coefficient position.  This prevents nat_combine_numerals from 
       
   127   introducing numerals to goals.*)
       
   128 fun dest_Sucs_sum relaxed t = 
       
   129   let val (k,ts) = dest_Suc_sum (t,(0,[]))
       
   130   in
       
   131      if relaxed orelse exists prod_has_numeral ts then 
       
   132        if k=0 then ts
       
   133        else mk_numeral (IntInf.fromInt k) :: ts
       
   134      else raise TERM("Nat_Numeral_Simprocs.dest_Sucs_sum", [t])
       
   135   end;
       
   136 
       
   137 
   124 (*Simplify 1*n and n*1 to n*)
   138 (*Simplify 1*n and n*1 to n*)
   125 val add_0s  = map rename_numerals [add_0, add_0_right];
   139 val add_0s  = map rename_numerals [add_0, add_0_right];
   126 val mult_1s = map rename_numerals [thm"nat_mult_1", thm"nat_mult_1_right"];
   140 val mult_1s = map rename_numerals [thm"nat_mult_1", thm"nat_mult_1_right"];
   127 
   141 
   128 (*Final simplification: cancel + and *; replace Numeral0 by 0 and Numeral1 by 1*)
   142 (*Final simplification: cancel + and *; replace Numeral0 by 0 and Numeral1 by 1*)
   136     Int_Numeral_Simprocs.simplify_meta_eq
   150     Int_Numeral_Simprocs.simplify_meta_eq
   137         ([nat_numeral_0_eq_0, numeral_1_eq_Suc_0, add_0, add_0_right,
   151         ([nat_numeral_0_eq_0, numeral_1_eq_Suc_0, add_0, add_0_right,
   138           mult_0, mult_0_right, mult_1, mult_1_right] @ contra_rules);
   152           mult_0, mult_0_right, mult_1, mult_1_right] @ contra_rules);
   139 
   153 
   140 
   154 
   141 (** Restricted version of dest_Sucs_sum for nat_combine_numerals:
       
   142     Simprocs never apply unless the original expression contains at least one
       
   143     numeral in a coefficient position. This avoids replacing x+x by
       
   144     2*x, for example, unless numerals have been used already.
       
   145 **)
       
   146 
       
   147 fun is_numeral (Const("Numeral.number_of", _) $ w) = true
       
   148   | is_numeral _ = false;
       
   149 
       
   150 fun prod_has_numeral t = exists is_numeral (dest_prod t);
       
   151 
       
   152 fun require_has_numeral ts = 
       
   153     if exists prod_has_numeral ts then ts
       
   154     else raise TERM("Nat_Numeral_Simprocs.restricted_dest_Sucs_sum", ts);
       
   155 
       
   156 fun restricted_dest_Sucs_sum t =
       
   157   case dest_Suc_sum (t,(0,[])) of
       
   158       (0,ts) => require_has_numeral ts
       
   159     | (k,ts) => mk_numeral k :: require_has_numeral ts
       
   160 
       
   161 
       
   162 (*Like HOL_ss but with an ordering that brings numerals to the front
   155 (*Like HOL_ss but with an ordering that brings numerals to the front
   163   under AC-rewriting.*)
   156   under AC-rewriting.*)
   164 val num_ss = Int_Numeral_Simprocs.num_ss;
   157 val num_ss = Int_Numeral_Simprocs.num_ss;
   165 
   158 
   166 (*** Applying CancelNumeralsFun ***)
   159 (*** Applying CancelNumeralsFun ***)
   167 
   160 
   168 structure CancelNumeralsCommon =
   161 structure CancelNumeralsCommon =
   169   struct
   162   struct
   170   val mk_sum            = (fn T:typ => mk_sum)
   163   val mk_sum            = (fn T:typ => mk_sum)
   171   val dest_sum          = dest_Sucs_sum
   164   val dest_sum          = dest_Sucs_sum true
   172   val mk_coeff          = mk_coeff
   165   val mk_coeff          = mk_coeff
   173   val dest_coeff        = dest_coeff
   166   val dest_coeff        = dest_coeff
   174   val find_first_coeff  = find_first_coeff []
   167   val find_first_coeff  = find_first_coeff []
   175   val trans_tac         = fn _ => trans_tac
   168   val trans_tac         = fn _ => trans_tac
   176 
   169 
   252 
   245 
   253 structure CombineNumeralsData =
   246 structure CombineNumeralsData =
   254   struct
   247   struct
   255   val add               = IntInf.+
   248   val add               = IntInf.+
   256   val mk_sum            = (fn T:typ => long_mk_sum)  (*to work for 2*x + 3*x *)
   249   val mk_sum            = (fn T:typ => long_mk_sum)  (*to work for 2*x + 3*x *)
   257   val dest_sum          = restricted_dest_Sucs_sum
   250   val dest_sum          = dest_Sucs_sum false
   258   val mk_coeff          = mk_coeff
   251   val mk_coeff          = mk_coeff
   259   val dest_coeff        = dest_coeff
   252   val dest_coeff        = dest_coeff
   260   val left_distrib      = left_add_mult_distrib RS trans
   253   val left_distrib      = left_add_mult_distrib RS trans
   261   val prove_conv        = Bin_Simprocs.prove_conv_nohyps
   254   val prove_conv        = Bin_Simprocs.prove_conv_nohyps
   262   val trans_tac         = fn _ => trans_tac
   255   val trans_tac         = fn _ => trans_tac