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 |