1632
|
1 |
(* Title: HOL/Integ/Bin.ML
|
|
2 |
Authors: Lawrence C Paulson, Cambridge University Computer Laboratory
|
|
3 |
David Spelt, University of Twente
|
|
4 |
Copyright 1994 University of Cambridge
|
|
5 |
Copyright 1996 University of Twente
|
|
6 |
|
|
7 |
Arithmetic on binary integers.
|
|
8 |
*)
|
|
9 |
|
|
10 |
open Bin;
|
|
11 |
|
|
12 |
(** extra rules for bin_succ, bin_pred, bin_add, bin_mult **)
|
|
13 |
|
|
14 |
qed_goal "norm_Bcons_Plus_0" Bin.thy "norm_Bcons Plus False = Plus"
|
|
15 |
(fn prem => [(Simp_tac 1)]);
|
|
16 |
|
|
17 |
qed_goal "norm_Bcons_Plus_1" Bin.thy "norm_Bcons Plus True = Bcons Plus True"
|
|
18 |
(fn prem => [(Simp_tac 1)]);
|
|
19 |
|
|
20 |
qed_goal "norm_Bcons_Minus_0" Bin.thy "norm_Bcons Minus False = Bcons Minus False"
|
|
21 |
(fn prem => [(Simp_tac 1)]);
|
|
22 |
|
|
23 |
qed_goal "norm_Bcons_Minus_1" Bin.thy "norm_Bcons Minus True = Minus"
|
|
24 |
(fn prem => [(Simp_tac 1)]);
|
|
25 |
|
|
26 |
qed_goal "norm_Bcons_Bcons" Bin.thy "norm_Bcons (Bcons w x) b = Bcons (Bcons w x) b"
|
|
27 |
(fn prem => [(Simp_tac 1)]);
|
|
28 |
|
|
29 |
qed_goal "bin_succ_Bcons1" Bin.thy "bin_succ(Bcons w True) = Bcons (bin_succ w) False"
|
|
30 |
(fn prem => [(Simp_tac 1)]);
|
|
31 |
|
|
32 |
qed_goal "bin_succ_Bcons0" Bin.thy "bin_succ(Bcons w False) = norm_Bcons w True"
|
|
33 |
(fn prem => [(Simp_tac 1)]);
|
|
34 |
|
|
35 |
qed_goal "bin_pred_Bcons1" Bin.thy "bin_pred(Bcons w True) = norm_Bcons w False"
|
|
36 |
(fn prem => [(Simp_tac 1)]);
|
|
37 |
|
|
38 |
qed_goal "bin_pred_Bcons0" Bin.thy "bin_pred(Bcons w False) = Bcons (bin_pred w) True"
|
|
39 |
(fn prem => [(Simp_tac 1)]);
|
|
40 |
|
|
41 |
qed_goal "bin_minus_Bcons1" Bin.thy "bin_minus(Bcons w True) = bin_pred (Bcons(bin_minus w) False)"
|
|
42 |
(fn prem => [(Simp_tac 1)]);
|
|
43 |
|
|
44 |
qed_goal "bin_minus_Bcons0" Bin.thy "bin_minus(Bcons w False) = Bcons (bin_minus w) False"
|
|
45 |
(fn prem => [(Simp_tac 1)]);
|
|
46 |
|
|
47 |
(*** bin_add: binary addition ***)
|
|
48 |
|
|
49 |
qed_goal "bin_add_Bcons_Bcons11" Bin.thy "bin_add (Bcons v True) (Bcons w True) = norm_Bcons (bin_add v (bin_succ w)) False"
|
|
50 |
(fn prem => [(Simp_tac 1)]);
|
|
51 |
|
|
52 |
qed_goal "bin_add_Bcons_Bcons10" Bin.thy "bin_add (Bcons v True) (Bcons w False) = norm_Bcons (bin_add v w) True"
|
|
53 |
(fn prem => [(Simp_tac 1)]);
|
|
54 |
|
|
55 |
(* SHOULD THIS THEOREM BE ADDED TO HOL_SS ? *)
|
|
56 |
val my = prove_goal HOL.thy "(False = (~P)) = P"
|
1894
|
57 |
(fn prem => [(Fast_tac 1)]);
|
1632
|
58 |
|
|
59 |
qed_goal "bin_add_Bcons_Bcons0" Bin.thy "bin_add (Bcons v False) (Bcons w y) = norm_Bcons (bin_add v w) y"
|
|
60 |
(fn prem => [(simp_tac (!simpset addsimps [my]) 1)]);
|
|
61 |
|
|
62 |
qed_goal "bin_add_Bcons_Plus" Bin.thy "bin_add (Bcons v x) Plus = Bcons v x"
|
|
63 |
(fn prems => [(Simp_tac 1)]);
|
|
64 |
|
|
65 |
qed_goal "bin_add_Bcons_Minus" Bin.thy "bin_add (Bcons v x) Minus = bin_pred (Bcons v x)"
|
|
66 |
(fn prems => [(Simp_tac 1)]);
|
|
67 |
|
|
68 |
qed_goal "bin_add_Bcons_Bcons" Bin.thy "bin_add (Bcons v x) (Bcons w y) = norm_Bcons(bin_add v (if x & y then (bin_succ w) else w)) (x~= y)"
|
|
69 |
(fn prems => [(Simp_tac 1)]);
|
|
70 |
|
|
71 |
|
|
72 |
(*** bin_add: binary multiplication ***)
|
|
73 |
|
|
74 |
qed_goal "bin_mult_Bcons1" Bin.thy "bin_mult (Bcons v True) w = bin_add (norm_Bcons (bin_mult v w) False) w"
|
|
75 |
(fn prem => [(Simp_tac 1)]);
|
|
76 |
|
|
77 |
qed_goal "bin_mult_Bcons0" Bin.thy "bin_mult (Bcons v False) w = norm_Bcons (bin_mult v w) False"
|
|
78 |
(fn prem => [(Simp_tac 1)]);
|
|
79 |
|
|
80 |
|
|
81 |
(**** The carry/borrow functions, bin_succ and bin_pred ****)
|
|
82 |
|
|
83 |
(** Lemmas **)
|
|
84 |
|
|
85 |
qed_goal "zadd_assoc_cong" Integ.thy "(z::int) + v = z' + v' ==> z + (v + w) = z' + (v' + w)"
|
|
86 |
(fn prems => [(asm_simp_tac (!simpset addsimps (prems @ [zadd_assoc RS sym])) 1)]);
|
|
87 |
|
|
88 |
qed_goal "zadd_assoc_swap" Integ.thy "(z::int) + (v + w) = v + (z + w)"
|
|
89 |
(fn prems => [(REPEAT (ares_tac [zadd_commute RS zadd_assoc_cong] 1))]);
|
|
90 |
|
|
91 |
|
|
92 |
val my_ss = !simpset setloop (split_tac [expand_if]) ;
|
|
93 |
|
|
94 |
|
|
95 |
(**** integ_of_bin ****)
|
|
96 |
|
|
97 |
|
|
98 |
qed_goal "integ_of_bin_norm_Bcons" Bin.thy "integ_of_bin(norm_Bcons w b) = integ_of_bin(Bcons w b)"
|
|
99 |
(fn prems=>[ (bin.induct_tac "w" 1),
|
|
100 |
(REPEAT(simp_tac (!simpset setloop (split_tac [expand_if])) 1)) ]);
|
|
101 |
|
|
102 |
qed_goal "integ_of_bin_succ" Bin.thy "integ_of_bin(bin_succ w) = $#1 + integ_of_bin w"
|
|
103 |
(fn prems=>[ (rtac bin.induct 1),
|
|
104 |
(REPEAT(asm_simp_tac (!simpset addsimps (integ_of_bin_norm_Bcons::zadd_ac)
|
|
105 |
setloop (split_tac [expand_if])) 1)) ]);
|
|
106 |
|
|
107 |
qed_goal "integ_of_bin_pred" Bin.thy "integ_of_bin(bin_pred w) = $~ ($#1) + integ_of_bin w"
|
|
108 |
(fn prems=>[ (rtac bin.induct 1),
|
|
109 |
(REPEAT(asm_simp_tac (!simpset addsimps (integ_of_bin_norm_Bcons::zadd_ac)
|
|
110 |
setloop (split_tac [expand_if])) 1)) ]);
|
|
111 |
|
|
112 |
qed_goal "integ_of_bin_minus" Bin.thy "integ_of_bin(bin_minus w) = $~ (integ_of_bin w)"
|
|
113 |
(fn prems=>[ (rtac bin.induct 1),
|
|
114 |
(Simp_tac 1),
|
|
115 |
(Simp_tac 1),
|
|
116 |
(asm_simp_tac (!simpset
|
|
117 |
delsimps [pred_Plus,pred_Minus,pred_Bcons]
|
|
118 |
addsimps [integ_of_bin_succ,integ_of_bin_pred,
|
|
119 |
zadd_assoc]
|
|
120 |
setloop (split_tac [expand_if])) 1)]);
|
|
121 |
|
|
122 |
|
|
123 |
val bin_add_simps = [add_Plus,add_Minus,bin_add_Bcons_Plus,bin_add_Bcons_Minus,bin_add_Bcons_Bcons,
|
|
124 |
integ_of_bin_succ, integ_of_bin_pred,
|
|
125 |
integ_of_bin_norm_Bcons];
|
|
126 |
val bin_simps = [iob_Plus,iob_Minus,iob_Bcons];
|
|
127 |
|
|
128 |
goal Bin.thy "! w. integ_of_bin(bin_add v w) = integ_of_bin v + integ_of_bin w";
|
|
129 |
by (bin.induct_tac "v" 1);
|
|
130 |
by (simp_tac (my_ss addsimps bin_add_simps) 1);
|
|
131 |
by (simp_tac (my_ss addsimps bin_add_simps) 1);
|
|
132 |
by (rtac allI 1);
|
|
133 |
by (bin.induct_tac "w" 1);
|
|
134 |
by (asm_simp_tac (my_ss addsimps (bin_add_simps)) 1);
|
|
135 |
by (asm_simp_tac (my_ss addsimps (bin_add_simps @ zadd_ac)) 1);
|
|
136 |
by (cut_inst_tac [("P","bool")] True_or_False 1);
|
|
137 |
by (etac disjE 1);
|
|
138 |
by (asm_simp_tac (my_ss addsimps (bin_add_simps @ zadd_ac)) 1);
|
|
139 |
by (asm_simp_tac (my_ss addsimps (bin_add_simps @ zadd_ac)) 1);
|
|
140 |
val integ_of_bin_add_lemma = result();
|
|
141 |
|
|
142 |
goal Bin.thy "integ_of_bin(bin_add v w) = integ_of_bin v + integ_of_bin w";
|
|
143 |
by (cut_facts_tac [integ_of_bin_add_lemma] 1);
|
1894
|
144 |
by (Fast_tac 1);
|
1632
|
145 |
qed "integ_of_bin_add";
|
|
146 |
|
|
147 |
val bin_mult_simps = [integ_of_bin_minus, integ_of_bin_add,integ_of_bin_norm_Bcons];
|
|
148 |
|
|
149 |
goal Bin.thy "integ_of_bin(bin_mult v w) = integ_of_bin v * integ_of_bin w";
|
|
150 |
by (bin.induct_tac "v" 1);
|
|
151 |
by (simp_tac (my_ss addsimps bin_mult_simps) 1);
|
|
152 |
by (simp_tac (my_ss addsimps bin_mult_simps) 1);
|
|
153 |
by (cut_inst_tac [("P","bool")] True_or_False 1);
|
|
154 |
by (etac disjE 1);
|
|
155 |
by (asm_simp_tac (my_ss addsimps (bin_mult_simps @ [zadd_zmult_distrib])) 2);
|
|
156 |
by (asm_simp_tac (my_ss addsimps (bin_mult_simps @ [zadd_zmult_distrib] @ zadd_ac)) 1);
|
|
157 |
qed "integ_of_bin_mult";
|
|
158 |
|
|
159 |
|
|
160 |
Delsimps [succ_Bcons,pred_Bcons,min_Bcons,add_Bcons,mult_Bcons,
|
|
161 |
iob_Plus,iob_Minus,iob_Bcons,
|
|
162 |
norm_Plus,norm_Minus,norm_Bcons];
|
|
163 |
|
|
164 |
Addsimps [integ_of_bin_add RS sym,
|
|
165 |
integ_of_bin_minus RS sym,
|
|
166 |
integ_of_bin_mult RS sym,
|
|
167 |
bin_succ_Bcons1,bin_succ_Bcons0,
|
|
168 |
bin_pred_Bcons1,bin_pred_Bcons0,
|
|
169 |
bin_minus_Bcons1,bin_minus_Bcons0,
|
|
170 |
bin_add_Bcons_Plus,bin_add_Bcons_Minus,
|
|
171 |
bin_add_Bcons_Bcons0,bin_add_Bcons_Bcons10,bin_add_Bcons_Bcons11,
|
|
172 |
bin_mult_Bcons1,bin_mult_Bcons0,
|
|
173 |
norm_Bcons_Plus_0,norm_Bcons_Plus_1,
|
|
174 |
norm_Bcons_Minus_0,norm_Bcons_Minus_1,
|
|
175 |
norm_Bcons_Bcons];
|
|
176 |
|
|
177 |
(*** Examples of performing binary arithmetic by simplification ***)
|
|
178 |
|
|
179 |
goal Bin.thy "#13 + #19 = #32";
|
|
180 |
by (Simp_tac 1);
|
|
181 |
result();
|
|
182 |
|
|
183 |
goal Bin.thy "#1234 + #5678 = #6912";
|
|
184 |
by (Simp_tac 1);
|
|
185 |
result();
|
|
186 |
|
|
187 |
goal Bin.thy "#1359 + #~2468 = #~1109";
|
|
188 |
by (Simp_tac 1);
|
|
189 |
result();
|
|
190 |
|
|
191 |
goal Bin.thy "#93746 + #~46375 = #47371";
|
|
192 |
by (Simp_tac 1);
|
|
193 |
result();
|
|
194 |
|
|
195 |
goal Bin.thy "$~ #65745 = #~65745";
|
|
196 |
by (Simp_tac 1);
|
|
197 |
result();
|
|
198 |
|
|
199 |
goal Bin.thy "$~ #~54321 = #54321";
|
|
200 |
by (Simp_tac 1);
|
|
201 |
result();
|
|
202 |
|
|
203 |
goal Bin.thy "#13 * #19 = #247";
|
|
204 |
by (Simp_tac 1);
|
|
205 |
result();
|
|
206 |
|
|
207 |
goal Bin.thy "#~84 * #51 = #~4284";
|
|
208 |
by (Simp_tac 1);
|
|
209 |
result();
|
|
210 |
|
|
211 |
goal Bin.thy "#255 * #255 = #65025";
|
|
212 |
by (Simp_tac 1);
|
|
213 |
result();
|
|
214 |
|
|
215 |
goal Bin.thy "#1359 * #~2468 = #~3354012";
|
|
216 |
by (Simp_tac 1);
|
|
217 |
result();
|