10 decision procedure for linear arithmetic. |
10 decision procedure for linear arithmetic. |
11 *) |
11 *) |
12 |
12 |
13 (** extra rules for bin_succ, bin_pred, bin_add, bin_mult **) |
13 (** extra rules for bin_succ, bin_pred, bin_add, bin_mult **) |
14 |
14 |
15 qed_goal "NCons_Pls_0" Bin.thy |
15 qed_goal "NCons_Pls_0" thy |
16 "NCons Pls False = Pls" |
16 "NCons Pls False = Pls" |
17 (fn _ => [(Simp_tac 1)]); |
17 (fn _ => [(Simp_tac 1)]); |
18 |
18 |
19 qed_goal "NCons_Pls_1" Bin.thy |
19 qed_goal "NCons_Pls_1" thy |
20 "NCons Pls True = Pls BIT True" |
20 "NCons Pls True = Pls BIT True" |
21 (fn _ => [(Simp_tac 1)]); |
21 (fn _ => [(Simp_tac 1)]); |
22 |
22 |
23 qed_goal "NCons_Min_0" Bin.thy |
23 qed_goal "NCons_Min_0" thy |
24 "NCons Min False = Min BIT False" |
24 "NCons Min False = Min BIT False" |
25 (fn _ => [(Simp_tac 1)]); |
25 (fn _ => [(Simp_tac 1)]); |
26 |
26 |
27 qed_goal "NCons_Min_1" Bin.thy |
27 qed_goal "NCons_Min_1" thy |
28 "NCons Min True = Min" |
28 "NCons Min True = Min" |
29 (fn _ => [(Simp_tac 1)]); |
29 (fn _ => [(Simp_tac 1)]); |
30 |
30 |
31 qed_goal "bin_succ_1" Bin.thy |
31 qed_goal "bin_succ_1" thy |
32 "bin_succ(w BIT True) = (bin_succ w) BIT False" |
32 "bin_succ(w BIT True) = (bin_succ w) BIT False" |
33 (fn _ => [(Simp_tac 1)]); |
33 (fn _ => [(Simp_tac 1)]); |
34 |
34 |
35 qed_goal "bin_succ_0" Bin.thy |
35 qed_goal "bin_succ_0" thy |
36 "bin_succ(w BIT False) = NCons w True" |
36 "bin_succ(w BIT False) = NCons w True" |
37 (fn _ => [(Simp_tac 1)]); |
37 (fn _ => [(Simp_tac 1)]); |
38 |
38 |
39 qed_goal "bin_pred_1" Bin.thy |
39 qed_goal "bin_pred_1" thy |
40 "bin_pred(w BIT True) = NCons w False" |
40 "bin_pred(w BIT True) = NCons w False" |
41 (fn _ => [(Simp_tac 1)]); |
41 (fn _ => [(Simp_tac 1)]); |
42 |
42 |
43 qed_goal "bin_pred_0" Bin.thy |
43 qed_goal "bin_pred_0" thy |
44 "bin_pred(w BIT False) = (bin_pred w) BIT True" |
44 "bin_pred(w BIT False) = (bin_pred w) BIT True" |
45 (fn _ => [(Simp_tac 1)]); |
45 (fn _ => [(Simp_tac 1)]); |
46 |
46 |
47 qed_goal "bin_minus_1" Bin.thy |
47 qed_goal "bin_minus_1" thy |
48 "bin_minus(w BIT True) = bin_pred (NCons (bin_minus w) False)" |
48 "bin_minus(w BIT True) = bin_pred (NCons (bin_minus w) False)" |
49 (fn _ => [(Simp_tac 1)]); |
49 (fn _ => [(Simp_tac 1)]); |
50 |
50 |
51 qed_goal "bin_minus_0" Bin.thy |
51 qed_goal "bin_minus_0" thy |
52 "bin_minus(w BIT False) = (bin_minus w) BIT False" |
52 "bin_minus(w BIT False) = (bin_minus w) BIT False" |
53 (fn _ => [(Simp_tac 1)]); |
53 (fn _ => [(Simp_tac 1)]); |
54 |
54 |
55 |
55 |
56 (*** bin_add: binary addition ***) |
56 (*** bin_add: binary addition ***) |
57 |
57 |
58 qed_goal "bin_add_BIT_11" Bin.thy |
58 qed_goal "bin_add_BIT_11" thy |
59 "bin_add (v BIT True) (w BIT True) = \ |
59 "bin_add (v BIT True) (w BIT True) = \ |
60 \ NCons (bin_add v (bin_succ w)) False" |
60 \ NCons (bin_add v (bin_succ w)) False" |
61 (fn _ => [(Simp_tac 1)]); |
61 (fn _ => [(Simp_tac 1)]); |
62 |
62 |
63 qed_goal "bin_add_BIT_10" Bin.thy |
63 qed_goal "bin_add_BIT_10" thy |
64 "bin_add (v BIT True) (w BIT False) = NCons (bin_add v w) True" |
64 "bin_add (v BIT True) (w BIT False) = NCons (bin_add v w) True" |
65 (fn _ => [(Simp_tac 1)]); |
65 (fn _ => [(Simp_tac 1)]); |
66 |
66 |
67 qed_goal "bin_add_BIT_0" Bin.thy |
67 qed_goal "bin_add_BIT_0" thy |
68 "bin_add (v BIT False) (w BIT y) = NCons (bin_add v w) y" |
68 "bin_add (v BIT False) (w BIT y) = NCons (bin_add v w) y" |
69 (fn _ => [Auto_tac]); |
69 (fn _ => [Auto_tac]); |
70 |
70 |
71 Goal "bin_add w Pls = w"; |
71 Goal "bin_add w Pls = w"; |
72 by (induct_tac "w" 1); |
72 by (induct_tac "w" 1); |
73 by Auto_tac; |
73 by Auto_tac; |
74 qed "bin_add_Pls_right"; |
74 qed "bin_add_Pls_right"; |
75 |
75 |
76 qed_goal "bin_add_BIT_Min" Bin.thy |
76 qed_goal "bin_add_BIT_Min" thy |
77 "bin_add (v BIT x) Min = bin_pred (v BIT x)" |
77 "bin_add (v BIT x) Min = bin_pred (v BIT x)" |
78 (fn _ => [(Simp_tac 1)]); |
78 (fn _ => [(Simp_tac 1)]); |
79 |
79 |
80 qed_goal "bin_add_BIT_BIT" Bin.thy |
80 qed_goal "bin_add_BIT_BIT" thy |
81 "bin_add (v BIT x) (w BIT y) = \ |
81 "bin_add (v BIT x) (w BIT y) = \ |
82 \ NCons(bin_add v (if x & y then (bin_succ w) else w)) (x~= y)" |
82 \ NCons(bin_add v (if x & y then (bin_succ w) else w)) (x~= y)" |
83 (fn _ => [(Simp_tac 1)]); |
83 (fn _ => [(Simp_tac 1)]); |
84 |
84 |
85 |
85 |
86 (*** bin_mult: binary multiplication ***) |
86 (*** bin_mult: binary multiplication ***) |
87 |
87 |
88 qed_goal "bin_mult_1" Bin.thy |
88 qed_goal "bin_mult_1" thy |
89 "bin_mult (v BIT True) w = bin_add (NCons (bin_mult v w) False) w" |
89 "bin_mult (v BIT True) w = bin_add (NCons (bin_mult v w) False) w" |
90 (fn _ => [(Simp_tac 1)]); |
90 (fn _ => [(Simp_tac 1)]); |
91 |
91 |
92 qed_goal "bin_mult_0" Bin.thy |
92 qed_goal "bin_mult_0" thy |
93 "bin_mult (v BIT False) w = NCons (bin_mult v w) False" |
93 "bin_mult (v BIT False) w = NCons (bin_mult v w) False" |
94 (fn _ => [(Simp_tac 1)]); |
94 (fn _ => [(Simp_tac 1)]); |
95 |
95 |
96 |
96 |
97 (**** The carry/borrow functions, bin_succ and bin_pred ****) |
97 (**** The carry/borrow functions, bin_succ and bin_pred ****) |
98 |
98 |
99 |
99 |
100 (**** integ_of ****) |
100 (**** number_of ****) |
101 |
101 |
102 qed_goal "integ_of_NCons" Bin.thy |
102 qed_goal "number_of_NCons" thy |
103 "integ_of(NCons w b) = integ_of(w BIT b)" |
103 "number_of(NCons w b) = (number_of(w BIT b)::int)" |
104 (fn _ =>[(induct_tac "w" 1), |
104 (fn _ =>[(induct_tac "w" 1), |
105 (ALLGOALS Asm_simp_tac) ]); |
105 (ALLGOALS Asm_simp_tac) ]); |
106 |
106 |
107 Addsimps [integ_of_NCons]; |
107 Addsimps [number_of_NCons]; |
108 |
108 |
109 qed_goal "integ_of_succ" Bin.thy |
109 qed_goal "number_of_succ" thy |
110 "integ_of(bin_succ w) = int 1 + integ_of w" |
110 "number_of(bin_succ w) = int 1 + number_of w" |
111 (fn _ =>[(rtac bin.induct 1), |
111 (fn _ =>[induct_tac "w" 1, |
112 (ALLGOALS(asm_simp_tac (simpset() addsimps zadd_ac))) ]); |
112 (ALLGOALS(asm_simp_tac (simpset() addsimps zadd_ac))) ]); |
113 |
113 |
114 qed_goal "integ_of_pred" Bin.thy |
114 qed_goal "number_of_pred" thy |
115 "integ_of(bin_pred w) = - (int 1) + integ_of w" |
115 "number_of(bin_pred w) = - (int 1) + number_of w" |
116 (fn _ =>[(rtac bin.induct 1), |
116 (fn _ =>[induct_tac "w" 1, |
117 (ALLGOALS(asm_simp_tac (simpset() addsimps zadd_ac))) ]); |
117 (ALLGOALS(asm_simp_tac (simpset() addsimps zadd_ac))) ]); |
118 |
118 |
119 Goal "integ_of(bin_minus w) = - (integ_of w)"; |
119 Goal "number_of(bin_minus w) = (- (number_of w)::int)"; |
120 by (rtac bin.induct 1); |
120 by (induct_tac "w" 1); |
121 by (Simp_tac 1); |
121 by (Simp_tac 1); |
122 by (Simp_tac 1); |
122 by (Simp_tac 1); |
123 by (asm_simp_tac (simpset() |
123 by (asm_simp_tac (simpset() |
124 delsimps [bin_pred_Pls, bin_pred_Min, bin_pred_BIT] |
124 delsimps [bin_pred_Pls, bin_pred_Min, bin_pred_BIT] |
125 addsimps [integ_of_succ,integ_of_pred, |
125 addsimps [number_of_succ,number_of_pred, |
126 zadd_assoc]) 1); |
126 zadd_assoc]) 1); |
127 qed "integ_of_minus"; |
127 qed "number_of_minus"; |
128 |
128 |
129 |
129 |
130 val bin_add_simps = [bin_add_BIT_BIT, integ_of_succ, integ_of_pred]; |
130 val bin_add_simps = [bin_add_BIT_BIT, number_of_succ, number_of_pred]; |
131 |
131 |
132 (*This proof is complicated by the mutual recursion*) |
132 (*This proof is complicated by the mutual recursion*) |
133 Goal "! w. integ_of(bin_add v w) = integ_of v + integ_of w"; |
133 Goal "! w. number_of(bin_add v w) = (number_of v + number_of w::int)"; |
134 by (induct_tac "v" 1); |
134 by (induct_tac "v" 1); |
135 by (simp_tac (simpset() addsimps bin_add_simps) 1); |
135 by (simp_tac (simpset() addsimps bin_add_simps) 1); |
136 by (simp_tac (simpset() addsimps bin_add_simps) 1); |
136 by (simp_tac (simpset() addsimps bin_add_simps) 1); |
137 by (rtac allI 1); |
137 by (rtac allI 1); |
138 by (induct_tac "w" 1); |
138 by (induct_tac "w" 1); |
139 by (ALLGOALS (asm_simp_tac (simpset() addsimps bin_add_simps @ zadd_ac))); |
139 by (ALLGOALS (asm_simp_tac (simpset() addsimps bin_add_simps @ zadd_ac))); |
140 qed_spec_mp "integ_of_add"; |
140 qed_spec_mp "number_of_add"; |
141 |
141 |
142 |
142 |
143 (*Subtraction*) |
143 (*Subtraction*) |
144 Goalw [zdiff_def] |
144 Goalw [zdiff_def] |
145 "integ_of v - integ_of w = integ_of(bin_add v (bin_minus w))"; |
145 "number_of v - number_of w = (number_of(bin_add v (bin_minus w))::int)"; |
146 by (simp_tac (simpset() addsimps [integ_of_add, integ_of_minus]) 1); |
146 by (simp_tac (simpset() addsimps [number_of_add, number_of_minus]) 1); |
147 qed "diff_integ_of_eq"; |
147 qed "diff_number_of_eq"; |
148 |
148 |
149 val bin_mult_simps = [zmult_zminus, integ_of_minus, integ_of_add]; |
149 val bin_mult_simps = [zmult_zminus, number_of_minus, number_of_add]; |
150 |
150 |
151 Goal "integ_of(bin_mult v w) = integ_of v * integ_of w"; |
151 Goal "number_of(bin_mult v w) = (number_of v * number_of w::int)"; |
152 by (induct_tac "v" 1); |
152 by (induct_tac "v" 1); |
153 by (simp_tac (simpset() addsimps bin_mult_simps) 1); |
153 by (simp_tac (simpset() addsimps bin_mult_simps) 1); |
154 by (simp_tac (simpset() addsimps bin_mult_simps) 1); |
154 by (simp_tac (simpset() addsimps bin_mult_simps) 1); |
155 by (asm_simp_tac |
155 by (asm_simp_tac |
156 (simpset() addsimps bin_mult_simps @ [zadd_zmult_distrib] @ zadd_ac) 1); |
156 (simpset() addsimps bin_mult_simps @ [zadd_zmult_distrib] @ zadd_ac) 1); |
157 qed "integ_of_mult"; |
157 qed "number_of_mult"; |
158 |
158 |
159 |
159 |
160 (** Simplification rules with integer constants **) |
160 (** Simplification rules with integer constants **) |
161 |
161 |
162 Goal "#0 + z = z"; |
162 Goal "#0 + z = (z::int)"; |
163 by (Simp_tac 1); |
163 by (Simp_tac 1); |
164 qed "zadd_0"; |
164 qed "zadd_0"; |
165 |
165 |
166 Goal "z + #0 = z"; |
166 Goal "z + #0 = (z::int)"; |
167 by (Simp_tac 1); |
167 by (Simp_tac 1); |
168 qed "zadd_0_right"; |
168 qed "zadd_0_right"; |
169 |
169 |
170 Addsimps [zadd_0, zadd_0_right]; |
170 Addsimps [zadd_0, zadd_0_right]; |
171 |
171 |
172 |
172 |
173 (** Converting simple cases of (int n) to numerals **) |
173 (** Converting simple cases of (int n) to numerals **) |
174 |
174 |
175 (*int 0 = #0 *) |
175 (*int 0 = #0 *) |
176 bind_thm ("int_0", integ_of_Pls RS sym); |
176 bind_thm ("int_0", number_of_Pls RS sym); |
177 |
177 |
178 Goal "int (Suc n) = #1 + int n"; |
178 Goal "int (Suc n) = #1 + int n"; |
179 by (simp_tac (simpset() addsimps [zadd_int]) 1); |
179 by (simp_tac (simpset() addsimps [zadd_int]) 1); |
180 qed "int_Suc"; |
180 qed "int_Suc"; |
181 |
181 |
182 Goal "- (#0) = #0"; |
182 Goal "- (#0) = (#0::int)"; |
183 by (Simp_tac 1); |
183 by (Simp_tac 1); |
184 qed "zminus_0"; |
184 qed "zminus_0"; |
185 |
185 |
186 Addsimps [zminus_0]; |
186 Addsimps [zminus_0]; |
187 |
187 |
188 |
188 |
189 Goal "#0 - x = -x"; |
189 Goal "(#0::int) - x = -x"; |
190 by (simp_tac (simpset() addsimps [zdiff_def]) 1); |
190 by (simp_tac (simpset() addsimps [zdiff_def]) 1); |
191 qed "zdiff0"; |
191 qed "zdiff0"; |
192 |
192 |
193 Goal "x - #0 = x"; |
193 Goal "x - (#0::int) = x"; |
194 by (simp_tac (simpset() addsimps [zdiff_def]) 1); |
194 by (simp_tac (simpset() addsimps [zdiff_def]) 1); |
195 qed "zdiff0_right"; |
195 qed "zdiff0_right"; |
196 |
196 |
197 Goal "x - x = #0"; |
197 Goal "x - x = (#0::int)"; |
198 by (simp_tac (simpset() addsimps [zdiff_def]) 1); |
198 by (simp_tac (simpset() addsimps [zdiff_def]) 1); |
199 qed "zdiff_self"; |
199 qed "zdiff_self"; |
200 |
200 |
201 Addsimps [zdiff0, zdiff0_right, zdiff_self]; |
201 Addsimps [zdiff0, zdiff0_right, zdiff_self]; |
202 |
202 |
203 (** Distributive laws for constants only **) |
203 (** Distributive laws for constants only **) |
204 |
204 |
205 Addsimps (map (read_instantiate_sg (sign_of Bin.thy) [("w", "integ_of ?v")]) |
205 Addsimps (map (read_instantiate_sg (sign_of thy) [("w", "number_of ?v")]) |
206 [zadd_zmult_distrib, zadd_zmult_distrib2, |
206 [zadd_zmult_distrib, zadd_zmult_distrib2, |
207 zdiff_zmult_distrib, zdiff_zmult_distrib2]); |
207 zdiff_zmult_distrib, zdiff_zmult_distrib2]); |
208 |
208 |
209 (** Special-case simplification for small constants **) |
209 (** Special-case simplification for small constants **) |
210 |
210 |
211 Goal "#0 * z = #0"; |
211 Goal "#0 * z = (#0::int)"; |
212 by (Simp_tac 1); |
212 by (Simp_tac 1); |
213 qed "zmult_0"; |
213 qed "zmult_0"; |
214 |
214 |
215 Goal "z * #0 = #0"; |
215 Goal "z * #0 = (#0::int)"; |
216 by (Simp_tac 1); |
216 by (Simp_tac 1); |
217 qed "zmult_0_right"; |
217 qed "zmult_0_right"; |
218 |
218 |
219 Goal "#1 * z = z"; |
219 Goal "#1 * z = (z::int)"; |
220 by (Simp_tac 1); |
220 by (Simp_tac 1); |
221 qed "zmult_1"; |
221 qed "zmult_1"; |
222 |
222 |
223 Goal "z * #1 = z"; |
223 Goal "z * #1 = (z::int)"; |
224 by (Simp_tac 1); |
224 by (Simp_tac 1); |
225 qed "zmult_1_right"; |
225 qed "zmult_1_right"; |
226 |
226 |
227 (*For specialist use*) |
227 (*For specialist use*) |
228 Goal "#2 * z = z+z"; |
228 Goal "#2 * z = (z+z::int)"; |
229 by (simp_tac (simpset() addsimps [zadd_zmult_distrib]) 1); |
229 by (simp_tac (simpset() addsimps [zadd_zmult_distrib]) 1); |
230 qed "zmult_2"; |
230 qed "zmult_2"; |
231 |
231 |
232 Goal "z * #2 = z+z"; |
232 Goal "z * #2 = (z+z::int)"; |
233 by (simp_tac (simpset() addsimps [zadd_zmult_distrib2]) 1); |
233 by (simp_tac (simpset() addsimps [zadd_zmult_distrib2]) 1); |
234 qed "zmult_2_right"; |
234 qed "zmult_2_right"; |
235 |
235 |
236 Addsimps [zmult_0, zmult_0_right, |
236 Addsimps [zmult_0, zmult_0_right, |
237 zmult_1, zmult_1_right]; |
237 zmult_1, zmult_1_right]; |
238 |
238 |
239 Goal "(w < z + #1) = (w<z | w=z)"; |
239 Goal "(w < z + (#1::int)) = (w<z | w=z)"; |
240 by (simp_tac (simpset() addsimps [zless_add_int_Suc_eq]) 1); |
240 by (simp_tac (simpset() addsimps [zless_add_int_Suc_eq]) 1); |
241 qed "zless_add1_eq"; |
241 qed "zless_add1_eq"; |
242 |
242 |
243 Goal "(w + #1 <= z) = (w<z)"; |
243 Goal "(w + (#1::int) <= z) = (w<z)"; |
244 by (simp_tac (simpset() addsimps [add_int_Suc_zle_eq]) 1); |
244 by (simp_tac (simpset() addsimps [add_int_Suc_zle_eq]) 1); |
245 qed "add1_zle_eq"; |
245 qed "add1_zle_eq"; |
246 Addsimps [add1_zle_eq]; |
246 Addsimps [add1_zle_eq]; |
247 |
247 |
248 Goal "neg x = (x < #0)"; |
248 Goal "neg x = (x < #0)"; |
284 (** Simplification rules for comparison of binary numbers (Norbert Voelker) **) |
284 (** Simplification rules for comparison of binary numbers (Norbert Voelker) **) |
285 |
285 |
286 (** Equals (=) **) |
286 (** Equals (=) **) |
287 |
287 |
288 Goalw [iszero_def] |
288 Goalw [iszero_def] |
289 "(integ_of x = integ_of y) = iszero(integ_of (bin_add x (bin_minus y)))"; |
289 "((number_of x::int) = number_of y) = iszero(number_of (bin_add x (bin_minus y)))"; |
290 by (simp_tac (simpset() addsimps |
290 by (simp_tac (simpset() addsimps |
291 (zcompare_rls @ [integ_of_add, integ_of_minus])) 1); |
291 (zcompare_rls @ [number_of_add, number_of_minus])) 1); |
292 qed "eq_integ_of_eq"; |
292 qed "eq_number_of_eq"; |
293 |
293 |
294 Goalw [iszero_def] "iszero (integ_of Pls)"; |
294 Goalw [iszero_def] "iszero ((number_of Pls)::int)"; |
295 by (Simp_tac 1); |
295 by (Simp_tac 1); |
296 qed "iszero_integ_of_Pls"; |
296 qed "iszero_number_of_Pls"; |
297 |
297 |
298 Goalw [iszero_def] "~ iszero(integ_of Min)"; |
298 Goalw [iszero_def] "~ iszero ((number_of Min)::int)"; |
299 by (Simp_tac 1); |
299 by (Simp_tac 1); |
300 qed "nonzero_integ_of_Min"; |
300 qed "nonzero_number_of_Min"; |
301 |
301 |
302 Goalw [iszero_def] |
302 Goalw [iszero_def] |
303 "iszero (integ_of (w BIT x)) = (~x & iszero (integ_of w))"; |
303 "iszero (number_of (w BIT x)) = (~x & iszero (number_of w::int))"; |
304 by (Simp_tac 1); |
304 by (Simp_tac 1); |
305 by (int_case_tac "integ_of w" 1); |
305 by (int_case_tac "number_of w" 1); |
306 by (ALLGOALS (asm_simp_tac |
306 by (ALLGOALS (asm_simp_tac |
307 (simpset() addsimps zcompare_rls @ |
307 (simpset() addsimps zcompare_rls @ |
308 [zminus_zadd_distrib RS sym, |
308 [zminus_zadd_distrib RS sym, |
309 zadd_int]))); |
309 zadd_int]))); |
310 qed "iszero_integ_of_BIT"; |
310 qed "iszero_number_of_BIT"; |
311 |
311 |
312 Goal "iszero (integ_of (w BIT False)) = iszero (integ_of w)"; |
312 Goal "iszero (number_of (w BIT False)) = iszero (number_of w::int)"; |
313 by (simp_tac (HOL_ss addsimps [iszero_integ_of_BIT]) 1); |
313 by (simp_tac (HOL_ss addsimps [iszero_number_of_BIT]) 1); |
314 qed "iszero_integ_of_0"; |
314 qed "iszero_number_of_0"; |
315 |
315 |
316 Goal "~ iszero (integ_of (w BIT True))"; |
316 Goal "~ iszero (number_of (w BIT True)::int)"; |
317 by (simp_tac (HOL_ss addsimps [iszero_integ_of_BIT]) 1); |
317 by (simp_tac (HOL_ss addsimps [iszero_number_of_BIT]) 1); |
318 qed "iszero_integ_of_1"; |
318 qed "iszero_number_of_1"; |
319 |
319 |
320 |
320 |
321 |
321 |
322 (** Less-than (<) **) |
322 (** Less-than (<) **) |
323 |
323 |
324 Goalw [zless_def,zdiff_def] |
324 Goalw [zless_def,zdiff_def] |
325 "integ_of x < integ_of y \ |
325 "(number_of x::int) < number_of y \ |
326 \ = neg (integ_of (bin_add x (bin_minus y)))"; |
326 \ = neg (number_of (bin_add x (bin_minus y)))"; |
327 by (simp_tac (simpset() addsimps bin_mult_simps) 1); |
327 by (simp_tac (simpset() addsimps bin_mult_simps) 1); |
328 qed "less_integ_of_eq_neg"; |
328 qed "less_number_of_eq_neg"; |
329 |
329 |
330 Goal "~ neg (integ_of Pls)"; |
330 Goal "~ neg (number_of Pls)"; |
331 by (Simp_tac 1); |
331 by (Simp_tac 1); |
332 qed "not_neg_integ_of_Pls"; |
332 qed "not_neg_number_of_Pls"; |
333 |
333 |
334 Goal "neg (integ_of Min)"; |
334 Goal "neg (number_of Min)"; |
335 by (Simp_tac 1); |
335 by (Simp_tac 1); |
336 qed "neg_integ_of_Min"; |
336 qed "neg_number_of_Min"; |
337 |
337 |
338 Goal "neg (integ_of (w BIT x)) = neg (integ_of w)"; |
338 Goal "neg (number_of (w BIT x)) = neg (number_of w)"; |
339 by (Asm_simp_tac 1); |
339 by (Asm_simp_tac 1); |
340 by (int_case_tac "integ_of w" 1); |
340 by (int_case_tac "number_of w" 1); |
341 by (ALLGOALS (asm_simp_tac |
341 by (ALLGOALS (asm_simp_tac |
342 (simpset() addsimps [zadd_int, neg_eq_less_nat0, |
342 (simpset() addsimps [zadd_int, neg_eq_less_nat0, |
343 symmetric zdiff_def] @ zcompare_rls))); |
343 symmetric zdiff_def] @ zcompare_rls))); |
344 qed "neg_integ_of_BIT"; |
344 qed "neg_number_of_BIT"; |
345 |
345 |
346 |
346 |
347 (** Less-than-or-equals (<=) **) |
347 (** Less-than-or-equals (<=) **) |
348 |
348 |
349 Goal "(integ_of x <= integ_of y) = (~ integ_of y < integ_of x)"; |
349 Goal "(number_of x <= (number_of y::int)) = (~ number_of y < (number_of x::int))"; |
350 by (simp_tac (simpset() addsimps [zle_def]) 1); |
350 by (simp_tac (simpset() addsimps [zle_def]) 1); |
351 qed "le_integ_of_eq_not_less"; |
351 qed "le_number_of_eq_not_less"; |
352 |
352 |
353 (*Delete the original rewrites, with their clumsy conditional expressions*) |
353 (*Delete the original rewrites, with their clumsy conditional expressions*) |
354 Delsimps [bin_succ_BIT, bin_pred_BIT, bin_minus_BIT, |
354 Delsimps [bin_succ_BIT, bin_pred_BIT, bin_minus_BIT, |
355 NCons_Pls, NCons_Min, bin_add_BIT, bin_mult_BIT]; |
355 NCons_Pls, NCons_Min, bin_add_BIT, bin_mult_BIT]; |
356 |
356 |
357 (*Hide the binary representation of integer constants*) |
357 (*Hide the binary representation of integer constants*) |
358 Delsimps [integ_of_Pls, integ_of_Min, integ_of_BIT]; |
358 Delsimps [number_of_Pls, number_of_Min, number_of_BIT]; |
359 |
359 |
360 (*simplification of arithmetic operations on integer constants*) |
360 (*simplification of arithmetic operations on integer constants*) |
361 val bin_arith_extra_simps = |
361 val bin_arith_extra_simps = |
362 [integ_of_add RS sym, |
362 [number_of_add RS sym, |
363 integ_of_minus RS sym, |
363 number_of_minus RS sym, |
364 integ_of_mult RS sym, |
364 number_of_mult RS sym, |
365 bin_succ_1, bin_succ_0, |
365 bin_succ_1, bin_succ_0, |
366 bin_pred_1, bin_pred_0, |
366 bin_pred_1, bin_pred_0, |
367 bin_minus_1, bin_minus_0, |
367 bin_minus_1, bin_minus_0, |
368 bin_add_Pls_right, bin_add_BIT_Min, |
368 bin_add_Pls_right, bin_add_BIT_Min, |
369 bin_add_BIT_0, bin_add_BIT_10, bin_add_BIT_11, |
369 bin_add_BIT_0, bin_add_BIT_10, bin_add_BIT_11, |
370 diff_integ_of_eq, |
370 diff_number_of_eq, |
371 bin_mult_1, bin_mult_0, |
371 bin_mult_1, bin_mult_0, |
372 NCons_Pls_0, NCons_Pls_1, |
372 NCons_Pls_0, NCons_Pls_1, |
373 NCons_Min_0, NCons_Min_1, NCons_BIT]; |
373 NCons_Min_0, NCons_Min_1, NCons_BIT]; |
374 |
374 |
375 (*For making a minimal simpset, one must include these default simprules |
375 (*For making a minimal simpset, one must include these default simprules |
376 of Bin.thy. Also include simp_thms, or at least (~False)=True*) |
376 of thy. Also include simp_thms, or at least (~False)=True*) |
377 val bin_arith_simps = |
377 val bin_arith_simps = |
378 [bin_pred_Pls, bin_pred_Min, |
378 [bin_pred_Pls, bin_pred_Min, |
379 bin_succ_Pls, bin_succ_Min, |
379 bin_succ_Pls, bin_succ_Min, |
380 bin_add_Pls, bin_add_Min, |
380 bin_add_Pls, bin_add_Min, |
381 bin_minus_Pls, bin_minus_Min, |
381 bin_minus_Pls, bin_minus_Min, |
382 bin_mult_Pls, bin_mult_Min] @ bin_arith_extra_simps; |
382 bin_mult_Pls, bin_mult_Min] @ bin_arith_extra_simps; |
383 |
383 |
384 (*Simplification of relational operations*) |
384 (*Simplification of relational operations*) |
385 val bin_rel_simps = |
385 val bin_rel_simps = |
386 [eq_integ_of_eq, iszero_integ_of_Pls, nonzero_integ_of_Min, |
386 [eq_number_of_eq, iszero_number_of_Pls, nonzero_number_of_Min, |
387 iszero_integ_of_0, iszero_integ_of_1, |
387 iszero_number_of_0, iszero_number_of_1, |
388 less_integ_of_eq_neg, |
388 less_number_of_eq_neg, |
389 not_neg_integ_of_Pls, neg_integ_of_Min, neg_integ_of_BIT, |
389 not_neg_number_of_Pls, neg_number_of_Min, neg_number_of_BIT, |
390 le_integ_of_eq_not_less]; |
390 le_number_of_eq_not_less]; |
391 |
391 |
392 Addsimps bin_arith_extra_simps; |
392 Addsimps bin_arith_extra_simps; |
393 Addsimps bin_rel_simps; |
393 Addsimps bin_rel_simps; |
394 |
394 |
395 (*---------------------------------------------------------------------------*) |
395 (*---------------------------------------------------------------------------*) |
408 structure Int_LA_Data(*: LIN_ARITH_DATA*) = |
408 structure Int_LA_Data(*: LIN_ARITH_DATA*) = |
409 struct |
409 struct |
410 |
410 |
411 val lessD = Nat_LA_Data.lessD @ [add1_zle_eq RS iffD2]; |
411 val lessD = Nat_LA_Data.lessD @ [add1_zle_eq RS iffD2]; |
412 |
412 |
413 (* borrowed from Bin.thy: *) |
|
414 fun dest_bit (Const ("False", _)) = 0 |
|
415 | dest_bit (Const ("True", _)) = 1 |
|
416 | dest_bit _ = raise Match; |
|
417 |
|
418 fun dest_bin tm = |
|
419 let |
|
420 fun bin_of (Const ("Bin.bin.Pls", _)) = [] |
|
421 | bin_of (Const ("Bin.bin.Min", _)) = [~1] |
|
422 | bin_of (Const ("Bin.bin.op BIT", _) $ bs $ b) = dest_bit b :: bin_of bs |
|
423 | bin_of _ = raise Match; |
|
424 |
|
425 fun int_of [] = 0 |
|
426 | int_of (b :: bs) = b + 2 * int_of bs; |
|
427 |
|
428 in int_of(bin_of tm) end; |
|
429 |
|
430 fun add_atom(t,m,(p,i)) = (case assoc(p,t) of None => ((t,m)::p,i) |
413 fun add_atom(t,m,(p,i)) = (case assoc(p,t) of None => ((t,m)::p,i) |
431 | Some n => (overwrite(p,(t,n+m:int)), i)); |
414 | Some n => (overwrite(p,(t,n+m:int)), i)); |
432 |
415 |
433 (* Turn term into list of summand * multiplicity plus a constant *) |
416 (* Turn term into list of summand * multiplicity plus a constant *) |
434 fun poly(Const("op +",_) $ s $ t, m, pi) = poly(s,m,poly(t,m,pi)) |
417 fun poly(Const("op +",_) $ s $ t, m, pi) = poly(s,m,poly(t,m,pi)) |
435 | poly(Const("op -",_) $ s $ t, m, pi) = poly(s,m,poly(t,~1*m,pi)) |
418 | poly(Const("op -",_) $ s $ t, m, pi) = poly(s,m,poly(t,~1*m,pi)) |
436 | poly(Const("uminus",_) $ t, m, pi) = poly(t,~1*m,pi) |
419 | poly(Const("uminus",_) $ t, m, pi) = poly(t,~1*m,pi) |
437 | poly(all as Const("op *",_) $ (Const("Bin.integ_of",_)$c) $ t, m, pi) = |
420 | poly(all as Const("op *",_) $ (Const("Numeral.number_of",_)$c) $ t, m, pi) = |
438 (poly(t,m*dest_bin c,pi) handle Match => add_atom(all,m,pi)) |
421 (poly(t,m*NumeralSyntax.dest_bin c,pi) handle Match => add_atom(all,m,pi)) |
439 | poly(all as Const("Bin.integ_of",_)$t,m,(p,i)) = |
422 | poly(all as Const("Numeral.number_of",_)$t,m,(p,i)) = |
440 ((p,i + m*dest_bin t) handle Match => add_atom(all,m,(p,i))) |
423 ((p,i + m*NumeralSyntax.dest_bin t) handle Match => add_atom(all,m,(p,i))) |
441 | poly x = add_atom x; |
424 | poly x = add_atom x; |
442 |
425 |
443 fun decomp2(rel,lhs,rhs) = |
426 fun decomp2(rel,lhs,rhs) = |
444 let val (p,i) = poly(lhs,1,([],0)) and (q,j) = poly(rhs,1,([],0)) |
427 let val (p,i) = poly(lhs,1,([],0)) and (q,j) = poly(rhs,1,([],0)) |
445 in case rel of |
428 in case rel of |
539 (* End of linear arithmetic *) |
522 (* End of linear arithmetic *) |
540 (*---------------------------------------------------------------------------*) |
523 (*---------------------------------------------------------------------------*) |
541 |
524 |
542 (** Simplification of arithmetic when nested to the right **) |
525 (** Simplification of arithmetic when nested to the right **) |
543 |
526 |
544 Goal "integ_of v + (integ_of w + z) = integ_of(bin_add v w) + z"; |
527 Goal "number_of v + (number_of w + z) = (number_of(bin_add v w) + z::int)"; |
545 by (simp_tac (simpset() addsimps [zadd_assoc RS sym]) 1); |
528 by (simp_tac (simpset() addsimps [zadd_assoc RS sym]) 1); |
546 qed "add_integ_of_left"; |
529 qed "add_number_of_left"; |
547 |
530 |
548 Goal "integ_of v * (integ_of w * z) = integ_of(bin_mult v w) * z"; |
531 Goal "number_of v * (number_of w * z) = (number_of(bin_mult v w) * z::int)"; |
549 by (simp_tac (simpset() addsimps [zmult_assoc RS sym]) 1); |
532 by (simp_tac (simpset() addsimps [zmult_assoc RS sym]) 1); |
550 qed "mult_integ_of_left"; |
533 qed "mult_number_of_left"; |
551 |
534 |
552 Addsimps [add_integ_of_left, mult_integ_of_left]; |
535 Addsimps [add_number_of_left, mult_number_of_left]; |
553 |
536 |
554 (** Simplification of inequalities involving numerical constants **) |
537 (** Simplification of inequalities involving numerical constants **) |
555 |
538 |
556 Goal "(w <= z + #1) = (w<=z | w = z + #1)"; |
539 Goal "(w <= z + (#1::int)) = (w<=z | w = z + (#1::int))"; |
557 by (arith_tac 1); |
540 by (arith_tac 1); |
558 qed "zle_add1_eq"; |
541 qed "zle_add1_eq"; |
559 |
542 |
560 Goal "(w <= z - #1) = (w<z)"; |
543 Goal "(w <= z - (#1::int)) = (w<(z::int))"; |
561 by (arith_tac 1); |
544 by (arith_tac 1); |
562 qed "zle_diff1_eq"; |
545 qed "zle_diff1_eq"; |
563 Addsimps [zle_diff1_eq]; |
546 Addsimps [zle_diff1_eq]; |
564 |
547 |
565 (*2nd premise can be proved automatically if v is a literal*) |
548 (*2nd premise can be proved automatically if v is a literal*) |
566 Goal "[| w <= z; #0 <= v |] ==> w <= z + v"; |
549 Goal "[| w <= z; #0 <= v |] ==> w <= z + (v::int)"; |
567 by (fast_arith_tac 1); |
550 by (fast_arith_tac 1); |
568 qed "zle_imp_zle_zadd"; |
551 qed "zle_imp_zle_zadd"; |
569 |
552 |
570 Goal "w <= z ==> w <= z + #1"; |
553 Goal "w <= z ==> w <= z + (#1::int)"; |
571 by (fast_arith_tac 1); |
554 by (fast_arith_tac 1); |
572 qed "zle_imp_zle_zadd1"; |
555 qed "zle_imp_zle_zadd1"; |
573 |
556 |
574 (*2nd premise can be proved automatically if v is a literal*) |
557 (*2nd premise can be proved automatically if v is a literal*) |
575 Goal "[| w < z; #0 <= v |] ==> w < z + v"; |
558 Goal "[| w < z; #0 <= v |] ==> w < z + (v::int)"; |
576 by (fast_arith_tac 1); |
559 by (fast_arith_tac 1); |
577 qed "zless_imp_zless_zadd"; |
560 qed "zless_imp_zless_zadd"; |
578 |
561 |
579 Goal "w < z ==> w < z + #1"; |
562 Goal "w < z ==> w < z + (#1::int)"; |
580 by (fast_arith_tac 1); |
563 by (fast_arith_tac 1); |
581 qed "zless_imp_zless_zadd1"; |
564 qed "zless_imp_zless_zadd1"; |
582 |
565 |
583 Goal "(w < z + #1) = (w<=z)"; |
566 Goal "(w < z + #1) = (w<=(z::int))"; |
584 by (arith_tac 1); |
567 by (arith_tac 1); |
585 qed "zle_add1_eq_le"; |
568 qed "zle_add1_eq_le"; |
586 Addsimps [zle_add1_eq_le]; |
569 Addsimps [zle_add1_eq_le]; |
587 |
570 |
588 Goal "(z = z + w) = (w = #0)"; |
571 Goal "(z = z + w) = (w = (#0::int))"; |
589 by (arith_tac 1); |
572 by (arith_tac 1); |
590 qed "zadd_left_cancel0"; |
573 qed "zadd_left_cancel0"; |
591 Addsimps [zadd_left_cancel0]; |
574 Addsimps [zadd_left_cancel0]; |
592 |
575 |
593 (*LOOPS as a simprule!*) |
576 (*LOOPS as a simprule!*) |
594 Goal "[| w + v < z; #0 <= v |] ==> w < z"; |
577 Goal "[| w + v < z; #0 <= v |] ==> w < (z::int)"; |
595 by (fast_arith_tac 1); |
578 by (fast_arith_tac 1); |
596 qed "zless_zadd_imp_zless"; |
579 qed "zless_zadd_imp_zless"; |
597 |
580 |
598 (*LOOPS as a simprule! Analogous to Suc_lessD*) |
581 (*LOOPS as a simprule! Analogous to Suc_lessD*) |
599 Goal "w + #1 < z ==> w < z"; |
582 Goal "w + #1 < z ==> w < (z::int)"; |
600 by (fast_arith_tac 1); |
583 by (fast_arith_tac 1); |
601 qed "zless_zadd1_imp_zless"; |
584 qed "zless_zadd1_imp_zless"; |
602 |
585 |
603 Goal "w + #-1 = w - #1"; |
586 Goal "w + #-1 = w - (#1::int)"; |
604 by (Simp_tac 1); |
587 by (Simp_tac 1); |
605 qed "zplus_minus1_conv"; |
588 qed "zplus_minus1_conv"; |
606 |
589 |
607 |
590 |
608 (*** nat ***) |
591 (*** nat ***) |