author | ballarin |
Wed, 30 Apr 2003 10:01:35 +0200 | |
changeset 13936 | d3671b878828 |
parent 13491 | ddf6ae639f21 |
child 14264 | 3d0c6238162a |
permissions | -rw-r--r-- |
2224
4fc4b465be5b
New material from Norbert Voelker for efficient binary comparisons
paulson
parents:
1894
diff
changeset
|
1 |
(* Title: HOL/Integ/Bin.ML |
7074
e0730ffaafcc
zadd_ac and zmult_ac are no longer included by default
paulson
parents:
7033
diff
changeset
|
2 |
ID: $Id$ |
2224
4fc4b465be5b
New material from Norbert Voelker for efficient binary comparisons
paulson
parents:
1894
diff
changeset
|
3 |
Authors: Lawrence C Paulson, Cambridge University Computer Laboratory |
4fc4b465be5b
New material from Norbert Voelker for efficient binary comparisons
paulson
parents:
1894
diff
changeset
|
4 |
David Spelt, University of Twente |
6060 | 5 |
Tobias Nipkow, Technical University Munich |
1632 | 6 |
Copyright 1994 University of Cambridge |
6060 | 7 |
Copyright 1996 University of Twente |
8 |
Copyright 1999 TU Munich |
|
1632 | 9 |
|
7708 | 10 |
Arithmetic on binary integers. |
1632 | 11 |
*) |
12 |
||
13 |
(** extra rules for bin_succ, bin_pred, bin_add, bin_mult **) |
|
14 |
||
13491 | 15 |
Goal "NCons bin.Pls False = bin.Pls"; |
7008
6def5ce146e2
qed_goal -> Goal; new theorems nat_le_0, nat_le_eq_zle and zdiff_int
paulson
parents:
6997
diff
changeset
|
16 |
by (Simp_tac 1); |
6def5ce146e2
qed_goal -> Goal; new theorems nat_le_0, nat_le_eq_zle and zdiff_int
paulson
parents:
6997
diff
changeset
|
17 |
qed "NCons_Pls_0"; |
1632 | 18 |
|
13491 | 19 |
Goal "NCons bin.Pls True = bin.Pls BIT True"; |
7008
6def5ce146e2
qed_goal -> Goal; new theorems nat_le_0, nat_le_eq_zle and zdiff_int
paulson
parents:
6997
diff
changeset
|
20 |
by (Simp_tac 1); |
6def5ce146e2
qed_goal -> Goal; new theorems nat_le_0, nat_le_eq_zle and zdiff_int
paulson
parents:
6997
diff
changeset
|
21 |
qed "NCons_Pls_1"; |
1632 | 22 |
|
13491 | 23 |
Goal "NCons bin.Min False = bin.Min BIT False"; |
7008
6def5ce146e2
qed_goal -> Goal; new theorems nat_le_0, nat_le_eq_zle and zdiff_int
paulson
parents:
6997
diff
changeset
|
24 |
by (Simp_tac 1); |
6def5ce146e2
qed_goal -> Goal; new theorems nat_le_0, nat_le_eq_zle and zdiff_int
paulson
parents:
6997
diff
changeset
|
25 |
qed "NCons_Min_0"; |
1632 | 26 |
|
13491 | 27 |
Goal "NCons bin.Min True = bin.Min"; |
7008
6def5ce146e2
qed_goal -> Goal; new theorems nat_le_0, nat_le_eq_zle and zdiff_int
paulson
parents:
6997
diff
changeset
|
28 |
by (Simp_tac 1); |
6def5ce146e2
qed_goal -> Goal; new theorems nat_le_0, nat_le_eq_zle and zdiff_int
paulson
parents:
6997
diff
changeset
|
29 |
qed "NCons_Min_1"; |
1632 | 30 |
|
7008
6def5ce146e2
qed_goal -> Goal; new theorems nat_le_0, nat_le_eq_zle and zdiff_int
paulson
parents:
6997
diff
changeset
|
31 |
Goal "bin_succ(w BIT True) = (bin_succ w) BIT False"; |
6def5ce146e2
qed_goal -> Goal; new theorems nat_le_0, nat_le_eq_zle and zdiff_int
paulson
parents:
6997
diff
changeset
|
32 |
by (Simp_tac 1); |
6def5ce146e2
qed_goal -> Goal; new theorems nat_le_0, nat_le_eq_zle and zdiff_int
paulson
parents:
6997
diff
changeset
|
33 |
qed "bin_succ_1"; |
1632 | 34 |
|
7008
6def5ce146e2
qed_goal -> Goal; new theorems nat_le_0, nat_le_eq_zle and zdiff_int
paulson
parents:
6997
diff
changeset
|
35 |
Goal "bin_succ(w BIT False) = NCons w True"; |
6def5ce146e2
qed_goal -> Goal; new theorems nat_le_0, nat_le_eq_zle and zdiff_int
paulson
parents:
6997
diff
changeset
|
36 |
by (Simp_tac 1); |
6def5ce146e2
qed_goal -> Goal; new theorems nat_le_0, nat_le_eq_zle and zdiff_int
paulson
parents:
6997
diff
changeset
|
37 |
qed "bin_succ_0"; |
1632 | 38 |
|
7008
6def5ce146e2
qed_goal -> Goal; new theorems nat_le_0, nat_le_eq_zle and zdiff_int
paulson
parents:
6997
diff
changeset
|
39 |
Goal "bin_pred(w BIT True) = NCons w False"; |
6def5ce146e2
qed_goal -> Goal; new theorems nat_le_0, nat_le_eq_zle and zdiff_int
paulson
parents:
6997
diff
changeset
|
40 |
by (Simp_tac 1); |
6def5ce146e2
qed_goal -> Goal; new theorems nat_le_0, nat_le_eq_zle and zdiff_int
paulson
parents:
6997
diff
changeset
|
41 |
qed "bin_pred_1"; |
1632 | 42 |
|
7008
6def5ce146e2
qed_goal -> Goal; new theorems nat_le_0, nat_le_eq_zle and zdiff_int
paulson
parents:
6997
diff
changeset
|
43 |
Goal "bin_pred(w BIT False) = (bin_pred w) BIT True"; |
6def5ce146e2
qed_goal -> Goal; new theorems nat_le_0, nat_le_eq_zle and zdiff_int
paulson
parents:
6997
diff
changeset
|
44 |
by (Simp_tac 1); |
6def5ce146e2
qed_goal -> Goal; new theorems nat_le_0, nat_le_eq_zle and zdiff_int
paulson
parents:
6997
diff
changeset
|
45 |
qed "bin_pred_0"; |
1632 | 46 |
|
7008
6def5ce146e2
qed_goal -> Goal; new theorems nat_le_0, nat_le_eq_zle and zdiff_int
paulson
parents:
6997
diff
changeset
|
47 |
Goal "bin_minus(w BIT True) = bin_pred (NCons (bin_minus w) False)"; |
6def5ce146e2
qed_goal -> Goal; new theorems nat_le_0, nat_le_eq_zle and zdiff_int
paulson
parents:
6997
diff
changeset
|
48 |
by (Simp_tac 1); |
6def5ce146e2
qed_goal -> Goal; new theorems nat_le_0, nat_le_eq_zle and zdiff_int
paulson
parents:
6997
diff
changeset
|
49 |
qed "bin_minus_1"; |
1632 | 50 |
|
7008
6def5ce146e2
qed_goal -> Goal; new theorems nat_le_0, nat_le_eq_zle and zdiff_int
paulson
parents:
6997
diff
changeset
|
51 |
Goal "bin_minus(w BIT False) = (bin_minus w) BIT False"; |
6def5ce146e2
qed_goal -> Goal; new theorems nat_le_0, nat_le_eq_zle and zdiff_int
paulson
parents:
6997
diff
changeset
|
52 |
by (Simp_tac 1); |
6def5ce146e2
qed_goal -> Goal; new theorems nat_le_0, nat_le_eq_zle and zdiff_int
paulson
parents:
6997
diff
changeset
|
53 |
qed "bin_minus_0"; |
1632 | 54 |
|
5491 | 55 |
|
1632 | 56 |
(*** bin_add: binary addition ***) |
57 |
||
7008
6def5ce146e2
qed_goal -> Goal; new theorems nat_le_0, nat_le_eq_zle and zdiff_int
paulson
parents:
6997
diff
changeset
|
58 |
Goal "bin_add (v BIT True) (w BIT True) = \ |
6def5ce146e2
qed_goal -> Goal; new theorems nat_le_0, nat_le_eq_zle and zdiff_int
paulson
parents:
6997
diff
changeset
|
59 |
\ NCons (bin_add v (bin_succ w)) False"; |
6def5ce146e2
qed_goal -> Goal; new theorems nat_le_0, nat_le_eq_zle and zdiff_int
paulson
parents:
6997
diff
changeset
|
60 |
by (Simp_tac 1); |
6def5ce146e2
qed_goal -> Goal; new theorems nat_le_0, nat_le_eq_zle and zdiff_int
paulson
parents:
6997
diff
changeset
|
61 |
qed "bin_add_BIT_11"; |
1632 | 62 |
|
7008
6def5ce146e2
qed_goal -> Goal; new theorems nat_le_0, nat_le_eq_zle and zdiff_int
paulson
parents:
6997
diff
changeset
|
63 |
Goal "bin_add (v BIT True) (w BIT False) = NCons (bin_add v w) True"; |
6def5ce146e2
qed_goal -> Goal; new theorems nat_le_0, nat_le_eq_zle and zdiff_int
paulson
parents:
6997
diff
changeset
|
64 |
by (Simp_tac 1); |
6def5ce146e2
qed_goal -> Goal; new theorems nat_le_0, nat_le_eq_zle and zdiff_int
paulson
parents:
6997
diff
changeset
|
65 |
qed "bin_add_BIT_10"; |
1632 | 66 |
|
7008
6def5ce146e2
qed_goal -> Goal; new theorems nat_le_0, nat_le_eq_zle and zdiff_int
paulson
parents:
6997
diff
changeset
|
67 |
Goal "bin_add (v BIT False) (w BIT y) = NCons (bin_add v w) y"; |
6def5ce146e2
qed_goal -> Goal; new theorems nat_le_0, nat_le_eq_zle and zdiff_int
paulson
parents:
6997
diff
changeset
|
68 |
by Auto_tac; |
6def5ce146e2
qed_goal -> Goal; new theorems nat_le_0, nat_le_eq_zle and zdiff_int
paulson
parents:
6997
diff
changeset
|
69 |
qed "bin_add_BIT_0"; |
1632 | 70 |
|
13491 | 71 |
Goal "bin_add w bin.Pls = w"; |
5551 | 72 |
by (induct_tac "w" 1); |
73 |
by Auto_tac; |
|
74 |
qed "bin_add_Pls_right"; |
|
1632 | 75 |
|
13491 | 76 |
Goal "bin_add w bin.Min = bin_pred w"; |
7517
bad2f36810e1
generalized the theorem bin_add_BIT_Min to bin_add_Min_right
paulson
parents:
7074
diff
changeset
|
77 |
by (induct_tac "w" 1); |
bad2f36810e1
generalized the theorem bin_add_BIT_Min to bin_add_Min_right
paulson
parents:
7074
diff
changeset
|
78 |
by Auto_tac; |
bad2f36810e1
generalized the theorem bin_add_BIT_Min to bin_add_Min_right
paulson
parents:
7074
diff
changeset
|
79 |
qed "bin_add_Min_right"; |
1632 | 80 |
|
7008
6def5ce146e2
qed_goal -> Goal; new theorems nat_le_0, nat_le_eq_zle and zdiff_int
paulson
parents:
6997
diff
changeset
|
81 |
Goal "bin_add (v BIT x) (w BIT y) = \ |
6def5ce146e2
qed_goal -> Goal; new theorems nat_le_0, nat_le_eq_zle and zdiff_int
paulson
parents:
6997
diff
changeset
|
82 |
\ NCons(bin_add v (if x & y then (bin_succ w) else w)) (x~= y)"; |
6def5ce146e2
qed_goal -> Goal; new theorems nat_le_0, nat_le_eq_zle and zdiff_int
paulson
parents:
6997
diff
changeset
|
83 |
by (Simp_tac 1); |
6def5ce146e2
qed_goal -> Goal; new theorems nat_le_0, nat_le_eq_zle and zdiff_int
paulson
parents:
6997
diff
changeset
|
84 |
qed "bin_add_BIT_BIT"; |
1632 | 85 |
|
86 |
||
6036 | 87 |
(*** bin_mult: binary multiplication ***) |
1632 | 88 |
|
7008
6def5ce146e2
qed_goal -> Goal; new theorems nat_le_0, nat_le_eq_zle and zdiff_int
paulson
parents:
6997
diff
changeset
|
89 |
Goal "bin_mult (v BIT True) w = bin_add (NCons (bin_mult v w) False) w"; |
6def5ce146e2
qed_goal -> Goal; new theorems nat_le_0, nat_le_eq_zle and zdiff_int
paulson
parents:
6997
diff
changeset
|
90 |
by (Simp_tac 1); |
6def5ce146e2
qed_goal -> Goal; new theorems nat_le_0, nat_le_eq_zle and zdiff_int
paulson
parents:
6997
diff
changeset
|
91 |
qed "bin_mult_1"; |
1632 | 92 |
|
7008
6def5ce146e2
qed_goal -> Goal; new theorems nat_le_0, nat_le_eq_zle and zdiff_int
paulson
parents:
6997
diff
changeset
|
93 |
Goal "bin_mult (v BIT False) w = NCons (bin_mult v w) False"; |
6def5ce146e2
qed_goal -> Goal; new theorems nat_le_0, nat_le_eq_zle and zdiff_int
paulson
parents:
6997
diff
changeset
|
94 |
by (Simp_tac 1); |
6def5ce146e2
qed_goal -> Goal; new theorems nat_le_0, nat_le_eq_zle and zdiff_int
paulson
parents:
6997
diff
changeset
|
95 |
qed "bin_mult_0"; |
1632 | 96 |
|
97 |
||
98 |
(**** The carry/borrow functions, bin_succ and bin_pred ****) |
|
99 |
||
100 |
||
11868
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
101 |
(** number_of **) |
1632 | 102 |
|
7008
6def5ce146e2
qed_goal -> Goal; new theorems nat_le_0, nat_le_eq_zle and zdiff_int
paulson
parents:
6997
diff
changeset
|
103 |
Goal "number_of(NCons w b) = (number_of(w BIT b)::int)"; |
6def5ce146e2
qed_goal -> Goal; new theorems nat_le_0, nat_le_eq_zle and zdiff_int
paulson
parents:
6997
diff
changeset
|
104 |
by (induct_tac "w" 1); |
6def5ce146e2
qed_goal -> Goal; new theorems nat_le_0, nat_le_eq_zle and zdiff_int
paulson
parents:
6997
diff
changeset
|
105 |
by (ALLGOALS Asm_simp_tac); |
6def5ce146e2
qed_goal -> Goal; new theorems nat_le_0, nat_le_eq_zle and zdiff_int
paulson
parents:
6997
diff
changeset
|
106 |
qed "number_of_NCons"; |
1632 | 107 |
|
6910 | 108 |
Addsimps [number_of_NCons]; |
1632 | 109 |
|
11868
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
110 |
Goal "number_of(bin_succ w) = (1 + number_of w :: int)"; |
7008
6def5ce146e2
qed_goal -> Goal; new theorems nat_le_0, nat_le_eq_zle and zdiff_int
paulson
parents:
6997
diff
changeset
|
111 |
by (induct_tac "w" 1); |
6def5ce146e2
qed_goal -> Goal; new theorems nat_le_0, nat_le_eq_zle and zdiff_int
paulson
parents:
6997
diff
changeset
|
112 |
by (ALLGOALS (asm_simp_tac (simpset() addsimps zadd_ac))); |
6def5ce146e2
qed_goal -> Goal; new theorems nat_le_0, nat_le_eq_zle and zdiff_int
paulson
parents:
6997
diff
changeset
|
113 |
qed "number_of_succ"; |
5491 | 114 |
|
11868
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
115 |
Goal "number_of(bin_pred w) = (- 1 + number_of w :: int)"; |
7008
6def5ce146e2
qed_goal -> Goal; new theorems nat_le_0, nat_le_eq_zle and zdiff_int
paulson
parents:
6997
diff
changeset
|
116 |
by (induct_tac "w" 1); |
6def5ce146e2
qed_goal -> Goal; new theorems nat_le_0, nat_le_eq_zle and zdiff_int
paulson
parents:
6997
diff
changeset
|
117 |
by (ALLGOALS (asm_simp_tac (simpset() addsimps zadd_ac))); |
6def5ce146e2
qed_goal -> Goal; new theorems nat_le_0, nat_le_eq_zle and zdiff_int
paulson
parents:
6997
diff
changeset
|
118 |
qed "number_of_pred"; |
1632 | 119 |
|
6910 | 120 |
Goal "number_of(bin_minus w) = (- (number_of w)::int)"; |
121 |
by (induct_tac "w" 1); |
|
5491 | 122 |
by (Simp_tac 1); |
123 |
by (Simp_tac 1); |
|
124 |
by (asm_simp_tac (simpset() |
|
5551 | 125 |
delsimps [bin_pred_Pls, bin_pred_Min, bin_pred_BIT] |
6910 | 126 |
addsimps [number_of_succ,number_of_pred, |
5491 | 127 |
zadd_assoc]) 1); |
6910 | 128 |
qed "number_of_minus"; |
1632 | 129 |
|
6036 | 130 |
(*This proof is complicated by the mutual recursion*) |
6910 | 131 |
Goal "! w. number_of(bin_add v w) = (number_of v + number_of w::int)"; |
11868
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
132 |
by (induct_tac "v" 1); |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
133 |
by (Simp_tac 1); |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
134 |
by (simp_tac (simpset() addsimps [number_of_pred]) 1); |
1632 | 135 |
by (rtac allI 1); |
5184 | 136 |
by (induct_tac "w" 1); |
11868
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
137 |
by (ALLGOALS (asm_simp_tac (simpset() addsimps |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
138 |
[bin_add_BIT_BIT, number_of_succ, number_of_pred] @ zadd_ac))); |
6910 | 139 |
qed_spec_mp "number_of_add"; |
1632 | 140 |
|
5779
5c74f003a68e
Explicit (and improved) simprules for binary arithmetic.
paulson
parents:
5747
diff
changeset
|
141 |
|
5c74f003a68e
Explicit (and improved) simprules for binary arithmetic.
paulson
parents:
5747
diff
changeset
|
142 |
(*Subtraction*) |
5c74f003a68e
Explicit (and improved) simprules for binary arithmetic.
paulson
parents:
5747
diff
changeset
|
143 |
Goalw [zdiff_def] |
6910 | 144 |
"number_of v - number_of w = (number_of(bin_add v (bin_minus w))::int)"; |
145 |
by (simp_tac (simpset() addsimps [number_of_add, number_of_minus]) 1); |
|
146 |
qed "diff_number_of_eq"; |
|
5779
5c74f003a68e
Explicit (and improved) simprules for binary arithmetic.
paulson
parents:
5747
diff
changeset
|
147 |
|
11868
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
148 |
bind_thms ("bin_mult_simps", |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
149 |
[int_Suc0_eq_1, zmult_zminus, number_of_minus, number_of_add]); |
1632 | 150 |
|
6910 | 151 |
Goal "number_of(bin_mult v w) = (number_of v * number_of w::int)"; |
5184 | 152 |
by (induct_tac "v" 1); |
4686 | 153 |
by (simp_tac (simpset() addsimps bin_mult_simps) 1); |
154 |
by (simp_tac (simpset() addsimps bin_mult_simps) 1); |
|
5491 | 155 |
by (asm_simp_tac |
5540 | 156 |
(simpset() addsimps bin_mult_simps @ [zadd_zmult_distrib] @ zadd_ac) 1); |
6910 | 157 |
qed "number_of_mult"; |
5491 | 158 |
|
1632 | 159 |
|
6941 | 160 |
(*The correctness of shifting. But it doesn't seem to give a measurable |
161 |
speed-up.*) |
|
11704
3c50a2cd6f00
* sane numerals (stage 2): plain "num" syntax (removed "#");
wenzelm
parents:
11701
diff
changeset
|
162 |
Goal "(2::int) * number_of w = number_of (w BIT False)"; |
6941 | 163 |
by (induct_tac "w" 1); |
164 |
by (ALLGOALS (asm_simp_tac |
|
165 |
(simpset() addsimps bin_mult_simps @ [zadd_zmult_distrib] @ zadd_ac))); |
|
166 |
qed "double_number_of_BIT"; |
|
167 |
||
168 |
||
11868
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
169 |
(** Converting numerals 0 and 1 to their abstract versions **) |
5491 | 170 |
|
11868
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
171 |
Goal "Numeral0 = (0::int)"; |
5491 | 172 |
by (Simp_tac 1); |
11868
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
173 |
qed "int_numeral_0_eq_0"; |
5582
a356fb49e69e
many renamings and changes. Simproc for cancelling common terms in relations
paulson
parents:
5562
diff
changeset
|
174 |
|
11868
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
175 |
Goal "Numeral1 = (1::int)"; |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
176 |
by (simp_tac (simpset() addsimps [int_1, int_Suc0_eq_1]) 1); |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
177 |
qed "int_numeral_1_eq_1"; |
5582
a356fb49e69e
many renamings and changes. Simproc for cancelling common terms in relations
paulson
parents:
5562
diff
changeset
|
178 |
|
6917 | 179 |
|
180 |
(** Special simplification, for constants only **) |
|
6838
941c4f70db91
rewrite rules to distribute CONSTANT multiplication over sum and difference;
paulson
parents:
6716
diff
changeset
|
181 |
|
7074
e0730ffaafcc
zadd_ac and zmult_ac are no longer included by default
paulson
parents:
7033
diff
changeset
|
182 |
(*Distributive laws for literals*) |
6917 | 183 |
Addsimps (map (inst "w" "number_of ?v") |
6838
941c4f70db91
rewrite rules to distribute CONSTANT multiplication over sum and difference;
paulson
parents:
6716
diff
changeset
|
184 |
[zadd_zmult_distrib, zadd_zmult_distrib2, |
941c4f70db91
rewrite rules to distribute CONSTANT multiplication over sum and difference;
paulson
parents:
6716
diff
changeset
|
185 |
zdiff_zmult_distrib, zdiff_zmult_distrib2]); |
941c4f70db91
rewrite rules to distribute CONSTANT multiplication over sum and difference;
paulson
parents:
6716
diff
changeset
|
186 |
|
6917 | 187 |
Addsimps (map (inst "x" "number_of ?v") |
188 |
[zless_zminus, zle_zminus, equation_zminus]); |
|
189 |
Addsimps (map (inst "y" "number_of ?v") |
|
190 |
[zminus_zless, zminus_zle, zminus_equation]); |
|
191 |
||
12018
ec054019c910
Numerals and simprocs for types real and hypreal. The abstract
paulson
parents:
11868
diff
changeset
|
192 |
(*Equations and inequations involving 1*) |
ec054019c910
Numerals and simprocs for types real and hypreal. The abstract
paulson
parents:
11868
diff
changeset
|
193 |
Addsimps (map (simplify (simpset()) o inst "x" "1") |
ec054019c910
Numerals and simprocs for types real and hypreal. The abstract
paulson
parents:
11868
diff
changeset
|
194 |
[zless_zminus, zle_zminus, equation_zminus]); |
ec054019c910
Numerals and simprocs for types real and hypreal. The abstract
paulson
parents:
11868
diff
changeset
|
195 |
Addsimps (map (simplify (simpset()) o inst "y" "1") |
ec054019c910
Numerals and simprocs for types real and hypreal. The abstract
paulson
parents:
11868
diff
changeset
|
196 |
[zminus_zless, zminus_zle, zminus_equation]); |
ec054019c910
Numerals and simprocs for types real and hypreal. The abstract
paulson
parents:
11868
diff
changeset
|
197 |
|
7074
e0730ffaafcc
zadd_ac and zmult_ac are no longer included by default
paulson
parents:
7033
diff
changeset
|
198 |
(*Moving negation out of products*) |
e0730ffaafcc
zadd_ac and zmult_ac are no longer included by default
paulson
parents:
7033
diff
changeset
|
199 |
Addsimps [zmult_zminus, zmult_zminus_right]; |
6917 | 200 |
|
9633
a71a83253997
better rules for cancellation of common factors across comparisons
paulson
parents:
9436
diff
changeset
|
201 |
(*Cancellation of constant factors in comparisons (< and <=) *) |
a71a83253997
better rules for cancellation of common factors across comparisons
paulson
parents:
9436
diff
changeset
|
202 |
Addsimps (map (inst "k" "number_of ?v") |
a71a83253997
better rules for cancellation of common factors across comparisons
paulson
parents:
9436
diff
changeset
|
203 |
[zmult_zless_cancel1, zmult_zless_cancel2, |
a71a83253997
better rules for cancellation of common factors across comparisons
paulson
parents:
9436
diff
changeset
|
204 |
zmult_zle_cancel1, zmult_zle_cancel2]); |
a71a83253997
better rules for cancellation of common factors across comparisons
paulson
parents:
9436
diff
changeset
|
205 |
|
a71a83253997
better rules for cancellation of common factors across comparisons
paulson
parents:
9436
diff
changeset
|
206 |
|
6838
941c4f70db91
rewrite rules to distribute CONSTANT multiplication over sum and difference;
paulson
parents:
6716
diff
changeset
|
207 |
(** Special-case simplification for small constants **) |
941c4f70db91
rewrite rules to distribute CONSTANT multiplication over sum and difference;
paulson
parents:
6716
diff
changeset
|
208 |
|
11704
3c50a2cd6f00
* sane numerals (stage 2): plain "num" syntax (removed "#");
wenzelm
parents:
11701
diff
changeset
|
209 |
Goal "-1 * z = -(z::int)"; |
11868
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
210 |
by (simp_tac (simpset() addsimps zcompare_rls@[int_Suc0_eq_1, zmult_zminus]) 1); |
6917 | 211 |
qed "zmult_minus1"; |
212 |
||
11704
3c50a2cd6f00
* sane numerals (stage 2): plain "num" syntax (removed "#");
wenzelm
parents:
11701
diff
changeset
|
213 |
Goal "z * -1 = -(z::int)"; |
11868
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
214 |
by (stac zmult_commute 1 THEN rtac zmult_minus1 1); |
6917 | 215 |
qed "zmult_minus1_right"; |
216 |
||
11868
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
217 |
Addsimps [zmult_minus1, zmult_minus1_right]; |
6917 | 218 |
|
8785 | 219 |
(*Negation of a coefficient*) |
220 |
Goal "- (number_of w) * z = number_of(bin_minus w) * (z::int)"; |
|
9436
62bb04ab4b01
rearranged setup of arithmetic procedures, avoiding global reference values;
wenzelm
parents:
9214
diff
changeset
|
221 |
by (simp_tac (simpset() addsimps [number_of_minus, zmult_zminus]) 1); |
8785 | 222 |
qed "zminus_number_of_zmult"; |
223 |
Addsimps [zminus_number_of_zmult]; |
|
224 |
||
11868
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
225 |
(*Integer unary minus for the abstract constant 1. Cannot be inserted |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
226 |
as a simprule until later: it is number_of_Min re-oriented!*) |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
227 |
Goal "- 1 = (-1::int)"; |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
228 |
by (Simp_tac 1); |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
229 |
qed "zminus_1_eq_m1"; |
5510
ad120f7c52ad
improved (but still flawed) treatment of binary arithmetic
paulson
parents:
5491
diff
changeset
|
230 |
|
11868
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
231 |
Goal "(0 < nat z) = (0 < z)"; |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
232 |
by (cut_inst_tac [("w","0")] zless_nat_conj 1); |
9945 | 233 |
by Auto_tac; |
234 |
qed "zero_less_nat_eq"; |
|
235 |
Addsimps [zero_less_nat_eq]; |
|
5747 | 236 |
|
237 |
||
5491 | 238 |
(** Simplification rules for comparison of binary numbers (Norbert Voelker) **) |
239 |
||
240 |
(** Equals (=) **) |
|
1632 | 241 |
|
5491 | 242 |
Goalw [iszero_def] |
6997 | 243 |
"((number_of x::int) = number_of y) = \ |
244 |
\ iszero (number_of (bin_add x (bin_minus y)))"; |
|
11868
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
245 |
by (simp_tac (simpset() |
10701 | 246 |
addsimps zcompare_rls @ [number_of_add, number_of_minus]) 1); |
6910 | 247 |
qed "eq_number_of_eq"; |
5491 | 248 |
|
13491 | 249 |
Goalw [iszero_def] "iszero ((number_of bin.Pls)::int)"; |
5491 | 250 |
by (Simp_tac 1); |
6910 | 251 |
qed "iszero_number_of_Pls"; |
5491 | 252 |
|
13491 | 253 |
Goalw [iszero_def] "~ iszero ((number_of bin.Min)::int)"; |
5491 | 254 |
by (Simp_tac 1); |
6910 | 255 |
qed "nonzero_number_of_Min"; |
5491 | 256 |
|
257 |
Goalw [iszero_def] |
|
6910 | 258 |
"iszero (number_of (w BIT x)) = (~x & iszero (number_of w::int))"; |
259 |
by (int_case_tac "number_of w" 1); |
|
11868
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
260 |
by (ALLGOALS |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
261 |
(asm_simp_tac |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
262 |
(simpset() addsimps zcompare_rls @ |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
263 |
[zero_reorient, zminus_zadd_distrib RS sym, |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
264 |
int_Suc0_eq_1 RS sym, zadd_int]))); |
6910 | 265 |
qed "iszero_number_of_BIT"; |
5491 | 266 |
|
6910 | 267 |
Goal "iszero (number_of (w BIT False)) = iszero (number_of w::int)"; |
268 |
by (simp_tac (HOL_ss addsimps [iszero_number_of_BIT]) 1); |
|
269 |
qed "iszero_number_of_0"; |
|
5779
5c74f003a68e
Explicit (and improved) simprules for binary arithmetic.
paulson
parents:
5747
diff
changeset
|
270 |
|
6910 | 271 |
Goal "~ iszero (number_of (w BIT True)::int)"; |
272 |
by (simp_tac (HOL_ss addsimps [iszero_number_of_BIT]) 1); |
|
273 |
qed "iszero_number_of_1"; |
|
5779
5c74f003a68e
Explicit (and improved) simprules for binary arithmetic.
paulson
parents:
5747
diff
changeset
|
274 |
|
5c74f003a68e
Explicit (and improved) simprules for binary arithmetic.
paulson
parents:
5747
diff
changeset
|
275 |
|
5491 | 276 |
|
277 |
(** Less-than (<) **) |
|
278 |
||
279 |
Goalw [zless_def,zdiff_def] |
|
11655 | 280 |
"((number_of x::int) < number_of y) \ |
6910 | 281 |
\ = neg (number_of (bin_add x (bin_minus y)))"; |
5491 | 282 |
by (simp_tac (simpset() addsimps bin_mult_simps) 1); |
6910 | 283 |
qed "less_number_of_eq_neg"; |
5491 | 284 |
|
11868
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
285 |
(*But if Numeral0 is rewritten to 0 then this rule can't be applied: |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
286 |
Numeral0 IS (number_of Pls) *) |
13491 | 287 |
Goal "~ neg (number_of bin.Pls)"; |
11868
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
288 |
by (simp_tac (simpset() addsimps [neg_eq_less_0]) 1); |
6910 | 289 |
qed "not_neg_number_of_Pls"; |
5491 | 290 |
|
13491 | 291 |
Goal "neg (number_of bin.Min)"; |
11868
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
292 |
by (simp_tac (simpset() addsimps [neg_eq_less_0, int_0_less_1]) 1); |
6910 | 293 |
qed "neg_number_of_Min"; |
5491 | 294 |
|
6910 | 295 |
Goal "neg (number_of (w BIT x)) = neg (number_of w)"; |
5491 | 296 |
by (Asm_simp_tac 1); |
6910 | 297 |
by (int_case_tac "number_of w" 1); |
5491 | 298 |
by (ALLGOALS (asm_simp_tac |
11868
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
299 |
(simpset() addsimps [int_Suc0_eq_1 RS sym, zadd_int, |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
300 |
neg_eq_less_0, symmetric zdiff_def] @ zcompare_rls))); |
6910 | 301 |
qed "neg_number_of_BIT"; |
5491 | 302 |
|
303 |
||
304 |
(** Less-than-or-equals (<=) **) |
|
305 |
||
7033 | 306 |
Goal "(number_of x <= (number_of y::int)) = \ |
307 |
\ (~ number_of y < (number_of x::int))"; |
|
308 |
by (rtac (linorder_not_less RS sym) 1); |
|
6910 | 309 |
qed "le_number_of_eq_not_less"; |
5491 | 310 |
|
9214 | 311 |
(** Absolute value (abs) **) |
312 |
||
313 |
Goalw [zabs_def] |
|
314 |
"abs(number_of x::int) = \ |
|
315 |
\ (if number_of x < (0::int) then -number_of x else number_of x)"; |
|
12486 | 316 |
by (rtac refl 1); |
11868
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
317 |
qed "zabs_number_of"; |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
318 |
|
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
319 |
(*0 and 1 require special rewrites because they aren't numerals*) |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
320 |
Goal "abs (0::int) = 0"; |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
321 |
by (simp_tac (simpset() addsimps [zabs_def]) 1); |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
322 |
qed "zabs_0"; |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
323 |
|
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
324 |
Goal "abs (1::int) = 1"; |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
325 |
by (simp_tac (simpset() delsimps [int_0, int_1] |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
326 |
addsimps [int_0 RS sym, int_1 RS sym, zabs_def]) 1); |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
327 |
qed "zabs_1"; |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
328 |
|
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
329 |
(*Re-orientation of the equation nnn=x*) |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
330 |
Goal "(number_of w = x) = (x = number_of w)"; |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
331 |
by Auto_tac; |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
332 |
qed "number_of_reorient"; |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
333 |
|
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
334 |
|
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
335 |
structure Bin_Simprocs = |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
336 |
struct |
13480
bb72bd43c6c3
use Tactic.prove instead of prove_goalw_cterm in internal proofs!
wenzelm
parents:
13462
diff
changeset
|
337 |
fun prove_conv tacs sg (hyps: thm list) xs (t, u) = |
11868
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
338 |
if t aconv u then None |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
339 |
else |
13480
bb72bd43c6c3
use Tactic.prove instead of prove_goalw_cterm in internal proofs!
wenzelm
parents:
13462
diff
changeset
|
340 |
let val eq = HOLogic.mk_Trueprop (HOLogic.mk_eq (t, u)) |
bb72bd43c6c3
use Tactic.prove instead of prove_goalw_cterm in internal proofs!
wenzelm
parents:
13462
diff
changeset
|
341 |
in Some (Tactic.prove sg xs [] eq (K (EVERY tacs))) end |
11868
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
342 |
|
13480
bb72bd43c6c3
use Tactic.prove instead of prove_goalw_cterm in internal proofs!
wenzelm
parents:
13462
diff
changeset
|
343 |
fun prove_conv_nohyps tacs sg = prove_conv tacs sg []; |
bb72bd43c6c3
use Tactic.prove instead of prove_goalw_cterm in internal proofs!
wenzelm
parents:
13462
diff
changeset
|
344 |
fun prove_conv_nohyps_novars tacs sg = prove_conv tacs sg [] []; |
11868
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
345 |
|
13462 | 346 |
fun prep_simproc (name, pats, proc) = |
347 |
Simplifier.simproc (Theory.sign_of (the_context())) name pats proc; |
|
11868
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
348 |
|
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
349 |
fun is_numeral (Const("Numeral.number_of", _) $ w) = true |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
350 |
| is_numeral _ = false |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
351 |
|
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
352 |
fun simplify_meta_eq f_number_of_eq f_eq = |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
353 |
mk_meta_eq ([f_eq, f_number_of_eq] MRS trans) |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
354 |
|
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
355 |
structure IntAbstractNumeralsData = |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
356 |
struct |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
357 |
val dest_eq = HOLogic.dest_eq o HOLogic.dest_Trueprop o concl_of |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
358 |
val is_numeral = is_numeral |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
359 |
val numeral_0_eq_0 = int_numeral_0_eq_0 |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
360 |
val numeral_1_eq_1 = int_numeral_1_eq_1 |
13480
bb72bd43c6c3
use Tactic.prove instead of prove_goalw_cterm in internal proofs!
wenzelm
parents:
13462
diff
changeset
|
361 |
val prove_conv = prove_conv_nohyps_novars |
11868
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
362 |
fun norm_tac simps = ALLGOALS (simp_tac (HOL_ss addsimps simps)) |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
363 |
val simplify_meta_eq = simplify_meta_eq |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
364 |
end |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
365 |
|
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
366 |
structure IntAbstractNumerals = AbstractNumeralsFun (IntAbstractNumeralsData) |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
367 |
|
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
368 |
|
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
369 |
(*For addition, we already have rules for the operand 0. |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
370 |
Multiplication is omitted because there are already special rules for |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
371 |
both 0 and 1 as operands. Unary minus is trivial, just have - 1 = -1. |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
372 |
For the others, having three patterns is a compromise between just having |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
373 |
one (many spurious calls) and having nine (just too many!) *) |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
374 |
val eval_numerals = |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
375 |
map prep_simproc |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
376 |
[("int_add_eval_numerals", |
13462 | 377 |
["(m::int) + 1", "(m::int) + number_of v"], |
11868
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
378 |
IntAbstractNumerals.proc (number_of_add RS sym)), |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
379 |
("int_diff_eval_numerals", |
13462 | 380 |
["(m::int) - 1", "(m::int) - number_of v"], |
11868
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
381 |
IntAbstractNumerals.proc diff_number_of_eq), |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
382 |
("int_eq_eval_numerals", |
13462 | 383 |
["(m::int) = 0", "(m::int) = 1", "(m::int) = number_of v"], |
11868
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
384 |
IntAbstractNumerals.proc eq_number_of_eq), |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
385 |
("int_less_eval_numerals", |
13462 | 386 |
["(m::int) < 0", "(m::int) < 1", "(m::int) < number_of v"], |
11868
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
387 |
IntAbstractNumerals.proc less_number_of_eq_neg), |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
388 |
("int_le_eval_numerals", |
13462 | 389 |
["(m::int) <= 0", "(m::int) <= 1", "(m::int) <= number_of v"], |
11868
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
390 |
IntAbstractNumerals.proc le_number_of_eq_not_less)] |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
391 |
|
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
392 |
(*reorientation simprules using ==, for the following simproc*) |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
393 |
val meta_zero_reorient = zero_reorient RS eq_reflection |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
394 |
val meta_one_reorient = one_reorient RS eq_reflection |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
395 |
val meta_number_of_reorient = number_of_reorient RS eq_reflection |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
396 |
|
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
397 |
(*reorientation simplification procedure: reorients (polymorphic) |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
398 |
0 = x, 1 = x, nnn = x provided x isn't 0, 1 or a numeral.*) |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
399 |
fun reorient_proc sg _ (_ $ t $ u) = |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
400 |
case u of |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
401 |
Const("0", _) => None |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
402 |
| Const("1", _) => None |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
403 |
| Const("Numeral.number_of", _) $ _ => None |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
404 |
| _ => Some (case t of |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
405 |
Const("0", _) => meta_zero_reorient |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
406 |
| Const("1", _) => meta_one_reorient |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
407 |
| Const("Numeral.number_of", _) $ _ => meta_number_of_reorient) |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
408 |
|
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
409 |
val reorient_simproc = |
13462 | 410 |
prep_simproc ("reorient_simproc", ["0=x", "1=x", "number_of w = x"], reorient_proc) |
11868
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
411 |
|
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
412 |
end; |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
413 |
|
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
414 |
|
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
415 |
Addsimprocs Bin_Simprocs.eval_numerals; |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
416 |
Addsimprocs [Bin_Simprocs.reorient_simproc]; |
9214 | 417 |
|
418 |
||
5540 | 419 |
(*Delete the original rewrites, with their clumsy conditional expressions*) |
5551 | 420 |
Delsimps [bin_succ_BIT, bin_pred_BIT, bin_minus_BIT, |
421 |
NCons_Pls, NCons_Min, bin_add_BIT, bin_mult_BIT]; |
|
5491 | 422 |
|
423 |
(*Hide the binary representation of integer constants*) |
|
6910 | 424 |
Delsimps [number_of_Pls, number_of_Min, number_of_BIT]; |
5491 | 425 |
|
11868
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
426 |
|
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
427 |
|
8787 | 428 |
(*Simplification of arithmetic operations on integer constants. |
429 |
Note that bin_pred_Pls, etc. were added to the simpset by primrec.*) |
|
430 |
||
11868
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
431 |
bind_thms ("NCons_simps", |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
432 |
[NCons_Pls_0, NCons_Pls_1, NCons_Min_0, NCons_Min_1, NCons_BIT]); |
8787 | 433 |
|
9108 | 434 |
bind_thms ("bin_arith_extra_simps", |
6910 | 435 |
[number_of_add RS sym, |
11868
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
436 |
number_of_minus RS sym, zminus_1_eq_m1, |
6910 | 437 |
number_of_mult RS sym, |
5779
5c74f003a68e
Explicit (and improved) simprules for binary arithmetic.
paulson
parents:
5747
diff
changeset
|
438 |
bin_succ_1, bin_succ_0, |
5c74f003a68e
Explicit (and improved) simprules for binary arithmetic.
paulson
parents:
5747
diff
changeset
|
439 |
bin_pred_1, bin_pred_0, |
5c74f003a68e
Explicit (and improved) simprules for binary arithmetic.
paulson
parents:
5747
diff
changeset
|
440 |
bin_minus_1, bin_minus_0, |
7517
bad2f36810e1
generalized the theorem bin_add_BIT_Min to bin_add_Min_right
paulson
parents:
7074
diff
changeset
|
441 |
bin_add_Pls_right, bin_add_Min_right, |
5779
5c74f003a68e
Explicit (and improved) simprules for binary arithmetic.
paulson
parents:
5747
diff
changeset
|
442 |
bin_add_BIT_0, bin_add_BIT_10, bin_add_BIT_11, |
11868
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
443 |
diff_number_of_eq, zabs_number_of, zabs_0, zabs_1, |
9108 | 444 |
bin_mult_1, bin_mult_0] @ NCons_simps); |
2224
4fc4b465be5b
New material from Norbert Voelker for efficient binary comparisons
paulson
parents:
1894
diff
changeset
|
445 |
|
5779
5c74f003a68e
Explicit (and improved) simprules for binary arithmetic.
paulson
parents:
5747
diff
changeset
|
446 |
(*For making a minimal simpset, one must include these default simprules |
6910 | 447 |
of thy. Also include simp_thms, or at least (~False)=True*) |
9108 | 448 |
bind_thms ("bin_arith_simps", |
5779
5c74f003a68e
Explicit (and improved) simprules for binary arithmetic.
paulson
parents:
5747
diff
changeset
|
449 |
[bin_pred_Pls, bin_pred_Min, |
5c74f003a68e
Explicit (and improved) simprules for binary arithmetic.
paulson
parents:
5747
diff
changeset
|
450 |
bin_succ_Pls, bin_succ_Min, |
5c74f003a68e
Explicit (and improved) simprules for binary arithmetic.
paulson
parents:
5747
diff
changeset
|
451 |
bin_add_Pls, bin_add_Min, |
5c74f003a68e
Explicit (and improved) simprules for binary arithmetic.
paulson
parents:
5747
diff
changeset
|
452 |
bin_minus_Pls, bin_minus_Min, |
9108 | 453 |
bin_mult_Pls, bin_mult_Min] @ bin_arith_extra_simps); |
2224
4fc4b465be5b
New material from Norbert Voelker for efficient binary comparisons
paulson
parents:
1894
diff
changeset
|
454 |
|
5779
5c74f003a68e
Explicit (and improved) simprules for binary arithmetic.
paulson
parents:
5747
diff
changeset
|
455 |
(*Simplification of relational operations*) |
9108 | 456 |
bind_thms ("bin_rel_simps", |
6910 | 457 |
[eq_number_of_eq, iszero_number_of_Pls, nonzero_number_of_Min, |
458 |
iszero_number_of_0, iszero_number_of_1, |
|
459 |
less_number_of_eq_neg, |
|
11868
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
460 |
not_neg_number_of_Pls, not_neg_0, not_neg_1, not_iszero_1, |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
461 |
neg_number_of_Min, neg_number_of_BIT, |
9108 | 462 |
le_number_of_eq_not_less]); |
2224
4fc4b465be5b
New material from Norbert Voelker for efficient binary comparisons
paulson
parents:
1894
diff
changeset
|
463 |
|
5779
5c74f003a68e
Explicit (and improved) simprules for binary arithmetic.
paulson
parents:
5747
diff
changeset
|
464 |
Addsimps bin_arith_extra_simps; |
5c74f003a68e
Explicit (and improved) simprules for binary arithmetic.
paulson
parents:
5747
diff
changeset
|
465 |
Addsimps bin_rel_simps; |
5510
ad120f7c52ad
improved (but still flawed) treatment of binary arithmetic
paulson
parents:
5491
diff
changeset
|
466 |
|
6997 | 467 |
|
8764 | 468 |
(** Simplification of arithmetic when nested to the right **) |
6997 | 469 |
|
8764 | 470 |
Goal "number_of v + (number_of w + z) = (number_of(bin_add v w) + z::int)"; |
471 |
by (simp_tac (simpset() addsimps [zadd_assoc RS sym]) 1); |
|
472 |
qed "add_number_of_left"; |
|
473 |
||
474 |
Goal "number_of v * (number_of w * z) = (number_of(bin_mult v w) * z::int)"; |
|
475 |
by (simp_tac (simpset() addsimps [zmult_assoc RS sym]) 1); |
|
476 |
qed "mult_number_of_left"; |
|
6997 | 477 |
|
478 |
Goalw [zdiff_def] |
|
479 |
"number_of v + (number_of w - c) = number_of(bin_add v w) - (c::int)"; |
|
8764 | 480 |
by (rtac add_number_of_left 1); |
481 |
qed "add_number_of_diff1"; |
|
6997 | 482 |
|
483 |
Goal "number_of v + (c - number_of w) = \ |
|
484 |
\ number_of (bin_add v (bin_minus w)) + (c::int)"; |
|
485 |
by (stac (diff_number_of_eq RS sym) 1); |
|
486 |
by Auto_tac; |
|
8764 | 487 |
qed "add_number_of_diff2"; |
6997 | 488 |
|
8764 | 489 |
Addsimps [add_number_of_left, mult_number_of_left, |
490 |
add_number_of_diff1, add_number_of_diff2]; |
|
11868
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
491 |
|
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
492 |
|
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
493 |
(** Inserting these natural simprules earlier would break many proofs! **) |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
494 |
|
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
495 |
(* int (Suc n) = 1 + int n *) |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
496 |
Addsimps [int_Suc]; |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
497 |
|
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
498 |
(* Numeral0 -> 0 and Numeral1 -> 1 *) |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
499 |
Addsimps [int_numeral_0_eq_0, int_numeral_1_eq_1]; |
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
500 |
|
56db9f3a6b3e
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
paulson
parents:
11713
diff
changeset
|
501 |