haftmann@29628
|
1 |
(* Title: HOL/Word/Word.thy
|
wenzelm@46124
|
2 |
Author: Jeremy Dawson and Gerwin Klein, NICTA
|
kleing@24333
|
3 |
*)
|
kleing@24333
|
4 |
|
wenzelm@61799
|
5 |
section \<open>A type of finite bit strings\<close>
|
huffman@24350
|
6 |
|
haftmann@29628
|
7 |
theory Word
|
wenzelm@41413
|
8 |
imports
|
wenzelm@41413
|
9 |
Type_Length
|
wenzelm@41413
|
10 |
"~~/src/HOL/Library/Boolean_Algebra"
|
haftmann@54854
|
11 |
Bits_Bit
|
wenzelm@41413
|
12 |
Bool_List_Representation
|
haftmann@53062
|
13 |
Misc_Typedef
|
haftmann@53062
|
14 |
Word_Miscellaneous
|
haftmann@37660
|
15 |
begin
|
haftmann@37660
|
16 |
|
wenzelm@61799
|
17 |
text \<open>See @{file "Examples/WordExamples.thy"} for examples.\<close>
|
wenzelm@61799
|
18 |
|
wenzelm@61799
|
19 |
subsection \<open>Type definition\<close>
|
haftmann@37660
|
20 |
|
wenzelm@61260
|
21 |
typedef (overloaded) 'a word = "{(0::int) ..< 2 ^ len_of TYPE('a::len0)}"
|
haftmann@37660
|
22 |
morphisms uint Abs_word by auto
|
haftmann@37660
|
23 |
|
huffman@47108
|
24 |
lemma uint_nonnegative:
|
huffman@47108
|
25 |
"0 \<le> uint w"
|
huffman@47108
|
26 |
using word.uint [of w] by simp
|
huffman@47108
|
27 |
|
huffman@47108
|
28 |
lemma uint_bounded:
|
huffman@47108
|
29 |
fixes w :: "'a::len0 word"
|
huffman@47108
|
30 |
shows "uint w < 2 ^ len_of TYPE('a)"
|
huffman@47108
|
31 |
using word.uint [of w] by simp
|
huffman@47108
|
32 |
|
huffman@47108
|
33 |
lemma uint_idem:
|
huffman@47108
|
34 |
fixes w :: "'a::len0 word"
|
huffman@47108
|
35 |
shows "uint w mod 2 ^ len_of TYPE('a) = uint w"
|
huffman@47108
|
36 |
using uint_nonnegative uint_bounded by (rule mod_pos_pos_trivial)
|
huffman@47108
|
37 |
|
haftmann@55816
|
38 |
lemma word_uint_eq_iff:
|
haftmann@55816
|
39 |
"a = b \<longleftrightarrow> uint a = uint b"
|
haftmann@55816
|
40 |
by (simp add: uint_inject)
|
haftmann@55816
|
41 |
|
haftmann@55816
|
42 |
lemma word_uint_eqI:
|
haftmann@55816
|
43 |
"uint a = uint b \<Longrightarrow> a = b"
|
haftmann@55816
|
44 |
by (simp add: word_uint_eq_iff)
|
haftmann@55816
|
45 |
|
wenzelm@61076
|
46 |
definition word_of_int :: "int \<Rightarrow> 'a::len0 word"
|
haftmann@54848
|
47 |
where
|
wenzelm@61799
|
48 |
\<comment> \<open>representation of words using unsigned or signed bins,
|
wenzelm@61799
|
49 |
only difference in these is the type class\<close>
|
haftmann@55816
|
50 |
"word_of_int k = Abs_word (k mod 2 ^ len_of TYPE('a))"
|
huffman@47108
|
51 |
|
huffman@47108
|
52 |
lemma uint_word_of_int:
|
huffman@47108
|
53 |
"uint (word_of_int k :: 'a::len0 word) = k mod 2 ^ len_of TYPE('a)"
|
huffman@47108
|
54 |
by (auto simp add: word_of_int_def intro: Abs_word_inverse)
|
huffman@47108
|
55 |
|
huffman@47108
|
56 |
lemma word_of_int_uint:
|
huffman@47108
|
57 |
"word_of_int (uint w) = w"
|
huffman@47108
|
58 |
by (simp add: word_of_int_def uint_idem uint_inverse)
|
huffman@47108
|
59 |
|
haftmann@55816
|
60 |
lemma split_word_all:
|
haftmann@55816
|
61 |
"(\<And>x::'a::len0 word. PROP P x) \<equiv> (\<And>x. PROP P (word_of_int x))"
|
haftmann@55816
|
62 |
proof
|
haftmann@55816
|
63 |
fix x :: "'a word"
|
haftmann@55816
|
64 |
assume "\<And>x. PROP P (word_of_int x)"
|
haftmann@55816
|
65 |
then have "PROP P (word_of_int (uint x))" .
|
haftmann@55816
|
66 |
then show "PROP P x" by (simp add: word_of_int_uint)
|
haftmann@55816
|
67 |
qed
|
haftmann@55816
|
68 |
|
haftmann@55816
|
69 |
|
wenzelm@61799
|
70 |
subsection \<open>Type conversions and casting\<close>
|
haftmann@55816
|
71 |
|
haftmann@55816
|
72 |
definition sint :: "'a::len word \<Rightarrow> int"
|
haftmann@55816
|
73 |
where
|
wenzelm@61799
|
74 |
\<comment> \<open>treats the most-significant-bit as a sign bit\<close>
|
haftmann@55816
|
75 |
sint_uint: "sint w = sbintrunc (len_of TYPE ('a) - 1) (uint w)"
|
haftmann@55816
|
76 |
|
haftmann@55816
|
77 |
definition unat :: "'a::len0 word \<Rightarrow> nat"
|
haftmann@55816
|
78 |
where
|
haftmann@55816
|
79 |
"unat w = nat (uint w)"
|
haftmann@55816
|
80 |
|
haftmann@55816
|
81 |
definition uints :: "nat \<Rightarrow> int set"
|
haftmann@55816
|
82 |
where
|
wenzelm@61799
|
83 |
\<comment> "the sets of integers representing the words"
|
haftmann@55816
|
84 |
"uints n = range (bintrunc n)"
|
haftmann@55816
|
85 |
|
haftmann@55816
|
86 |
definition sints :: "nat \<Rightarrow> int set"
|
haftmann@55816
|
87 |
where
|
haftmann@55816
|
88 |
"sints n = range (sbintrunc (n - 1))"
|
haftmann@55816
|
89 |
|
haftmann@55816
|
90 |
lemma uints_num:
|
haftmann@55816
|
91 |
"uints n = {i. 0 \<le> i \<and> i < 2 ^ n}"
|
haftmann@55816
|
92 |
by (simp add: uints_def range_bintrunc)
|
haftmann@55816
|
93 |
|
haftmann@55816
|
94 |
lemma sints_num:
|
haftmann@55816
|
95 |
"sints n = {i. - (2 ^ (n - 1)) \<le> i \<and> i < 2 ^ (n - 1)}"
|
haftmann@55816
|
96 |
by (simp add: sints_def range_sbintrunc)
|
haftmann@55816
|
97 |
|
haftmann@55816
|
98 |
definition unats :: "nat \<Rightarrow> nat set"
|
haftmann@55816
|
99 |
where
|
haftmann@55816
|
100 |
"unats n = {i. i < 2 ^ n}"
|
haftmann@55816
|
101 |
|
haftmann@55816
|
102 |
definition norm_sint :: "nat \<Rightarrow> int \<Rightarrow> int"
|
haftmann@55816
|
103 |
where
|
haftmann@55816
|
104 |
"norm_sint n w = (w + 2 ^ (n - 1)) mod 2 ^ n - 2 ^ (n - 1)"
|
haftmann@55816
|
105 |
|
haftmann@55816
|
106 |
definition scast :: "'a::len word \<Rightarrow> 'b::len word"
|
haftmann@55816
|
107 |
where
|
wenzelm@61799
|
108 |
\<comment> "cast a word to a different length"
|
haftmann@55816
|
109 |
"scast w = word_of_int (sint w)"
|
haftmann@55816
|
110 |
|
haftmann@55816
|
111 |
definition ucast :: "'a::len0 word \<Rightarrow> 'b::len0 word"
|
haftmann@55816
|
112 |
where
|
haftmann@55816
|
113 |
"ucast w = word_of_int (uint w)"
|
haftmann@55816
|
114 |
|
haftmann@55816
|
115 |
instantiation word :: (len0) size
|
haftmann@55816
|
116 |
begin
|
haftmann@55816
|
117 |
|
haftmann@55816
|
118 |
definition
|
haftmann@55816
|
119 |
word_size: "size (w :: 'a word) = len_of TYPE('a)"
|
haftmann@55816
|
120 |
|
haftmann@55816
|
121 |
instance ..
|
haftmann@55816
|
122 |
|
haftmann@55816
|
123 |
end
|
haftmann@55816
|
124 |
|
haftmann@55816
|
125 |
lemma word_size_gt_0 [iff]:
|
haftmann@55816
|
126 |
"0 < size (w::'a::len word)"
|
haftmann@55816
|
127 |
by (simp add: word_size)
|
haftmann@55816
|
128 |
|
haftmann@55816
|
129 |
lemmas lens_gt_0 = word_size_gt_0 len_gt_0
|
haftmann@55816
|
130 |
|
haftmann@55816
|
131 |
lemma lens_not_0 [iff]:
|
haftmann@55816
|
132 |
shows "size (w::'a::len word) \<noteq> 0"
|
haftmann@55816
|
133 |
and "len_of TYPE('a::len) \<noteq> 0"
|
haftmann@55816
|
134 |
by auto
|
haftmann@55816
|
135 |
|
haftmann@55816
|
136 |
definition source_size :: "('a::len0 word \<Rightarrow> 'b) \<Rightarrow> nat"
|
haftmann@55816
|
137 |
where
|
wenzelm@61799
|
138 |
\<comment> "whether a cast (or other) function is to a longer or shorter length"
|
blanchet@58053
|
139 |
[code del]: "source_size c = (let arb = undefined; x = c arb in size arb)"
|
haftmann@55816
|
140 |
|
haftmann@55816
|
141 |
definition target_size :: "('a \<Rightarrow> 'b::len0 word) \<Rightarrow> nat"
|
haftmann@55816
|
142 |
where
|
blanchet@58053
|
143 |
[code del]: "target_size c = size (c undefined)"
|
haftmann@55816
|
144 |
|
haftmann@55816
|
145 |
definition is_up :: "('a::len0 word \<Rightarrow> 'b::len0 word) \<Rightarrow> bool"
|
haftmann@55816
|
146 |
where
|
haftmann@55816
|
147 |
"is_up c \<longleftrightarrow> source_size c \<le> target_size c"
|
haftmann@55816
|
148 |
|
haftmann@55816
|
149 |
definition is_down :: "('a :: len0 word \<Rightarrow> 'b :: len0 word) \<Rightarrow> bool"
|
haftmann@55816
|
150 |
where
|
haftmann@55816
|
151 |
"is_down c \<longleftrightarrow> target_size c \<le> source_size c"
|
haftmann@55816
|
152 |
|
haftmann@55816
|
153 |
definition of_bl :: "bool list \<Rightarrow> 'a::len0 word"
|
haftmann@55816
|
154 |
where
|
haftmann@55816
|
155 |
"of_bl bl = word_of_int (bl_to_bin bl)"
|
haftmann@55816
|
156 |
|
haftmann@55816
|
157 |
definition to_bl :: "'a::len0 word \<Rightarrow> bool list"
|
haftmann@55816
|
158 |
where
|
haftmann@55816
|
159 |
"to_bl w = bin_to_bl (len_of TYPE ('a)) (uint w)"
|
haftmann@55816
|
160 |
|
haftmann@55816
|
161 |
definition word_reverse :: "'a::len0 word \<Rightarrow> 'a word"
|
haftmann@55816
|
162 |
where
|
haftmann@55816
|
163 |
"word_reverse w = of_bl (rev (to_bl w))"
|
haftmann@55816
|
164 |
|
haftmann@55816
|
165 |
definition word_int_case :: "(int \<Rightarrow> 'b) \<Rightarrow> 'a::len0 word \<Rightarrow> 'b"
|
haftmann@55816
|
166 |
where
|
haftmann@55816
|
167 |
"word_int_case f w = f (uint w)"
|
haftmann@55816
|
168 |
|
haftmann@55816
|
169 |
translations
|
haftmann@55816
|
170 |
"case x of XCONST of_int y => b" == "CONST word_int_case (%y. b) x"
|
haftmann@55816
|
171 |
"case x of (XCONST of_int :: 'a) y => b" => "CONST word_int_case (%y. b) x"
|
haftmann@55816
|
172 |
|
haftmann@55816
|
173 |
|
wenzelm@61799
|
174 |
subsection \<open>Correspondence relation for theorem transfer\<close>
|
haftmann@55817
|
175 |
|
haftmann@55817
|
176 |
definition cr_word :: "int \<Rightarrow> 'a::len0 word \<Rightarrow> bool"
|
haftmann@55817
|
177 |
where
|
haftmann@55817
|
178 |
"cr_word = (\<lambda>x y. word_of_int x = y)"
|
haftmann@55817
|
179 |
|
haftmann@55817
|
180 |
lemma Quotient_word:
|
haftmann@55817
|
181 |
"Quotient (\<lambda>x y. bintrunc (len_of TYPE('a)) x = bintrunc (len_of TYPE('a)) y)
|
haftmann@55817
|
182 |
word_of_int uint (cr_word :: _ \<Rightarrow> 'a::len0 word \<Rightarrow> bool)"
|
haftmann@55817
|
183 |
unfolding Quotient_alt_def cr_word_def
|
haftmann@55817
|
184 |
by (simp add: no_bintr_alt1 word_of_int_uint) (simp add: word_of_int_def Abs_word_inject)
|
haftmann@55817
|
185 |
|
haftmann@55817
|
186 |
lemma reflp_word:
|
haftmann@55817
|
187 |
"reflp (\<lambda>x y. bintrunc (len_of TYPE('a::len0)) x = bintrunc (len_of TYPE('a)) y)"
|
haftmann@55817
|
188 |
by (simp add: reflp_def)
|
haftmann@55817
|
189 |
|
haftmann@59487
|
190 |
setup_lifting Quotient_word reflp_word
|
haftmann@55817
|
191 |
|
wenzelm@61799
|
192 |
text \<open>TODO: The next lemma could be generated automatically.\<close>
|
haftmann@55817
|
193 |
|
haftmann@55817
|
194 |
lemma uint_transfer [transfer_rule]:
|
blanchet@55945
|
195 |
"(rel_fun pcr_word op =) (bintrunc (len_of TYPE('a)))
|
haftmann@55817
|
196 |
(uint :: 'a::len0 word \<Rightarrow> int)"
|
blanchet@55945
|
197 |
unfolding rel_fun_def word.pcr_cr_eq cr_word_def
|
haftmann@55817
|
198 |
by (simp add: no_bintr_alt1 uint_word_of_int)
|
haftmann@55817
|
199 |
|
haftmann@55817
|
200 |
|
wenzelm@61799
|
201 |
subsection \<open>Basic code generation setup\<close>
|
haftmann@55817
|
202 |
|
haftmann@55817
|
203 |
definition Word :: "int \<Rightarrow> 'a::len0 word"
|
haftmann@55817
|
204 |
where
|
haftmann@55817
|
205 |
[code_post]: "Word = word_of_int"
|
haftmann@55817
|
206 |
|
haftmann@55817
|
207 |
lemma [code abstype]:
|
haftmann@55817
|
208 |
"Word (uint w) = w"
|
haftmann@55817
|
209 |
by (simp add: Word_def word_of_int_uint)
|
haftmann@55817
|
210 |
|
haftmann@55817
|
211 |
declare uint_word_of_int [code abstract]
|
haftmann@55817
|
212 |
|
haftmann@55817
|
213 |
instantiation word :: (len0) equal
|
haftmann@55817
|
214 |
begin
|
haftmann@55817
|
215 |
|
haftmann@55817
|
216 |
definition equal_word :: "'a word \<Rightarrow> 'a word \<Rightarrow> bool"
|
haftmann@55817
|
217 |
where
|
haftmann@55817
|
218 |
"equal_word k l \<longleftrightarrow> HOL.equal (uint k) (uint l)"
|
haftmann@55817
|
219 |
|
haftmann@55817
|
220 |
instance proof
|
haftmann@55817
|
221 |
qed (simp add: equal equal_word_def word_uint_eq_iff)
|
haftmann@55817
|
222 |
|
haftmann@55817
|
223 |
end
|
haftmann@55817
|
224 |
|
haftmann@55817
|
225 |
notation fcomp (infixl "\<circ>>" 60)
|
haftmann@55817
|
226 |
notation scomp (infixl "\<circ>\<rightarrow>" 60)
|
haftmann@55817
|
227 |
|
haftmann@55817
|
228 |
instantiation word :: ("{len0, typerep}") random
|
haftmann@55817
|
229 |
begin
|
haftmann@55817
|
230 |
|
haftmann@55817
|
231 |
definition
|
haftmann@55817
|
232 |
"random_word i = Random.range i \<circ>\<rightarrow> (\<lambda>k. Pair (
|
haftmann@55817
|
233 |
let j = word_of_int (int_of_integer (integer_of_natural k)) :: 'a word
|
haftmann@55817
|
234 |
in (j, \<lambda>_::unit. Code_Evaluation.term_of j)))"
|
haftmann@55817
|
235 |
|
haftmann@55817
|
236 |
instance ..
|
haftmann@55817
|
237 |
|
haftmann@55817
|
238 |
end
|
haftmann@55817
|
239 |
|
haftmann@55817
|
240 |
no_notation fcomp (infixl "\<circ>>" 60)
|
haftmann@55817
|
241 |
no_notation scomp (infixl "\<circ>\<rightarrow>" 60)
|
haftmann@55817
|
242 |
|
haftmann@55817
|
243 |
|
wenzelm@61799
|
244 |
subsection \<open>Type-definition locale instantiations\<close>
|
haftmann@55816
|
245 |
|
haftmann@55816
|
246 |
lemmas uint_0 = uint_nonnegative (* FIXME duplicate *)
|
haftmann@55816
|
247 |
lemmas uint_lt = uint_bounded (* FIXME duplicate *)
|
haftmann@55816
|
248 |
lemmas uint_mod_same = uint_idem (* FIXME duplicate *)
|
haftmann@55816
|
249 |
|
haftmann@55816
|
250 |
lemma td_ext_uint:
|
haftmann@55816
|
251 |
"td_ext (uint :: 'a word \<Rightarrow> int) word_of_int (uints (len_of TYPE('a::len0)))
|
haftmann@55816
|
252 |
(\<lambda>w::int. w mod 2 ^ len_of TYPE('a))"
|
haftmann@55816
|
253 |
apply (unfold td_ext_def')
|
haftmann@55816
|
254 |
apply (simp add: uints_num word_of_int_def bintrunc_mod2p)
|
haftmann@55816
|
255 |
apply (simp add: uint_mod_same uint_0 uint_lt
|
haftmann@55816
|
256 |
word.uint_inverse word.Abs_word_inverse int_mod_lem)
|
haftmann@55816
|
257 |
done
|
haftmann@55816
|
258 |
|
haftmann@55816
|
259 |
interpretation word_uint:
|
haftmann@55816
|
260 |
td_ext "uint::'a::len0 word \<Rightarrow> int"
|
haftmann@55816
|
261 |
word_of_int
|
haftmann@55816
|
262 |
"uints (len_of TYPE('a::len0))"
|
haftmann@55816
|
263 |
"\<lambda>w. w mod 2 ^ len_of TYPE('a::len0)"
|
haftmann@55816
|
264 |
by (fact td_ext_uint)
|
haftmann@55816
|
265 |
|
haftmann@55816
|
266 |
lemmas td_uint = word_uint.td_thm
|
haftmann@55816
|
267 |
lemmas int_word_uint = word_uint.eq_norm
|
haftmann@55816
|
268 |
|
haftmann@55816
|
269 |
lemma td_ext_ubin:
|
haftmann@55816
|
270 |
"td_ext (uint :: 'a word \<Rightarrow> int) word_of_int (uints (len_of TYPE('a::len0)))
|
haftmann@55816
|
271 |
(bintrunc (len_of TYPE('a)))"
|
haftmann@55816
|
272 |
by (unfold no_bintr_alt1) (fact td_ext_uint)
|
haftmann@55816
|
273 |
|
haftmann@55816
|
274 |
interpretation word_ubin:
|
haftmann@55816
|
275 |
td_ext "uint::'a::len0 word \<Rightarrow> int"
|
haftmann@55816
|
276 |
word_of_int
|
haftmann@55816
|
277 |
"uints (len_of TYPE('a::len0))"
|
haftmann@55816
|
278 |
"bintrunc (len_of TYPE('a::len0))"
|
haftmann@55816
|
279 |
by (fact td_ext_ubin)
|
haftmann@55816
|
280 |
|
haftmann@55816
|
281 |
|
wenzelm@61799
|
282 |
subsection \<open>Arithmetic operations\<close>
|
haftmann@37660
|
283 |
|
huffman@47387
|
284 |
lift_definition word_succ :: "'a::len0 word \<Rightarrow> 'a word" is "\<lambda>x. x + 1"
|
huffman@47374
|
285 |
by (metis bintr_ariths(6))
|
huffman@47374
|
286 |
|
huffman@47387
|
287 |
lift_definition word_pred :: "'a::len0 word \<Rightarrow> 'a word" is "\<lambda>x. x - 1"
|
huffman@47374
|
288 |
by (metis bintr_ariths(7))
|
huffman@45545
|
289 |
|
huffman@47108
|
290 |
instantiation word :: (len0) "{neg_numeral, Divides.div, comm_monoid_mult, comm_ring}"
|
haftmann@37660
|
291 |
begin
|
haftmann@37660
|
292 |
|
huffman@47387
|
293 |
lift_definition zero_word :: "'a word" is "0" .
|
huffman@47387
|
294 |
|
huffman@47387
|
295 |
lift_definition one_word :: "'a word" is "1" .
|
huffman@47387
|
296 |
|
huffman@47387
|
297 |
lift_definition plus_word :: "'a word \<Rightarrow> 'a word \<Rightarrow> 'a word" is "op +"
|
huffman@47374
|
298 |
by (metis bintr_ariths(2))
|
huffman@47374
|
299 |
|
huffman@47387
|
300 |
lift_definition minus_word :: "'a word \<Rightarrow> 'a word \<Rightarrow> 'a word" is "op -"
|
huffman@47374
|
301 |
by (metis bintr_ariths(3))
|
huffman@47374
|
302 |
|
huffman@47387
|
303 |
lift_definition uminus_word :: "'a word \<Rightarrow> 'a word" is uminus
|
huffman@47374
|
304 |
by (metis bintr_ariths(5))
|
huffman@47374
|
305 |
|
huffman@47387
|
306 |
lift_definition times_word :: "'a word \<Rightarrow> 'a word \<Rightarrow> 'a word" is "op *"
|
huffman@47374
|
307 |
by (metis bintr_ariths(4))
|
haftmann@37660
|
308 |
|
haftmann@37660
|
309 |
definition
|
haftmann@60429
|
310 |
word_div_def: "a div b = word_of_int (uint a div uint b)"
|
haftmann@37660
|
311 |
|
haftmann@37660
|
312 |
definition
|
haftmann@37660
|
313 |
word_mod_def: "a mod b = word_of_int (uint a mod uint b)"
|
haftmann@37660
|
314 |
|
huffman@47374
|
315 |
instance
|
wenzelm@61169
|
316 |
by standard (transfer, simp add: algebra_simps)+
|
huffman@47374
|
317 |
|
huffman@47374
|
318 |
end
|
huffman@47374
|
319 |
|
wenzelm@61799
|
320 |
text \<open>Legacy theorems:\<close>
|
huffman@47374
|
321 |
|
huffman@47611
|
322 |
lemma word_arith_wis [code]: shows
|
huffman@47374
|
323 |
word_add_def: "a + b = word_of_int (uint a + uint b)" and
|
huffman@47374
|
324 |
word_sub_wi: "a - b = word_of_int (uint a - uint b)" and
|
huffman@47374
|
325 |
word_mult_def: "a * b = word_of_int (uint a * uint b)" and
|
huffman@47374
|
326 |
word_minus_def: "- a = word_of_int (- uint a)" and
|
huffman@47374
|
327 |
word_succ_alt: "word_succ a = word_of_int (uint a + 1)" and
|
huffman@47374
|
328 |
word_pred_alt: "word_pred a = word_of_int (uint a - 1)" and
|
huffman@47374
|
329 |
word_0_wi: "0 = word_of_int 0" and
|
huffman@47374
|
330 |
word_1_wi: "1 = word_of_int 1"
|
huffman@47374
|
331 |
unfolding plus_word_def minus_word_def times_word_def uminus_word_def
|
huffman@47374
|
332 |
unfolding word_succ_def word_pred_def zero_word_def one_word_def
|
huffman@47374
|
333 |
by simp_all
|
huffman@45545
|
334 |
|
huffman@45545
|
335 |
lemmas arths =
|
wenzelm@45604
|
336 |
bintr_ariths [THEN word_ubin.norm_eq_iff [THEN iffD1], folded word_ubin.eq_norm]
|
huffman@45545
|
337 |
|
huffman@45545
|
338 |
lemma wi_homs:
|
huffman@45545
|
339 |
shows
|
huffman@45545
|
340 |
wi_hom_add: "word_of_int a + word_of_int b = word_of_int (a + b)" and
|
huffman@46013
|
341 |
wi_hom_sub: "word_of_int a - word_of_int b = word_of_int (a - b)" and
|
huffman@45545
|
342 |
wi_hom_mult: "word_of_int a * word_of_int b = word_of_int (a * b)" and
|
huffman@45545
|
343 |
wi_hom_neg: "- word_of_int a = word_of_int (- a)" and
|
huffman@46000
|
344 |
wi_hom_succ: "word_succ (word_of_int a) = word_of_int (a + 1)" and
|
huffman@46000
|
345 |
wi_hom_pred: "word_pred (word_of_int a) = word_of_int (a - 1)"
|
huffman@47374
|
346 |
by (transfer, simp)+
|
huffman@45545
|
347 |
|
huffman@45545
|
348 |
lemmas wi_hom_syms = wi_homs [symmetric]
|
huffman@45545
|
349 |
|
huffman@46013
|
350 |
lemmas word_of_int_homs = wi_homs word_0_wi word_1_wi
|
huffman@46009
|
351 |
|
huffman@46009
|
352 |
lemmas word_of_int_hom_syms = word_of_int_homs [symmetric]
|
huffman@45545
|
353 |
|
huffman@45545
|
354 |
instance word :: (len) comm_ring_1
|
huffman@45810
|
355 |
proof
|
huffman@45810
|
356 |
have "0 < len_of TYPE('a)" by (rule len_gt_0)
|
huffman@45810
|
357 |
then show "(0::'a word) \<noteq> 1"
|
huffman@47372
|
358 |
by - (transfer, auto simp add: gr0_conv_Suc)
|
huffman@45810
|
359 |
qed
|
huffman@45545
|
360 |
|
huffman@45545
|
361 |
lemma word_of_nat: "of_nat n = word_of_int (int n)"
|
huffman@45545
|
362 |
by (induct n) (auto simp add : word_of_int_hom_syms)
|
huffman@45545
|
363 |
|
huffman@45545
|
364 |
lemma word_of_int: "of_int = word_of_int"
|
huffman@45545
|
365 |
apply (rule ext)
|
huffman@45545
|
366 |
apply (case_tac x rule: int_diff_cases)
|
huffman@46013
|
367 |
apply (simp add: word_of_nat wi_hom_sub)
|
huffman@45545
|
368 |
done
|
huffman@45545
|
369 |
|
haftmann@54848
|
370 |
definition udvd :: "'a::len word => 'a::len word => bool" (infixl "udvd" 50)
|
haftmann@54848
|
371 |
where
|
haftmann@40827
|
372 |
"a udvd b = (EX n>=0. uint b = n * uint a)"
|
haftmann@37660
|
373 |
|
huffman@45547
|
374 |
|
wenzelm@61799
|
375 |
subsection \<open>Ordering\<close>
|
huffman@45547
|
376 |
|
huffman@45547
|
377 |
instantiation word :: (len0) linorder
|
huffman@45547
|
378 |
begin
|
huffman@45547
|
379 |
|
haftmann@37660
|
380 |
definition
|
haftmann@37660
|
381 |
word_le_def: "a \<le> b \<longleftrightarrow> uint a \<le> uint b"
|
haftmann@37660
|
382 |
|
haftmann@37660
|
383 |
definition
|
huffman@47108
|
384 |
word_less_def: "a < b \<longleftrightarrow> uint a < uint b"
|
haftmann@37660
|
385 |
|
huffman@45547
|
386 |
instance
|
wenzelm@61169
|
387 |
by standard (auto simp: word_less_def word_le_def)
|
huffman@45547
|
388 |
|
huffman@45547
|
389 |
end
|
huffman@45547
|
390 |
|
haftmann@54848
|
391 |
definition word_sle :: "'a :: len word => 'a word => bool" ("(_/ <=s _)" [50, 51] 50)
|
haftmann@54848
|
392 |
where
|
haftmann@40827
|
393 |
"a <=s b = (sint a <= sint b)"
|
haftmann@37660
|
394 |
|
haftmann@54848
|
395 |
definition word_sless :: "'a :: len word => 'a word => bool" ("(_/ <s _)" [50, 51] 50)
|
haftmann@54848
|
396 |
where
|
haftmann@40827
|
397 |
"(x <s y) = (x <=s y & x ~= y)"
|
haftmann@37660
|
398 |
|
haftmann@37660
|
399 |
|
wenzelm@61799
|
400 |
subsection \<open>Bit-wise operations\<close>
|
haftmann@37660
|
401 |
|
haftmann@37660
|
402 |
instantiation word :: (len0) bits
|
haftmann@37660
|
403 |
begin
|
haftmann@37660
|
404 |
|
huffman@47387
|
405 |
lift_definition bitNOT_word :: "'a word \<Rightarrow> 'a word" is bitNOT
|
huffman@47374
|
406 |
by (metis bin_trunc_not)
|
huffman@47374
|
407 |
|
huffman@47387
|
408 |
lift_definition bitAND_word :: "'a word \<Rightarrow> 'a word \<Rightarrow> 'a word" is bitAND
|
huffman@47374
|
409 |
by (metis bin_trunc_and)
|
huffman@47374
|
410 |
|
huffman@47387
|
411 |
lift_definition bitOR_word :: "'a word \<Rightarrow> 'a word \<Rightarrow> 'a word" is bitOR
|
huffman@47374
|
412 |
by (metis bin_trunc_or)
|
huffman@47374
|
413 |
|
huffman@47387
|
414 |
lift_definition bitXOR_word :: "'a word \<Rightarrow> 'a word \<Rightarrow> 'a word" is bitXOR
|
huffman@47374
|
415 |
by (metis bin_trunc_xor)
|
haftmann@37660
|
416 |
|
haftmann@37660
|
417 |
definition
|
haftmann@37660
|
418 |
word_test_bit_def: "test_bit a = bin_nth (uint a)"
|
haftmann@37660
|
419 |
|
haftmann@37660
|
420 |
definition
|
haftmann@37660
|
421 |
word_set_bit_def: "set_bit a n x =
|
haftmann@54847
|
422 |
word_of_int (bin_sc n x (uint a))"
|
haftmann@37660
|
423 |
|
haftmann@37660
|
424 |
definition
|
haftmann@37660
|
425 |
word_set_bits_def: "(BITS n. f n) = of_bl (bl_of_nth (len_of TYPE ('a)) f)"
|
haftmann@37660
|
426 |
|
haftmann@37660
|
427 |
definition
|
haftmann@54847
|
428 |
word_lsb_def: "lsb a \<longleftrightarrow> bin_last (uint a)"
|
haftmann@37660
|
429 |
|
haftmann@54848
|
430 |
definition shiftl1 :: "'a word \<Rightarrow> 'a word"
|
haftmann@54848
|
431 |
where
|
haftmann@54847
|
432 |
"shiftl1 w = word_of_int (uint w BIT False)"
|
haftmann@37660
|
433 |
|
haftmann@54848
|
434 |
definition shiftr1 :: "'a word \<Rightarrow> 'a word"
|
haftmann@54848
|
435 |
where
|
wenzelm@61799
|
436 |
\<comment> "shift right as unsigned or as signed, ie logical or arithmetic"
|
haftmann@37660
|
437 |
"shiftr1 w = word_of_int (bin_rest (uint w))"
|
haftmann@37660
|
438 |
|
haftmann@37660
|
439 |
definition
|
haftmann@37660
|
440 |
shiftl_def: "w << n = (shiftl1 ^^ n) w"
|
haftmann@37660
|
441 |
|
haftmann@37660
|
442 |
definition
|
haftmann@37660
|
443 |
shiftr_def: "w >> n = (shiftr1 ^^ n) w"
|
haftmann@37660
|
444 |
|
haftmann@37660
|
445 |
instance ..
|
haftmann@37660
|
446 |
|
haftmann@37660
|
447 |
end
|
haftmann@37660
|
448 |
|
huffman@47611
|
449 |
lemma [code]: shows
|
huffman@47374
|
450 |
word_not_def: "NOT (a::'a::len0 word) = word_of_int (NOT (uint a))" and
|
huffman@47374
|
451 |
word_and_def: "(a::'a word) AND b = word_of_int (uint a AND uint b)" and
|
huffman@47374
|
452 |
word_or_def: "(a::'a word) OR b = word_of_int (uint a OR uint b)" and
|
huffman@47374
|
453 |
word_xor_def: "(a::'a word) XOR b = word_of_int (uint a XOR uint b)"
|
huffman@47374
|
454 |
unfolding bitNOT_word_def bitAND_word_def bitOR_word_def bitXOR_word_def
|
huffman@47374
|
455 |
by simp_all
|
huffman@47374
|
456 |
|
haftmann@37660
|
457 |
instantiation word :: (len) bitss
|
haftmann@37660
|
458 |
begin
|
haftmann@37660
|
459 |
|
haftmann@37660
|
460 |
definition
|
haftmann@37660
|
461 |
word_msb_def:
|
huffman@46001
|
462 |
"msb a \<longleftrightarrow> bin_sign (sint a) = -1"
|
haftmann@37660
|
463 |
|
haftmann@37660
|
464 |
instance ..
|
haftmann@37660
|
465 |
|
haftmann@37660
|
466 |
end
|
haftmann@37660
|
467 |
|
haftmann@54848
|
468 |
definition setBit :: "'a :: len0 word => nat => 'a word"
|
haftmann@54848
|
469 |
where
|
haftmann@40827
|
470 |
"setBit w n = set_bit w n True"
|
haftmann@37660
|
471 |
|
haftmann@54848
|
472 |
definition clearBit :: "'a :: len0 word => nat => 'a word"
|
haftmann@54848
|
473 |
where
|
haftmann@40827
|
474 |
"clearBit w n = set_bit w n False"
|
haftmann@37660
|
475 |
|
haftmann@37660
|
476 |
|
wenzelm@61799
|
477 |
subsection \<open>Shift operations\<close>
|
haftmann@37660
|
478 |
|
haftmann@54848
|
479 |
definition sshiftr1 :: "'a :: len word => 'a word"
|
haftmann@54848
|
480 |
where
|
haftmann@40827
|
481 |
"sshiftr1 w = word_of_int (bin_rest (sint w))"
|
haftmann@37660
|
482 |
|
haftmann@54848
|
483 |
definition bshiftr1 :: "bool => 'a :: len word => 'a word"
|
haftmann@54848
|
484 |
where
|
haftmann@40827
|
485 |
"bshiftr1 b w = of_bl (b # butlast (to_bl w))"
|
haftmann@37660
|
486 |
|
haftmann@54848
|
487 |
definition sshiftr :: "'a :: len word => nat => 'a word" (infixl ">>>" 55)
|
haftmann@54848
|
488 |
where
|
haftmann@40827
|
489 |
"w >>> n = (sshiftr1 ^^ n) w"
|
haftmann@37660
|
490 |
|
haftmann@54848
|
491 |
definition mask :: "nat => 'a::len word"
|
haftmann@54848
|
492 |
where
|
haftmann@40827
|
493 |
"mask n = (1 << n) - 1"
|
haftmann@37660
|
494 |
|
haftmann@54848
|
495 |
definition revcast :: "'a :: len0 word => 'b :: len0 word"
|
haftmann@54848
|
496 |
where
|
haftmann@40827
|
497 |
"revcast w = of_bl (takefill False (len_of TYPE('b)) (to_bl w))"
|
haftmann@37660
|
498 |
|
haftmann@54848
|
499 |
definition slice1 :: "nat => 'a :: len0 word => 'b :: len0 word"
|
haftmann@54848
|
500 |
where
|
haftmann@40827
|
501 |
"slice1 n w = of_bl (takefill False n (to_bl w))"
|
haftmann@37660
|
502 |
|
haftmann@54848
|
503 |
definition slice :: "nat => 'a :: len0 word => 'b :: len0 word"
|
haftmann@54848
|
504 |
where
|
haftmann@40827
|
505 |
"slice n w = slice1 (size w - n) w"
|
haftmann@37660
|
506 |
|
haftmann@37660
|
507 |
|
wenzelm@61799
|
508 |
subsection \<open>Rotation\<close>
|
haftmann@37660
|
509 |
|
haftmann@54848
|
510 |
definition rotater1 :: "'a list => 'a list"
|
haftmann@54848
|
511 |
where
|
haftmann@40827
|
512 |
"rotater1 ys =
|
haftmann@40827
|
513 |
(case ys of [] => [] | x # xs => last ys # butlast ys)"
|
haftmann@37660
|
514 |
|
haftmann@54848
|
515 |
definition rotater :: "nat => 'a list => 'a list"
|
haftmann@54848
|
516 |
where
|
haftmann@40827
|
517 |
"rotater n = rotater1 ^^ n"
|
haftmann@37660
|
518 |
|
haftmann@54848
|
519 |
definition word_rotr :: "nat => 'a :: len0 word => 'a :: len0 word"
|
haftmann@54848
|
520 |
where
|
haftmann@40827
|
521 |
"word_rotr n w = of_bl (rotater n (to_bl w))"
|
haftmann@37660
|
522 |
|
haftmann@54848
|
523 |
definition word_rotl :: "nat => 'a :: len0 word => 'a :: len0 word"
|
haftmann@54848
|
524 |
where
|
haftmann@40827
|
525 |
"word_rotl n w = of_bl (rotate n (to_bl w))"
|
haftmann@37660
|
526 |
|
haftmann@54848
|
527 |
definition word_roti :: "int => 'a :: len0 word => 'a :: len0 word"
|
haftmann@54848
|
528 |
where
|
haftmann@40827
|
529 |
"word_roti i w = (if i >= 0 then word_rotr (nat i) w
|
haftmann@40827
|
530 |
else word_rotl (nat (- i)) w)"
|
haftmann@37660
|
531 |
|
haftmann@37660
|
532 |
|
wenzelm@61799
|
533 |
subsection \<open>Split and cat operations\<close>
|
haftmann@37660
|
534 |
|
haftmann@54848
|
535 |
definition word_cat :: "'a :: len0 word => 'b :: len0 word => 'c :: len0 word"
|
haftmann@54848
|
536 |
where
|
haftmann@40827
|
537 |
"word_cat a b = word_of_int (bin_cat (uint a) (len_of TYPE ('b)) (uint b))"
|
haftmann@37660
|
538 |
|
haftmann@54848
|
539 |
definition word_split :: "'a :: len0 word => ('b :: len0 word) * ('c :: len0 word)"
|
haftmann@54848
|
540 |
where
|
haftmann@40827
|
541 |
"word_split a =
|
haftmann@40827
|
542 |
(case bin_split (len_of TYPE ('c)) (uint a) of
|
haftmann@40827
|
543 |
(u, v) => (word_of_int u, word_of_int v))"
|
haftmann@37660
|
544 |
|
haftmann@54848
|
545 |
definition word_rcat :: "'a :: len0 word list => 'b :: len0 word"
|
haftmann@54848
|
546 |
where
|
haftmann@40827
|
547 |
"word_rcat ws =
|
haftmann@37660
|
548 |
word_of_int (bin_rcat (len_of TYPE ('a)) (map uint ws))"
|
haftmann@37660
|
549 |
|
haftmann@54848
|
550 |
definition word_rsplit :: "'a :: len0 word => 'b :: len word list"
|
haftmann@54848
|
551 |
where
|
haftmann@40827
|
552 |
"word_rsplit w =
|
haftmann@37660
|
553 |
map word_of_int (bin_rsplit (len_of TYPE ('b)) (len_of TYPE ('a), uint w))"
|
haftmann@37660
|
554 |
|
wenzelm@61799
|
555 |
definition max_word :: "'a::len word" \<comment> "Largest representable machine integer."
|
haftmann@54848
|
556 |
where
|
haftmann@40827
|
557 |
"max_word = word_of_int (2 ^ len_of TYPE('a) - 1)"
|
haftmann@37660
|
558 |
|
haftmann@55816
|
559 |
lemmas of_nth_def = word_set_bits_def (* FIXME duplicate *)
|
haftmann@55816
|
560 |
|
haftmann@37660
|
561 |
|
wenzelm@61799
|
562 |
subsection \<open>Theorems about typedefs\<close>
|
huffman@46010
|
563 |
|
haftmann@37660
|
564 |
lemma sint_sbintrunc':
|
haftmann@37660
|
565 |
"sint (word_of_int bin :: 'a word) =
|
haftmann@37660
|
566 |
(sbintrunc (len_of TYPE ('a :: len) - 1) bin)"
|
haftmann@37660
|
567 |
unfolding sint_uint
|
haftmann@37660
|
568 |
by (auto simp: word_ubin.eq_norm sbintrunc_bintrunc_lt)
|
haftmann@37660
|
569 |
|
haftmann@37660
|
570 |
lemma uint_sint:
|
haftmann@37660
|
571 |
"uint w = bintrunc (len_of TYPE('a)) (sint (w :: 'a :: len word))"
|
haftmann@37660
|
572 |
unfolding sint_uint by (auto simp: bintrunc_sbintrunc_le)
|
haftmann@37660
|
573 |
|
huffman@46057
|
574 |
lemma bintr_uint:
|
huffman@46057
|
575 |
fixes w :: "'a::len0 word"
|
huffman@46057
|
576 |
shows "len_of TYPE('a) \<le> n \<Longrightarrow> bintrunc n (uint w) = uint w"
|
haftmann@37660
|
577 |
apply (subst word_ubin.norm_Rep [symmetric])
|
haftmann@37660
|
578 |
apply (simp only: bintrunc_bintrunc_min word_size)
|
haftmann@54863
|
579 |
apply (simp add: min.absorb2)
|
haftmann@37660
|
580 |
done
|
haftmann@37660
|
581 |
|
huffman@46057
|
582 |
lemma wi_bintr:
|
huffman@46057
|
583 |
"len_of TYPE('a::len0) \<le> n \<Longrightarrow>
|
huffman@46057
|
584 |
word_of_int (bintrunc n w) = (word_of_int w :: 'a word)"
|
haftmann@54863
|
585 |
by (clarsimp simp add: word_ubin.norm_eq_iff [symmetric] min.absorb1)
|
haftmann@37660
|
586 |
|
haftmann@37660
|
587 |
lemma td_ext_sbin:
|
haftmann@55816
|
588 |
"td_ext (sint :: 'a word \<Rightarrow> int) word_of_int (sints (len_of TYPE('a::len)))
|
haftmann@37660
|
589 |
(sbintrunc (len_of TYPE('a) - 1))"
|
haftmann@37660
|
590 |
apply (unfold td_ext_def' sint_uint)
|
haftmann@37660
|
591 |
apply (simp add : word_ubin.eq_norm)
|
haftmann@37660
|
592 |
apply (cases "len_of TYPE('a)")
|
haftmann@37660
|
593 |
apply (auto simp add : sints_def)
|
haftmann@37660
|
594 |
apply (rule sym [THEN trans])
|
haftmann@37660
|
595 |
apply (rule word_ubin.Abs_norm)
|
haftmann@37660
|
596 |
apply (simp only: bintrunc_sbintrunc)
|
haftmann@37660
|
597 |
apply (drule sym)
|
haftmann@37660
|
598 |
apply simp
|
haftmann@37660
|
599 |
done
|
haftmann@37660
|
600 |
|
haftmann@55816
|
601 |
lemma td_ext_sint:
|
haftmann@55816
|
602 |
"td_ext (sint :: 'a word \<Rightarrow> int) word_of_int (sints (len_of TYPE('a::len)))
|
haftmann@55816
|
603 |
(\<lambda>w. (w + 2 ^ (len_of TYPE('a) - 1)) mod 2 ^ len_of TYPE('a) -
|
haftmann@55816
|
604 |
2 ^ (len_of TYPE('a) - 1))"
|
haftmann@55816
|
605 |
using td_ext_sbin [where ?'a = 'a] by (simp add: no_sbintr_alt2)
|
haftmann@37660
|
606 |
|
haftmann@37660
|
607 |
(* We do sint before sbin, before sint is the user version
|
haftmann@37660
|
608 |
and interpretations do not produce thm duplicates. I.e.
|
haftmann@37660
|
609 |
we get the name word_sint.Rep_eqD, but not word_sbin.Req_eqD,
|
haftmann@37660
|
610 |
because the latter is the same thm as the former *)
|
haftmann@37660
|
611 |
interpretation word_sint:
|
haftmann@37660
|
612 |
td_ext "sint ::'a::len word => int"
|
haftmann@37660
|
613 |
word_of_int
|
haftmann@37660
|
614 |
"sints (len_of TYPE('a::len))"
|
haftmann@37660
|
615 |
"%w. (w + 2^(len_of TYPE('a::len) - 1)) mod 2^len_of TYPE('a::len) -
|
haftmann@37660
|
616 |
2 ^ (len_of TYPE('a::len) - 1)"
|
haftmann@37660
|
617 |
by (rule td_ext_sint)
|
haftmann@37660
|
618 |
|
haftmann@37660
|
619 |
interpretation word_sbin:
|
haftmann@37660
|
620 |
td_ext "sint ::'a::len word => int"
|
haftmann@37660
|
621 |
word_of_int
|
haftmann@37660
|
622 |
"sints (len_of TYPE('a::len))"
|
haftmann@37660
|
623 |
"sbintrunc (len_of TYPE('a::len) - 1)"
|
haftmann@37660
|
624 |
by (rule td_ext_sbin)
|
haftmann@37660
|
625 |
|
wenzelm@45604
|
626 |
lemmas int_word_sint = td_ext_sint [THEN td_ext.eq_norm]
|
haftmann@37660
|
627 |
|
haftmann@37660
|
628 |
lemmas td_sint = word_sint.td
|
haftmann@37660
|
629 |
|
haftmann@37660
|
630 |
lemma to_bl_def':
|
haftmann@37660
|
631 |
"(to_bl :: 'a :: len0 word => bool list) =
|
haftmann@37660
|
632 |
bin_to_bl (len_of TYPE('a)) o uint"
|
wenzelm@44762
|
633 |
by (auto simp: to_bl_def)
|
haftmann@37660
|
634 |
|
huffman@47108
|
635 |
lemmas word_reverse_no_def [simp] = word_reverse_def [of "numeral w"] for w
|
haftmann@37660
|
636 |
|
huffman@45805
|
637 |
lemma uints_mod: "uints n = range (\<lambda>w. w mod 2 ^ n)"
|
huffman@45805
|
638 |
by (fact uints_def [unfolded no_bintr_alt1])
|
huffman@45805
|
639 |
|
huffman@47108
|
640 |
lemma word_numeral_alt:
|
huffman@47108
|
641 |
"numeral b = word_of_int (numeral b)"
|
huffman@47108
|
642 |
by (induct b, simp_all only: numeral.simps word_of_int_homs)
|
huffman@47108
|
643 |
|
huffman@47108
|
644 |
declare word_numeral_alt [symmetric, code_abbrev]
|
huffman@47108
|
645 |
|
huffman@47108
|
646 |
lemma word_neg_numeral_alt:
|
haftmann@54489
|
647 |
"- numeral b = word_of_int (- numeral b)"
|
haftmann@54489
|
648 |
by (simp only: word_numeral_alt wi_hom_neg)
|
huffman@47108
|
649 |
|
huffman@47108
|
650 |
declare word_neg_numeral_alt [symmetric, code_abbrev]
|
huffman@47108
|
651 |
|
huffman@47372
|
652 |
lemma word_numeral_transfer [transfer_rule]:
|
blanchet@55945
|
653 |
"(rel_fun op = pcr_word) numeral numeral"
|
blanchet@55945
|
654 |
"(rel_fun op = pcr_word) (- numeral) (- numeral)"
|
blanchet@55945
|
655 |
apply (simp_all add: rel_fun_def word.pcr_cr_eq cr_word_def)
|
haftmann@54489
|
656 |
using word_numeral_alt [symmetric] word_neg_numeral_alt [symmetric] by blast+
|
huffman@47372
|
657 |
|
huffman@45805
|
658 |
lemma uint_bintrunc [simp]:
|
huffman@47108
|
659 |
"uint (numeral bin :: 'a word) =
|
huffman@47108
|
660 |
bintrunc (len_of TYPE ('a :: len0)) (numeral bin)"
|
huffman@47108
|
661 |
unfolding word_numeral_alt by (rule word_ubin.eq_norm)
|
huffman@47108
|
662 |
|
haftmann@54489
|
663 |
lemma uint_bintrunc_neg [simp]: "uint (- numeral bin :: 'a word) =
|
haftmann@54489
|
664 |
bintrunc (len_of TYPE ('a :: len0)) (- numeral bin)"
|
huffman@47108
|
665 |
by (simp only: word_neg_numeral_alt word_ubin.eq_norm)
|
haftmann@37660
|
666 |
|
huffman@45805
|
667 |
lemma sint_sbintrunc [simp]:
|
huffman@47108
|
668 |
"sint (numeral bin :: 'a word) =
|
huffman@47108
|
669 |
sbintrunc (len_of TYPE ('a :: len) - 1) (numeral bin)"
|
huffman@47108
|
670 |
by (simp only: word_numeral_alt word_sbin.eq_norm)
|
huffman@47108
|
671 |
|
haftmann@54489
|
672 |
lemma sint_sbintrunc_neg [simp]: "sint (- numeral bin :: 'a word) =
|
haftmann@54489
|
673 |
sbintrunc (len_of TYPE ('a :: len) - 1) (- numeral bin)"
|
huffman@47108
|
674 |
by (simp only: word_neg_numeral_alt word_sbin.eq_norm)
|
haftmann@37660
|
675 |
|
huffman@45805
|
676 |
lemma unat_bintrunc [simp]:
|
huffman@47108
|
677 |
"unat (numeral bin :: 'a :: len0 word) =
|
huffman@47108
|
678 |
nat (bintrunc (len_of TYPE('a)) (numeral bin))"
|
huffman@47108
|
679 |
by (simp only: unat_def uint_bintrunc)
|
huffman@47108
|
680 |
|
huffman@47108
|
681 |
lemma unat_bintrunc_neg [simp]:
|
haftmann@54489
|
682 |
"unat (- numeral bin :: 'a :: len0 word) =
|
haftmann@54489
|
683 |
nat (bintrunc (len_of TYPE('a)) (- numeral bin))"
|
huffman@47108
|
684 |
by (simp only: unat_def uint_bintrunc_neg)
|
haftmann@37660
|
685 |
|
haftmann@40827
|
686 |
lemma size_0_eq: "size (w :: 'a :: len0 word) = 0 \<Longrightarrow> v = w"
|
haftmann@37660
|
687 |
apply (unfold word_size)
|
haftmann@37660
|
688 |
apply (rule word_uint.Rep_eqD)
|
haftmann@37660
|
689 |
apply (rule box_equals)
|
haftmann@37660
|
690 |
defer
|
haftmann@37660
|
691 |
apply (rule word_ubin.norm_Rep)+
|
haftmann@37660
|
692 |
apply simp
|
haftmann@37660
|
693 |
done
|
haftmann@37660
|
694 |
|
huffman@45805
|
695 |
lemma uint_ge_0 [iff]: "0 \<le> uint (x::'a::len0 word)"
|
huffman@45805
|
696 |
using word_uint.Rep [of x] by (simp add: uints_num)
|
huffman@45805
|
697 |
|
huffman@45805
|
698 |
lemma uint_lt2p [iff]: "uint (x::'a::len0 word) < 2 ^ len_of TYPE('a)"
|
huffman@45805
|
699 |
using word_uint.Rep [of x] by (simp add: uints_num)
|
huffman@45805
|
700 |
|
huffman@45805
|
701 |
lemma sint_ge: "- (2 ^ (len_of TYPE('a) - 1)) \<le> sint (x::'a::len word)"
|
huffman@45805
|
702 |
using word_sint.Rep [of x] by (simp add: sints_num)
|
huffman@45805
|
703 |
|
huffman@45805
|
704 |
lemma sint_lt: "sint (x::'a::len word) < 2 ^ (len_of TYPE('a) - 1)"
|
huffman@45805
|
705 |
using word_sint.Rep [of x] by (simp add: sints_num)
|
haftmann@37660
|
706 |
|
haftmann@37660
|
707 |
lemma sign_uint_Pls [simp]:
|
huffman@46604
|
708 |
"bin_sign (uint x) = 0"
|
huffman@47108
|
709 |
by (simp add: sign_Pls_ge_0)
|
haftmann@37660
|
710 |
|
huffman@45805
|
711 |
lemma uint_m2p_neg: "uint (x::'a::len0 word) - 2 ^ len_of TYPE('a) < 0"
|
huffman@45805
|
712 |
by (simp only: diff_less_0_iff_less uint_lt2p)
|
huffman@45805
|
713 |
|
huffman@45805
|
714 |
lemma uint_m2p_not_non_neg:
|
huffman@45805
|
715 |
"\<not> 0 \<le> uint (x::'a::len0 word) - 2 ^ len_of TYPE('a)"
|
huffman@45805
|
716 |
by (simp only: not_le uint_m2p_neg)
|
haftmann@37660
|
717 |
|
haftmann@37660
|
718 |
lemma lt2p_lem:
|
haftmann@55816
|
719 |
"len_of TYPE('a) \<le> n \<Longrightarrow> uint (w :: 'a::len0 word) < 2 ^ n"
|
haftmann@55816
|
720 |
by (metis bintr_uint bintrunc_mod2p int_mod_lem zless2p)
|
haftmann@37660
|
721 |
|
huffman@45805
|
722 |
lemma uint_le_0_iff [simp]: "uint x \<le> 0 \<longleftrightarrow> uint x = 0"
|
huffman@45805
|
723 |
by (fact uint_ge_0 [THEN leD, THEN linorder_antisym_conv1])
|
haftmann@37660
|
724 |
|
haftmann@40827
|
725 |
lemma uint_nat: "uint w = int (unat w)"
|
haftmann@37660
|
726 |
unfolding unat_def by auto
|
haftmann@37660
|
727 |
|
huffman@47108
|
728 |
lemma uint_numeral:
|
huffman@47108
|
729 |
"uint (numeral b :: 'a :: len0 word) = numeral b mod 2 ^ len_of TYPE('a)"
|
huffman@47108
|
730 |
unfolding word_numeral_alt
|
haftmann@37660
|
731 |
by (simp only: int_word_uint)
|
haftmann@37660
|
732 |
|
huffman@47108
|
733 |
lemma uint_neg_numeral:
|
haftmann@54489
|
734 |
"uint (- numeral b :: 'a :: len0 word) = - numeral b mod 2 ^ len_of TYPE('a)"
|
huffman@47108
|
735 |
unfolding word_neg_numeral_alt
|
huffman@47108
|
736 |
by (simp only: int_word_uint)
|
huffman@47108
|
737 |
|
huffman@47108
|
738 |
lemma unat_numeral:
|
huffman@47108
|
739 |
"unat (numeral b::'a::len0 word) = numeral b mod 2 ^ len_of TYPE ('a)"
|
haftmann@37660
|
740 |
apply (unfold unat_def)
|
huffman@47108
|
741 |
apply (clarsimp simp only: uint_numeral)
|
haftmann@37660
|
742 |
apply (rule nat_mod_distrib [THEN trans])
|
huffman@47108
|
743 |
apply (rule zero_le_numeral)
|
haftmann@37660
|
744 |
apply (simp_all add: nat_power_eq)
|
haftmann@37660
|
745 |
done
|
haftmann@37660
|
746 |
|
huffman@47108
|
747 |
lemma sint_numeral: "sint (numeral b :: 'a :: len word) = (numeral b +
|
haftmann@37660
|
748 |
2 ^ (len_of TYPE('a) - 1)) mod 2 ^ len_of TYPE('a) -
|
haftmann@37660
|
749 |
2 ^ (len_of TYPE('a) - 1)"
|
huffman@47108
|
750 |
unfolding word_numeral_alt by (rule int_word_sint)
|
huffman@47108
|
751 |
|
haftmann@55816
|
752 |
lemma word_of_int_0 [simp, code_post]:
|
haftmann@55816
|
753 |
"word_of_int 0 = 0"
|
huffman@45958
|
754 |
unfolding word_0_wi ..
|
huffman@45958
|
755 |
|
haftmann@55816
|
756 |
lemma word_of_int_1 [simp, code_post]:
|
haftmann@55816
|
757 |
"word_of_int 1 = 1"
|
huffman@45958
|
758 |
unfolding word_1_wi ..
|
huffman@45958
|
759 |
|
haftmann@54489
|
760 |
lemma word_of_int_neg_1 [simp]: "word_of_int (- 1) = - 1"
|
haftmann@54489
|
761 |
by (simp add: wi_hom_syms)
|
haftmann@54489
|
762 |
|
huffman@47108
|
763 |
lemma word_of_int_numeral [simp] :
|
huffman@47108
|
764 |
"(word_of_int (numeral bin) :: 'a :: len0 word) = (numeral bin)"
|
huffman@47108
|
765 |
unfolding word_numeral_alt ..
|
huffman@47108
|
766 |
|
huffman@47108
|
767 |
lemma word_of_int_neg_numeral [simp]:
|
haftmann@54489
|
768 |
"(word_of_int (- numeral bin) :: 'a :: len0 word) = (- numeral bin)"
|
haftmann@54489
|
769 |
unfolding word_numeral_alt wi_hom_syms ..
|
haftmann@37660
|
770 |
|
haftmann@37660
|
771 |
lemma word_int_case_wi:
|
haftmann@37660
|
772 |
"word_int_case f (word_of_int i :: 'b word) =
|
haftmann@37660
|
773 |
f (i mod 2 ^ len_of TYPE('b::len0))"
|
haftmann@37660
|
774 |
unfolding word_int_case_def by (simp add: word_uint.eq_norm)
|
haftmann@37660
|
775 |
|
haftmann@37660
|
776 |
lemma word_int_split:
|
haftmann@37660
|
777 |
"P (word_int_case f x) =
|
haftmann@37660
|
778 |
(ALL i. x = (word_of_int i :: 'b :: len0 word) &
|
haftmann@37660
|
779 |
0 <= i & i < 2 ^ len_of TYPE('b) --> P (f i))"
|
haftmann@37660
|
780 |
unfolding word_int_case_def
|
haftmann@55816
|
781 |
by (auto simp: word_uint.eq_norm mod_pos_pos_trivial)
|
haftmann@37660
|
782 |
|
haftmann@37660
|
783 |
lemma word_int_split_asm:
|
haftmann@37660
|
784 |
"P (word_int_case f x) =
|
haftmann@37660
|
785 |
(~ (EX n. x = (word_of_int n :: 'b::len0 word) &
|
haftmann@37660
|
786 |
0 <= n & n < 2 ^ len_of TYPE('b::len0) & ~ P (f n)))"
|
haftmann@37660
|
787 |
unfolding word_int_case_def
|
haftmann@55816
|
788 |
by (auto simp: word_uint.eq_norm mod_pos_pos_trivial)
|
huffman@45805
|
789 |
|
wenzelm@45604
|
790 |
lemmas uint_range' = word_uint.Rep [unfolded uints_num mem_Collect_eq]
|
wenzelm@45604
|
791 |
lemmas sint_range' = word_sint.Rep [unfolded One_nat_def sints_num mem_Collect_eq]
|
haftmann@37660
|
792 |
|
haftmann@37660
|
793 |
lemma uint_range_size: "0 <= uint w & uint w < 2 ^ size w"
|
haftmann@37660
|
794 |
unfolding word_size by (rule uint_range')
|
haftmann@37660
|
795 |
|
haftmann@37660
|
796 |
lemma sint_range_size:
|
haftmann@37660
|
797 |
"- (2 ^ (size w - Suc 0)) <= sint w & sint w < 2 ^ (size w - Suc 0)"
|
haftmann@37660
|
798 |
unfolding word_size by (rule sint_range')
|
haftmann@37660
|
799 |
|
huffman@45805
|
800 |
lemma sint_above_size: "2 ^ (size (w::'a::len word) - 1) \<le> x \<Longrightarrow> sint w < x"
|
huffman@45805
|
801 |
unfolding word_size by (rule less_le_trans [OF sint_lt])
|
huffman@45805
|
802 |
|
huffman@45805
|
803 |
lemma sint_below_size:
|
huffman@45805
|
804 |
"x \<le> - (2 ^ (size (w::'a::len word) - 1)) \<Longrightarrow> x \<le> sint w"
|
huffman@45805
|
805 |
unfolding word_size by (rule order_trans [OF _ sint_ge])
|
haftmann@37660
|
806 |
|
haftmann@55816
|
807 |
|
wenzelm@61799
|
808 |
subsection \<open>Testing bits\<close>
|
huffman@46010
|
809 |
|
haftmann@37660
|
810 |
lemma test_bit_eq_iff: "(test_bit (u::'a::len0 word) = test_bit v) = (u = v)"
|
haftmann@37660
|
811 |
unfolding word_test_bit_def by (simp add: bin_nth_eq_iff)
|
haftmann@37660
|
812 |
|
haftmann@37660
|
813 |
lemma test_bit_size [rule_format] : "(w::'a::len0 word) !! n --> n < size w"
|
haftmann@37660
|
814 |
apply (unfold word_test_bit_def)
|
haftmann@37660
|
815 |
apply (subst word_ubin.norm_Rep [symmetric])
|
haftmann@37660
|
816 |
apply (simp only: nth_bintr word_size)
|
haftmann@37660
|
817 |
apply fast
|
haftmann@37660
|
818 |
done
|
haftmann@37660
|
819 |
|
huffman@46021
|
820 |
lemma word_eq_iff:
|
huffman@46021
|
821 |
fixes x y :: "'a::len0 word"
|
huffman@46021
|
822 |
shows "x = y \<longleftrightarrow> (\<forall>n<len_of TYPE('a). x !! n = y !! n)"
|
huffman@46021
|
823 |
unfolding uint_inject [symmetric] bin_eq_iff word_test_bit_def [symmetric]
|
huffman@46021
|
824 |
by (metis test_bit_size [unfolded word_size])
|
huffman@46021
|
825 |
|
huffman@46023
|
826 |
lemma word_eqI [rule_format]:
|
haftmann@37660
|
827 |
fixes u :: "'a::len0 word"
|
haftmann@40827
|
828 |
shows "(ALL n. n < size u --> u !! n = v !! n) \<Longrightarrow> u = v"
|
huffman@46021
|
829 |
by (simp add: word_size word_eq_iff)
|
haftmann@37660
|
830 |
|
huffman@45805
|
831 |
lemma word_eqD: "(u::'a::len0 word) = v \<Longrightarrow> u !! x = v !! x"
|
huffman@45805
|
832 |
by simp
|
haftmann@37660
|
833 |
|
haftmann@37660
|
834 |
lemma test_bit_bin': "w !! n = (n < size w & bin_nth (uint w) n)"
|
haftmann@37660
|
835 |
unfolding word_test_bit_def word_size
|
haftmann@37660
|
836 |
by (simp add: nth_bintr [symmetric])
|
haftmann@37660
|
837 |
|
haftmann@37660
|
838 |
lemmas test_bit_bin = test_bit_bin' [unfolded word_size]
|
haftmann@37660
|
839 |
|
huffman@46057
|
840 |
lemma bin_nth_uint_imp:
|
huffman@46057
|
841 |
"bin_nth (uint (w::'a::len0 word)) n \<Longrightarrow> n < len_of TYPE('a)"
|
haftmann@37660
|
842 |
apply (rule nth_bintr [THEN iffD1, THEN conjunct1])
|
haftmann@37660
|
843 |
apply (subst word_ubin.norm_Rep)
|
haftmann@37660
|
844 |
apply assumption
|
haftmann@37660
|
845 |
done
|
haftmann@37660
|
846 |
|
huffman@46057
|
847 |
lemma bin_nth_sint:
|
huffman@46057
|
848 |
fixes w :: "'a::len word"
|
huffman@46057
|
849 |
shows "len_of TYPE('a) \<le> n \<Longrightarrow>
|
huffman@46057
|
850 |
bin_nth (sint w) n = bin_nth (sint w) (len_of TYPE('a) - 1)"
|
haftmann@37660
|
851 |
apply (subst word_sbin.norm_Rep [symmetric])
|
huffman@46057
|
852 |
apply (auto simp add: nth_sbintr)
|
haftmann@37660
|
853 |
done
|
haftmann@37660
|
854 |
|
haftmann@37660
|
855 |
(* type definitions theorem for in terms of equivalent bool list *)
|
haftmann@37660
|
856 |
lemma td_bl:
|
haftmann@37660
|
857 |
"type_definition (to_bl :: 'a::len0 word => bool list)
|
haftmann@37660
|
858 |
of_bl
|
haftmann@37660
|
859 |
{bl. length bl = len_of TYPE('a)}"
|
haftmann@37660
|
860 |
apply (unfold type_definition_def of_bl_def to_bl_def)
|
haftmann@37660
|
861 |
apply (simp add: word_ubin.eq_norm)
|
haftmann@37660
|
862 |
apply safe
|
haftmann@37660
|
863 |
apply (drule sym)
|
haftmann@37660
|
864 |
apply simp
|
haftmann@37660
|
865 |
done
|
haftmann@37660
|
866 |
|
haftmann@37660
|
867 |
interpretation word_bl:
|
haftmann@37660
|
868 |
type_definition "to_bl :: 'a::len0 word => bool list"
|
haftmann@37660
|
869 |
of_bl
|
haftmann@37660
|
870 |
"{bl. length bl = len_of TYPE('a::len0)}"
|
haftmann@55816
|
871 |
by (fact td_bl)
|
haftmann@37660
|
872 |
|
huffman@45816
|
873 |
lemmas word_bl_Rep' = word_bl.Rep [unfolded mem_Collect_eq, iff]
|
wenzelm@45538
|
874 |
|
haftmann@40827
|
875 |
lemma word_size_bl: "size w = size (to_bl w)"
|
haftmann@37660
|
876 |
unfolding word_size by auto
|
haftmann@37660
|
877 |
|
haftmann@37660
|
878 |
lemma to_bl_use_of_bl:
|
haftmann@37660
|
879 |
"(to_bl w = bl) = (w = of_bl bl \<and> length bl = length (to_bl w))"
|
huffman@45816
|
880 |
by (fastforce elim!: word_bl.Abs_inverse [unfolded mem_Collect_eq])
|
haftmann@37660
|
881 |
|
haftmann@37660
|
882 |
lemma to_bl_word_rev: "to_bl (word_reverse w) = rev (to_bl w)"
|
haftmann@37660
|
883 |
unfolding word_reverse_def by (simp add: word_bl.Abs_inverse)
|
haftmann@37660
|
884 |
|
haftmann@37660
|
885 |
lemma word_rev_rev [simp] : "word_reverse (word_reverse w) = w"
|
haftmann@37660
|
886 |
unfolding word_reverse_def by (simp add : word_bl.Abs_inverse)
|
haftmann@37660
|
887 |
|
haftmann@40827
|
888 |
lemma word_rev_gal: "word_reverse w = u \<Longrightarrow> word_reverse u = w"
|
huffman@47108
|
889 |
by (metis word_rev_rev)
|
haftmann@37660
|
890 |
|
huffman@45805
|
891 |
lemma word_rev_gal': "u = word_reverse w \<Longrightarrow> w = word_reverse u"
|
huffman@45805
|
892 |
by simp
|
huffman@45805
|
893 |
|
huffman@45805
|
894 |
lemma length_bl_gt_0 [iff]: "0 < length (to_bl (x::'a::len word))"
|
huffman@45805
|
895 |
unfolding word_bl_Rep' by (rule len_gt_0)
|
huffman@45805
|
896 |
|
huffman@45805
|
897 |
lemma bl_not_Nil [iff]: "to_bl (x::'a::len word) \<noteq> []"
|
huffman@45805
|
898 |
by (fact length_bl_gt_0 [unfolded length_greater_0_conv])
|
huffman@45805
|
899 |
|
huffman@45805
|
900 |
lemma length_bl_neq_0 [iff]: "length (to_bl (x::'a::len word)) \<noteq> 0"
|
huffman@45805
|
901 |
by (fact length_bl_gt_0 [THEN gr_implies_not0])
|
haftmann@37660
|
902 |
|
huffman@46001
|
903 |
lemma hd_bl_sign_sint: "hd (to_bl w) = (bin_sign (sint w) = -1)"
|
haftmann@37660
|
904 |
apply (unfold to_bl_def sint_uint)
|
haftmann@37660
|
905 |
apply (rule trans [OF _ bl_sbin_sign])
|
haftmann@37660
|
906 |
apply simp
|
haftmann@37660
|
907 |
done
|
haftmann@37660
|
908 |
|
haftmann@37660
|
909 |
lemma of_bl_drop':
|
haftmann@40827
|
910 |
"lend = length bl - len_of TYPE ('a :: len0) \<Longrightarrow>
|
haftmann@37660
|
911 |
of_bl (drop lend bl) = (of_bl bl :: 'a word)"
|
haftmann@37660
|
912 |
apply (unfold of_bl_def)
|
haftmann@37660
|
913 |
apply (clarsimp simp add : trunc_bl2bin [symmetric])
|
haftmann@37660
|
914 |
done
|
haftmann@37660
|
915 |
|
haftmann@37660
|
916 |
lemma test_bit_of_bl:
|
haftmann@37660
|
917 |
"(of_bl bl::'a::len0 word) !! n = (rev bl ! n \<and> n < len_of TYPE('a) \<and> n < length bl)"
|
haftmann@37660
|
918 |
apply (unfold of_bl_def word_test_bit_def)
|
haftmann@37660
|
919 |
apply (auto simp add: word_size word_ubin.eq_norm nth_bintr bin_nth_of_bl)
|
haftmann@37660
|
920 |
done
|
haftmann@37660
|
921 |
|
haftmann@37660
|
922 |
lemma no_of_bl:
|
huffman@47108
|
923 |
"(numeral bin ::'a::len0 word) = of_bl (bin_to_bl (len_of TYPE ('a)) (numeral bin))"
|
huffman@47108
|
924 |
unfolding of_bl_def by simp
|
haftmann@37660
|
925 |
|
haftmann@40827
|
926 |
lemma uint_bl: "to_bl w = bin_to_bl (size w) (uint w)"
|
haftmann@37660
|
927 |
unfolding word_size to_bl_def by auto
|
haftmann@37660
|
928 |
|
haftmann@37660
|
929 |
lemma to_bl_bin: "bl_to_bin (to_bl w) = uint w"
|
haftmann@37660
|
930 |
unfolding uint_bl by (simp add : word_size)
|
haftmann@37660
|
931 |
|
haftmann@37660
|
932 |
lemma to_bl_of_bin:
|
haftmann@37660
|
933 |
"to_bl (word_of_int bin::'a::len0 word) = bin_to_bl (len_of TYPE('a)) bin"
|
haftmann@37660
|
934 |
unfolding uint_bl by (clarsimp simp add: word_ubin.eq_norm word_size)
|
haftmann@37660
|
935 |
|
huffman@47108
|
936 |
lemma to_bl_numeral [simp]:
|
huffman@47108
|
937 |
"to_bl (numeral bin::'a::len0 word) =
|
huffman@47108
|
938 |
bin_to_bl (len_of TYPE('a)) (numeral bin)"
|
huffman@47108
|
939 |
unfolding word_numeral_alt by (rule to_bl_of_bin)
|
huffman@47108
|
940 |
|
huffman@47108
|
941 |
lemma to_bl_neg_numeral [simp]:
|
haftmann@54489
|
942 |
"to_bl (- numeral bin::'a::len0 word) =
|
haftmann@54489
|
943 |
bin_to_bl (len_of TYPE('a)) (- numeral bin)"
|
huffman@47108
|
944 |
unfolding word_neg_numeral_alt by (rule to_bl_of_bin)
|
haftmann@37660
|
945 |
|
haftmann@37660
|
946 |
lemma to_bl_to_bin [simp] : "bl_to_bin (to_bl w) = uint w"
|
haftmann@37660
|
947 |
unfolding uint_bl by (simp add : word_size)
|
huffman@46011
|
948 |
|
huffman@46011
|
949 |
lemma uint_bl_bin:
|
huffman@46011
|
950 |
fixes x :: "'a::len0 word"
|
huffman@46011
|
951 |
shows "bl_to_bin (bin_to_bl (len_of TYPE('a)) (uint x)) = uint x"
|
huffman@46011
|
952 |
by (rule trans [OF bin_bl_bin word_ubin.norm_Rep])
|
wenzelm@45604
|
953 |
|
haftmann@37660
|
954 |
(* naturals *)
|
haftmann@37660
|
955 |
lemma uints_unats: "uints n = int ` unats n"
|
haftmann@37660
|
956 |
apply (unfold unats_def uints_num)
|
haftmann@37660
|
957 |
apply safe
|
haftmann@37660
|
958 |
apply (rule_tac image_eqI)
|
haftmann@37660
|
959 |
apply (erule_tac nat_0_le [symmetric])
|
haftmann@37660
|
960 |
apply auto
|
haftmann@37660
|
961 |
apply (erule_tac nat_less_iff [THEN iffD2])
|
haftmann@37660
|
962 |
apply (rule_tac [2] zless_nat_eq_int_zless [THEN iffD1])
|
lp15@61649
|
963 |
apply (auto simp add : nat_power_eq of_nat_power)
|
haftmann@37660
|
964 |
done
|
haftmann@37660
|
965 |
|
haftmann@37660
|
966 |
lemma unats_uints: "unats n = nat ` uints n"
|
haftmann@37660
|
967 |
by (auto simp add : uints_unats image_iff)
|
haftmann@37660
|
968 |
|
huffman@46962
|
969 |
lemmas bintr_num = word_ubin.norm_eq_iff
|
huffman@47108
|
970 |
[of "numeral a" "numeral b", symmetric, folded word_numeral_alt] for a b
|
huffman@46962
|
971 |
lemmas sbintr_num = word_sbin.norm_eq_iff
|
huffman@47108
|
972 |
[of "numeral a" "numeral b", symmetric, folded word_numeral_alt] for a b
|
haftmann@37660
|
973 |
|
haftmann@37660
|
974 |
lemma num_of_bintr':
|
huffman@47108
|
975 |
"bintrunc (len_of TYPE('a :: len0)) (numeral a) = (numeral b) \<Longrightarrow>
|
huffman@47108
|
976 |
numeral a = (numeral b :: 'a word)"
|
huffman@46962
|
977 |
unfolding bintr_num by (erule subst, simp)
|
haftmann@37660
|
978 |
|
haftmann@37660
|
979 |
lemma num_of_sbintr':
|
huffman@47108
|
980 |
"sbintrunc (len_of TYPE('a :: len) - 1) (numeral a) = (numeral b) \<Longrightarrow>
|
huffman@47108
|
981 |
numeral a = (numeral b :: 'a word)"
|
huffman@46962
|
982 |
unfolding sbintr_num by (erule subst, simp)
|
huffman@46962
|
983 |
|
huffman@46962
|
984 |
lemma num_abs_bintr:
|
huffman@47108
|
985 |
"(numeral x :: 'a word) =
|
huffman@47108
|
986 |
word_of_int (bintrunc (len_of TYPE('a::len0)) (numeral x))"
|
huffman@47108
|
987 |
by (simp only: word_ubin.Abs_norm word_numeral_alt)
|
huffman@46962
|
988 |
|
huffman@46962
|
989 |
lemma num_abs_sbintr:
|
huffman@47108
|
990 |
"(numeral x :: 'a word) =
|
huffman@47108
|
991 |
word_of_int (sbintrunc (len_of TYPE('a::len) - 1) (numeral x))"
|
huffman@47108
|
992 |
by (simp only: word_sbin.Abs_norm word_numeral_alt)
|
huffman@46962
|
993 |
|
haftmann@37660
|
994 |
(** cast - note, no arg for new length, as it's determined by type of result,
|
haftmann@37660
|
995 |
thus in "cast w = w, the type means cast to length of w! **)
|
haftmann@37660
|
996 |
|
haftmann@37660
|
997 |
lemma ucast_id: "ucast w = w"
|
haftmann@37660
|
998 |
unfolding ucast_def by auto
|
haftmann@37660
|
999 |
|
haftmann@37660
|
1000 |
lemma scast_id: "scast w = w"
|
haftmann@37660
|
1001 |
unfolding scast_def by auto
|
haftmann@37660
|
1002 |
|
haftmann@40827
|
1003 |
lemma ucast_bl: "ucast w = of_bl (to_bl w)"
|
haftmann@37660
|
1004 |
unfolding ucast_def of_bl_def uint_bl
|
haftmann@37660
|
1005 |
by (auto simp add : word_size)
|
haftmann@37660
|
1006 |
|
haftmann@37660
|
1007 |
lemma nth_ucast:
|
haftmann@37660
|
1008 |
"(ucast w::'a::len0 word) !! n = (w !! n & n < len_of TYPE('a))"
|
haftmann@37660
|
1009 |
apply (unfold ucast_def test_bit_bin)
|
haftmann@37660
|
1010 |
apply (simp add: word_ubin.eq_norm nth_bintr word_size)
|
haftmann@37660
|
1011 |
apply (fast elim!: bin_nth_uint_imp)
|
haftmann@37660
|
1012 |
done
|
haftmann@37660
|
1013 |
|
haftmann@37660
|
1014 |
(* for literal u(s)cast *)
|
haftmann@37660
|
1015 |
|
huffman@46001
|
1016 |
lemma ucast_bintr [simp]:
|
huffman@47108
|
1017 |
"ucast (numeral w ::'a::len0 word) =
|
huffman@47108
|
1018 |
word_of_int (bintrunc (len_of TYPE('a)) (numeral w))"
|
haftmann@37660
|
1019 |
unfolding ucast_def by simp
|
huffman@47108
|
1020 |
(* TODO: neg_numeral *)
|
haftmann@37660
|
1021 |
|
huffman@46001
|
1022 |
lemma scast_sbintr [simp]:
|
huffman@47108
|
1023 |
"scast (numeral w ::'a::len word) =
|
huffman@47108
|
1024 |
word_of_int (sbintrunc (len_of TYPE('a) - Suc 0) (numeral w))"
|
haftmann@37660
|
1025 |
unfolding scast_def by simp
|
haftmann@37660
|
1026 |
|
huffman@46011
|
1027 |
lemma source_size: "source_size (c::'a::len0 word \<Rightarrow> _) = len_of TYPE('a)"
|
huffman@46011
|
1028 |
unfolding source_size_def word_size Let_def ..
|
huffman@46011
|
1029 |
|
huffman@46011
|
1030 |
lemma target_size: "target_size (c::_ \<Rightarrow> 'b::len0 word) = len_of TYPE('b)"
|
huffman@46011
|
1031 |
unfolding target_size_def word_size Let_def ..
|
huffman@46011
|
1032 |
|
huffman@46011
|
1033 |
lemma is_down:
|
huffman@46011
|
1034 |
fixes c :: "'a::len0 word \<Rightarrow> 'b::len0 word"
|
huffman@46011
|
1035 |
shows "is_down c \<longleftrightarrow> len_of TYPE('b) \<le> len_of TYPE('a)"
|
huffman@46011
|
1036 |
unfolding is_down_def source_size target_size ..
|
huffman@46011
|
1037 |
|
huffman@46011
|
1038 |
lemma is_up:
|
huffman@46011
|
1039 |
fixes c :: "'a::len0 word \<Rightarrow> 'b::len0 word"
|
huffman@46011
|
1040 |
shows "is_up c \<longleftrightarrow> len_of TYPE('a) \<le> len_of TYPE('b)"
|
huffman@46011
|
1041 |
unfolding is_up_def source_size target_size ..
|
haftmann@37660
|
1042 |
|
wenzelm@45604
|
1043 |
lemmas is_up_down = trans [OF is_up is_down [symmetric]]
|
haftmann@37660
|
1044 |
|
huffman@45811
|
1045 |
lemma down_cast_same [OF refl]: "uc = ucast \<Longrightarrow> is_down uc \<Longrightarrow> uc = scast"
|
haftmann@37660
|
1046 |
apply (unfold is_down)
|
haftmann@37660
|
1047 |
apply safe
|
haftmann@37660
|
1048 |
apply (rule ext)
|
haftmann@37660
|
1049 |
apply (unfold ucast_def scast_def uint_sint)
|
haftmann@37660
|
1050 |
apply (rule word_ubin.norm_eq_iff [THEN iffD1])
|
haftmann@37660
|
1051 |
apply simp
|
haftmann@37660
|
1052 |
done
|
haftmann@37660
|
1053 |
|
huffman@45811
|
1054 |
lemma word_rev_tf:
|
huffman@45811
|
1055 |
"to_bl (of_bl bl::'a::len0 word) =
|
huffman@45811
|
1056 |
rev (takefill False (len_of TYPE('a)) (rev bl))"
|
haftmann@37660
|
1057 |
unfolding of_bl_def uint_bl
|
haftmann@37660
|
1058 |
by (clarsimp simp add: bl_bin_bl_rtf word_ubin.eq_norm word_size)
|
haftmann@37660
|
1059 |
|
huffman@45811
|
1060 |
lemma word_rep_drop:
|
huffman@45811
|
1061 |
"to_bl (of_bl bl::'a::len0 word) =
|
huffman@45811
|
1062 |
replicate (len_of TYPE('a) - length bl) False @
|
huffman@45811
|
1063 |
drop (length bl - len_of TYPE('a)) bl"
|
huffman@45811
|
1064 |
by (simp add: word_rev_tf takefill_alt rev_take)
|
haftmann@37660
|
1065 |
|
haftmann@37660
|
1066 |
lemma to_bl_ucast:
|
haftmann@37660
|
1067 |
"to_bl (ucast (w::'b::len0 word) ::'a::len0 word) =
|
haftmann@37660
|
1068 |
replicate (len_of TYPE('a) - len_of TYPE('b)) False @
|
haftmann@37660
|
1069 |
drop (len_of TYPE('b) - len_of TYPE('a)) (to_bl w)"
|
haftmann@37660
|
1070 |
apply (unfold ucast_bl)
|
haftmann@37660
|
1071 |
apply (rule trans)
|
haftmann@37660
|
1072 |
apply (rule word_rep_drop)
|
haftmann@37660
|
1073 |
apply simp
|
haftmann@37660
|
1074 |
done
|
haftmann@37660
|
1075 |
|
huffman@45811
|
1076 |
lemma ucast_up_app [OF refl]:
|
haftmann@40827
|
1077 |
"uc = ucast \<Longrightarrow> source_size uc + n = target_size uc \<Longrightarrow>
|
haftmann@37660
|
1078 |
to_bl (uc w) = replicate n False @ (to_bl w)"
|
haftmann@37660
|
1079 |
by (auto simp add : source_size target_size to_bl_ucast)
|
haftmann@37660
|
1080 |
|
huffman@45811
|
1081 |
lemma ucast_down_drop [OF refl]:
|
haftmann@40827
|
1082 |
"uc = ucast \<Longrightarrow> source_size uc = target_size uc + n \<Longrightarrow>
|
haftmann@37660
|
1083 |
to_bl (uc w) = drop n (to_bl w)"
|
haftmann@37660
|
1084 |
by (auto simp add : source_size target_size to_bl_ucast)
|
haftmann@37660
|
1085 |
|
huffman@45811
|
1086 |
lemma scast_down_drop [OF refl]:
|
haftmann@40827
|
1087 |
"sc = scast \<Longrightarrow> source_size sc = target_size sc + n \<Longrightarrow>
|
haftmann@37660
|
1088 |
to_bl (sc w) = drop n (to_bl w)"
|
haftmann@37660
|
1089 |
apply (subgoal_tac "sc = ucast")
|
haftmann@37660
|
1090 |
apply safe
|
haftmann@37660
|
1091 |
apply simp
|
huffman@45811
|
1092 |
apply (erule ucast_down_drop)
|
huffman@45811
|
1093 |
apply (rule down_cast_same [symmetric])
|
haftmann@37660
|
1094 |
apply (simp add : source_size target_size is_down)
|
haftmann@37660
|
1095 |
done
|
haftmann@37660
|
1096 |
|
huffman@45811
|
1097 |
lemma sint_up_scast [OF refl]:
|
haftmann@40827
|
1098 |
"sc = scast \<Longrightarrow> is_up sc \<Longrightarrow> sint (sc w) = sint w"
|
haftmann@37660
|
1099 |
apply (unfold is_up)
|
haftmann@37660
|
1100 |
apply safe
|
haftmann@37660
|
1101 |
apply (simp add: scast_def word_sbin.eq_norm)
|
haftmann@37660
|
1102 |
apply (rule box_equals)
|
haftmann@37660
|
1103 |
prefer 3
|
haftmann@37660
|
1104 |
apply (rule word_sbin.norm_Rep)
|
haftmann@37660
|
1105 |
apply (rule sbintrunc_sbintrunc_l)
|
haftmann@37660
|
1106 |
defer
|
haftmann@37660
|
1107 |
apply (subst word_sbin.norm_Rep)
|
haftmann@37660
|
1108 |
apply (rule refl)
|
haftmann@37660
|
1109 |
apply simp
|
haftmann@37660
|
1110 |
done
|
haftmann@37660
|
1111 |
|
huffman@45811
|
1112 |
lemma uint_up_ucast [OF refl]:
|
haftmann@40827
|
1113 |
"uc = ucast \<Longrightarrow> is_up uc \<Longrightarrow> uint (uc w) = uint w"
|
haftmann@37660
|
1114 |
apply (unfold is_up)
|
haftmann@37660
|
1115 |
apply safe
|
haftmann@37660
|
1116 |
apply (rule bin_eqI)
|
haftmann@37660
|
1117 |
apply (fold word_test_bit_def)
|
haftmann@37660
|
1118 |
apply (auto simp add: nth_ucast)
|
haftmann@37660
|
1119 |
apply (auto simp add: test_bit_bin)
|
haftmann@37660
|
1120 |
done
|
huffman@45811
|
1121 |
|
huffman@45811
|
1122 |
lemma ucast_up_ucast [OF refl]:
|
huffman@45811
|
1123 |
"uc = ucast \<Longrightarrow> is_up uc \<Longrightarrow> ucast (uc w) = ucast w"
|
haftmann@37660
|
1124 |
apply (simp (no_asm) add: ucast_def)
|
haftmann@37660
|
1125 |
apply (clarsimp simp add: uint_up_ucast)
|
haftmann@37660
|
1126 |
done
|
haftmann@37660
|
1127 |
|
huffman@45811
|
1128 |
lemma scast_up_scast [OF refl]:
|
huffman@45811
|
1129 |
"sc = scast \<Longrightarrow> is_up sc \<Longrightarrow> scast (sc w) = scast w"
|
haftmann@37660
|
1130 |
apply (simp (no_asm) add: scast_def)
|
haftmann@37660
|
1131 |
apply (clarsimp simp add: sint_up_scast)
|
haftmann@37660
|
1132 |
done
|
haftmann@37660
|
1133 |
|
huffman@45811
|
1134 |
lemma ucast_of_bl_up [OF refl]:
|
haftmann@40827
|
1135 |
"w = of_bl bl \<Longrightarrow> size bl <= size w \<Longrightarrow> ucast w = of_bl bl"
|
haftmann@37660
|
1136 |
by (auto simp add : nth_ucast word_size test_bit_of_bl intro!: word_eqI)
|
haftmann@37660
|
1137 |
|
haftmann@37660
|
1138 |
lemmas ucast_up_ucast_id = trans [OF ucast_up_ucast ucast_id]
|
haftmann@37660
|
1139 |
lemmas scast_up_scast_id = trans [OF scast_up_scast scast_id]
|
haftmann@37660
|
1140 |
|
haftmann@37660
|
1141 |
lemmas isduu = is_up_down [where c = "ucast", THEN iffD2]
|
haftmann@37660
|
1142 |
lemmas isdus = is_up_down [where c = "scast", THEN iffD2]
|
haftmann@37660
|
1143 |
lemmas ucast_down_ucast_id = isduu [THEN ucast_up_ucast_id]
|
haftmann@37660
|
1144 |
lemmas scast_down_scast_id = isdus [THEN ucast_up_ucast_id]
|
haftmann@37660
|
1145 |
|
haftmann@37660
|
1146 |
lemma up_ucast_surj:
|
haftmann@40827
|
1147 |
"is_up (ucast :: 'b::len0 word => 'a::len0 word) \<Longrightarrow>
|
haftmann@37660
|
1148 |
surj (ucast :: 'a word => 'b word)"
|
haftmann@37660
|
1149 |
by (rule surjI, erule ucast_up_ucast_id)
|
haftmann@37660
|
1150 |
|
haftmann@37660
|
1151 |
lemma up_scast_surj:
|
haftmann@40827
|
1152 |
"is_up (scast :: 'b::len word => 'a::len word) \<Longrightarrow>
|
haftmann@37660
|
1153 |
surj (scast :: 'a word => 'b word)"
|
haftmann@37660
|
1154 |
by (rule surjI, erule scast_up_scast_id)
|
haftmann@37660
|
1155 |
|
haftmann@37660
|
1156 |
lemma down_scast_inj:
|
haftmann@40827
|
1157 |
"is_down (scast :: 'b::len word => 'a::len word) \<Longrightarrow>
|
haftmann@37660
|
1158 |
inj_on (ucast :: 'a word => 'b word) A"
|
haftmann@37660
|
1159 |
by (rule inj_on_inverseI, erule scast_down_scast_id)
|
haftmann@37660
|
1160 |
|
haftmann@37660
|
1161 |
lemma down_ucast_inj:
|
haftmann@40827
|
1162 |
"is_down (ucast :: 'b::len0 word => 'a::len0 word) \<Longrightarrow>
|
haftmann@37660
|
1163 |
inj_on (ucast :: 'a word => 'b word) A"
|
haftmann@37660
|
1164 |
by (rule inj_on_inverseI, erule ucast_down_ucast_id)
|
haftmann@37660
|
1165 |
|
haftmann@37660
|
1166 |
lemma of_bl_append_same: "of_bl (X @ to_bl w) = w"
|
haftmann@37660
|
1167 |
by (rule word_bl.Rep_eqD) (simp add: word_rep_drop)
|
huffman@45811
|
1168 |
|
huffman@46646
|
1169 |
lemma ucast_down_wi [OF refl]:
|
huffman@46646
|
1170 |
"uc = ucast \<Longrightarrow> is_down uc \<Longrightarrow> uc (word_of_int x) = word_of_int x"
|
huffman@46646
|
1171 |
apply (unfold is_down)
|
haftmann@37660
|
1172 |
apply (clarsimp simp add: ucast_def word_ubin.eq_norm)
|
haftmann@37660
|
1173 |
apply (rule word_ubin.norm_eq_iff [THEN iffD1])
|
haftmann@37660
|
1174 |
apply (erule bintrunc_bintrunc_ge)
|
haftmann@37660
|
1175 |
done
|
huffman@45811
|
1176 |
|
huffman@46646
|
1177 |
lemma ucast_down_no [OF refl]:
|
huffman@47108
|
1178 |
"uc = ucast \<Longrightarrow> is_down uc \<Longrightarrow> uc (numeral bin) = numeral bin"
|
huffman@47108
|
1179 |
unfolding word_numeral_alt by clarify (rule ucast_down_wi)
|
huffman@46646
|
1180 |
|
huffman@45811
|
1181 |
lemma ucast_down_bl [OF refl]:
|
huffman@45811
|
1182 |
"uc = ucast \<Longrightarrow> is_down uc \<Longrightarrow> uc (of_bl bl) = of_bl bl"
|
huffman@46646
|
1183 |
unfolding of_bl_def by clarify (erule ucast_down_wi)
|
haftmann@37660
|
1184 |
|
haftmann@37660
|
1185 |
lemmas slice_def' = slice_def [unfolded word_size]
|
haftmann@37660
|
1186 |
lemmas test_bit_def' = word_test_bit_def [THEN fun_cong]
|
haftmann@37660
|
1187 |
|
haftmann@37660
|
1188 |
lemmas word_log_defs = word_and_def word_or_def word_xor_def word_not_def
|
haftmann@37660
|
1189 |
|
haftmann@37660
|
1190 |
|
wenzelm@61799
|
1191 |
subsection \<open>Word Arithmetic\<close>
|
haftmann@37660
|
1192 |
|
haftmann@37660
|
1193 |
lemma word_less_alt: "(a < b) = (uint a < uint b)"
|
haftmann@55818
|
1194 |
by (fact word_less_def)
|
haftmann@37660
|
1195 |
|
haftmann@37660
|
1196 |
lemma signed_linorder: "class.linorder word_sle word_sless"
|
wenzelm@61169
|
1197 |
by standard (unfold word_sle_def word_sless_def, auto)
|
haftmann@37660
|
1198 |
|
haftmann@37660
|
1199 |
interpretation signed: linorder "word_sle" "word_sless"
|
haftmann@37660
|
1200 |
by (rule signed_linorder)
|
haftmann@37660
|
1201 |
|
haftmann@37660
|
1202 |
lemma udvdI:
|
haftmann@40827
|
1203 |
"0 \<le> n \<Longrightarrow> uint b = n * uint a \<Longrightarrow> a udvd b"
|
haftmann@37660
|
1204 |
by (auto simp: udvd_def)
|
haftmann@37660
|
1205 |
|
huffman@47108
|
1206 |
lemmas word_div_no [simp] = word_div_def [of "numeral a" "numeral b"] for a b
|
huffman@47108
|
1207 |
|
huffman@47108
|
1208 |
lemmas word_mod_no [simp] = word_mod_def [of "numeral a" "numeral b"] for a b
|
huffman@47108
|
1209 |
|
huffman@47108
|
1210 |
lemmas word_less_no [simp] = word_less_def [of "numeral a" "numeral b"] for a b
|
huffman@47108
|
1211 |
|
huffman@47108
|
1212 |
lemmas word_le_no [simp] = word_le_def [of "numeral a" "numeral b"] for a b
|
huffman@47108
|
1213 |
|
huffman@47108
|
1214 |
lemmas word_sless_no [simp] = word_sless_def [of "numeral a" "numeral b"] for a b
|
huffman@47108
|
1215 |
|
huffman@47108
|
1216 |
lemmas word_sle_no [simp] = word_sle_def [of "numeral a" "numeral b"] for a b
|
haftmann@37660
|
1217 |
|
haftmann@54489
|
1218 |
lemma word_m1_wi: "- 1 = word_of_int (- 1)"
|
haftmann@54489
|
1219 |
using word_neg_numeral_alt [of Num.One] by simp
|
haftmann@37660
|
1220 |
|
huffman@46648
|
1221 |
lemma word_0_bl [simp]: "of_bl [] = 0"
|
huffman@46648
|
1222 |
unfolding of_bl_def by simp
|
haftmann@37660
|
1223 |
|
haftmann@37660
|
1224 |
lemma word_1_bl: "of_bl [True] = 1"
|
huffman@46648
|
1225 |
unfolding of_bl_def by (simp add: bl_to_bin_def)
|
huffman@46648
|
1226 |
|
huffman@46648
|
1227 |
lemma uint_eq_0 [simp]: "uint 0 = 0"
|
huffman@46648
|
1228 |
unfolding word_0_wi word_ubin.eq_norm by simp
|
haftmann@37660
|
1229 |
|
huffman@45995
|
1230 |
lemma of_bl_0 [simp]: "of_bl (replicate n False) = 0"
|
huffman@46648
|
1231 |
by (simp add: of_bl_def bl_to_bin_rep_False)
|
haftmann@37660
|
1232 |
|
huffman@45805
|
1233 |
lemma to_bl_0 [simp]:
|
haftmann@37660
|
1234 |
"to_bl (0::'a::len0 word) = replicate (len_of TYPE('a)) False"
|
haftmann@37660
|
1235 |
unfolding uint_bl
|
huffman@46617
|
1236 |
by (simp add: word_size bin_to_bl_zero)
|
haftmann@37660
|
1237 |
|
haftmann@55818
|
1238 |
lemma uint_0_iff:
|
haftmann@55818
|
1239 |
"uint x = 0 \<longleftrightarrow> x = 0"
|
haftmann@55818
|
1240 |
by (simp add: word_uint_eq_iff)
|
haftmann@55818
|
1241 |
|
haftmann@55818
|
1242 |
lemma unat_0_iff:
|
haftmann@55818
|
1243 |
"unat x = 0 \<longleftrightarrow> x = 0"
|
haftmann@37660
|
1244 |
unfolding unat_def by (auto simp add : nat_eq_iff uint_0_iff)
|
haftmann@37660
|
1245 |
|
haftmann@55818
|
1246 |
lemma unat_0 [simp]:
|
haftmann@55818
|
1247 |
"unat 0 = 0"
|
haftmann@37660
|
1248 |
unfolding unat_def by auto
|
haftmann@37660
|
1249 |
|
haftmann@55818
|
1250 |
lemma size_0_same':
|
haftmann@55818
|
1251 |
"size w = 0 \<Longrightarrow> w = (v :: 'a :: len0 word)"
|
haftmann@37660
|
1252 |
apply (unfold word_size)
|
haftmann@37660
|
1253 |
apply (rule box_equals)
|
haftmann@37660
|
1254 |
defer
|
haftmann@37660
|
1255 |
apply (rule word_uint.Rep_inverse)+
|
haftmann@37660
|
1256 |
apply (rule word_ubin.norm_eq_iff [THEN iffD1])
|
haftmann@37660
|
1257 |
apply simp
|
haftmann@37660
|
1258 |
done
|
haftmann@37660
|
1259 |
|
huffman@45816
|
1260 |
lemmas size_0_same = size_0_same' [unfolded word_size]
|
haftmann@37660
|
1261 |
|
haftmann@37660
|
1262 |
lemmas unat_eq_0 = unat_0_iff
|
haftmann@37660
|
1263 |
lemmas unat_eq_zero = unat_0_iff
|
haftmann@37660
|
1264 |
|
haftmann@37660
|
1265 |
lemma unat_gt_0: "(0 < unat x) = (x ~= 0)"
|
haftmann@37660
|
1266 |
by (auto simp: unat_0_iff [symmetric])
|
haftmann@37660
|
1267 |
|
huffman@45958
|
1268 |
lemma ucast_0 [simp]: "ucast 0 = 0"
|
huffman@45995
|
1269 |
unfolding ucast_def by simp
|
huffman@45958
|
1270 |
|
huffman@45958
|
1271 |
lemma sint_0 [simp]: "sint 0 = 0"
|
huffman@45958
|
1272 |
unfolding sint_uint by simp
|
huffman@45958
|
1273 |
|
huffman@45958
|
1274 |
lemma scast_0 [simp]: "scast 0 = 0"
|
huffman@45995
|
1275 |
unfolding scast_def by simp
|
haftmann@37660
|
1276 |
|
haftmann@58410
|
1277 |
lemma sint_n1 [simp] : "sint (- 1) = - 1"
|
haftmann@54489
|
1278 |
unfolding word_m1_wi word_sbin.eq_norm by simp
|
haftmann@54489
|
1279 |
|
haftmann@54489
|
1280 |
lemma scast_n1 [simp]: "scast (- 1) = - 1"
|
huffman@45958
|
1281 |
unfolding scast_def by simp
|
huffman@45958
|
1282 |
|
huffman@45958
|
1283 |
lemma uint_1 [simp]: "uint (1::'a::len word) = 1"
|
haftmann@55818
|
1284 |
by (simp only: word_1_wi word_ubin.eq_norm) (simp add: bintrunc_minus_simps(4))
|
huffman@45958
|
1285 |
|
huffman@45958
|
1286 |
lemma unat_1 [simp]: "unat (1::'a::len word) = 1"
|
huffman@45958
|
1287 |
unfolding unat_def by simp
|
huffman@45958
|
1288 |
|
huffman@45958
|
1289 |
lemma ucast_1 [simp]: "ucast (1::'a::len word) = 1"
|
huffman@45995
|
1290 |
unfolding ucast_def by simp
|
haftmann@37660
|
1291 |
|
haftmann@37660
|
1292 |
(* now, to get the weaker results analogous to word_div/mod_def *)
|
haftmann@37660
|
1293 |
|
haftmann@55816
|
1294 |
|
wenzelm@61799
|
1295 |
subsection \<open>Transferring goals from words to ints\<close>
|
haftmann@37660
|
1296 |
|
haftmann@37660
|
1297 |
lemma word_ths:
|
haftmann@37660
|
1298 |
shows
|
haftmann@37660
|
1299 |
word_succ_p1: "word_succ a = a + 1" and
|
haftmann@37660
|
1300 |
word_pred_m1: "word_pred a = a - 1" and
|
haftmann@37660
|
1301 |
word_pred_succ: "word_pred (word_succ a) = a" and
|
haftmann@37660
|
1302 |
word_succ_pred: "word_succ (word_pred a) = a" and
|
haftmann@37660
|
1303 |
word_mult_succ: "word_succ a * b = b + a * b"
|
huffman@47374
|
1304 |
by (transfer, simp add: algebra_simps)+
|
haftmann@37660
|
1305 |
|
huffman@45816
|
1306 |
lemma uint_cong: "x = y \<Longrightarrow> uint x = uint y"
|
huffman@45816
|
1307 |
by simp
|
haftmann@37660
|
1308 |
|
haftmann@55818
|
1309 |
lemma uint_word_ariths:
|
haftmann@55818
|
1310 |
fixes a b :: "'a::len0 word"
|
haftmann@55818
|
1311 |
shows "uint (a + b) = (uint a + uint b) mod 2 ^ len_of TYPE('a::len0)"
|
haftmann@55818
|
1312 |
and "uint (a - b) = (uint a - uint b) mod 2 ^ len_of TYPE('a)"
|
haftmann@55818
|
1313 |
and "uint (a * b) = uint a * uint b mod 2 ^ len_of TYPE('a)"
|
haftmann@55818
|
1314 |
and "uint (- a) = - uint a mod 2 ^ len_of TYPE('a)"
|
haftmann@55818
|
1315 |
and "uint (word_succ a) = (uint a + 1) mod 2 ^ len_of TYPE('a)"
|
haftmann@55818
|
1316 |
and "uint (word_pred a) = (uint a - 1) mod 2 ^ len_of TYPE('a)"
|
haftmann@55818
|
1317 |
and "uint (0 :: 'a word) = 0 mod 2 ^ len_of TYPE('a)"
|
haftmann@55818
|
1318 |
and "uint (1 :: 'a word) = 1 mod 2 ^ len_of TYPE('a)"
|
haftmann@55818
|
1319 |
by (simp_all add: word_arith_wis [THEN trans [OF uint_cong int_word_uint]])
|
haftmann@55818
|
1320 |
|
haftmann@55818
|
1321 |
lemma uint_word_arith_bintrs:
|
haftmann@55818
|
1322 |
fixes a b :: "'a::len0 word"
|
haftmann@55818
|
1323 |
shows "uint (a + b) = bintrunc (len_of TYPE('a)) (uint a + uint b)"
|
haftmann@55818
|
1324 |
and "uint (a - b) = bintrunc (len_of TYPE('a)) (uint a - uint b)"
|
haftmann@55818
|
1325 |
and "uint (a * b) = bintrunc (len_of TYPE('a)) (uint a * uint b)"
|
haftmann@55818
|
1326 |
and "uint (- a) = bintrunc (len_of TYPE('a)) (- uint a)"
|
haftmann@55818
|
1327 |
and "uint (word_succ a) = bintrunc (len_of TYPE('a)) (uint a + 1)"
|
haftmann@55818
|
1328 |
and "uint (word_pred a) = bintrunc (len_of TYPE('a)) (uint a - 1)"
|
haftmann@55818
|
1329 |
and "uint (0 :: 'a word) = bintrunc (len_of TYPE('a)) 0"
|
haftmann@55818
|
1330 |
and "uint (1 :: 'a word) = bintrunc (len_of TYPE('a)) 1"
|
haftmann@55818
|
1331 |
by (simp_all add: uint_word_ariths bintrunc_mod2p)
|
haftmann@55818
|
1332 |
|
haftmann@55818
|
1333 |
lemma sint_word_ariths:
|
haftmann@55818
|
1334 |
fixes a b :: "'a::len word"
|
haftmann@55818
|
1335 |
shows "sint (a + b) = sbintrunc (len_of TYPE('a) - 1) (sint a + sint b)"
|
haftmann@55818
|
1336 |
and "sint (a - b) = sbintrunc (len_of TYPE('a) - 1) (sint a - sint b)"
|
haftmann@55818
|
1337 |
and "sint (a * b) = sbintrunc (len_of TYPE('a) - 1) (sint a * sint b)"
|
haftmann@55818
|
1338 |
and "sint (- a) = sbintrunc (len_of TYPE('a) - 1) (- sint a)"
|
haftmann@55818
|
1339 |
and "sint (word_succ a) = sbintrunc (len_of TYPE('a) - 1) (sint a + 1)"
|
haftmann@55818
|
1340 |
and "sint (word_pred a) = sbintrunc (len_of TYPE('a) - 1) (sint a - 1)"
|
haftmann@55818
|
1341 |
and "sint (0 :: 'a word) = sbintrunc (len_of TYPE('a) - 1) 0"
|
haftmann@55818
|
1342 |
and "sint (1 :: 'a word) = sbintrunc (len_of TYPE('a) - 1) 1"
|
haftmann@55818
|
1343 |
by (simp_all add: uint_word_arith_bintrs
|
haftmann@55818
|
1344 |
[THEN uint_sint [symmetric, THEN trans],
|
haftmann@55818
|
1345 |
unfolded uint_sint bintr_arith1s bintr_ariths
|
haftmann@55818
|
1346 |
len_gt_0 [THEN bin_sbin_eq_iff'] word_sbin.norm_Rep])
|
wenzelm@45604
|
1347 |
|
wenzelm@45604
|
1348 |
lemmas uint_div_alt = word_div_def [THEN trans [OF uint_cong int_word_uint]]
|
wenzelm@45604
|
1349 |
lemmas uint_mod_alt = word_mod_def [THEN trans [OF uint_cong int_word_uint]]
|
haftmann@37660
|
1350 |
|
haftmann@58410
|
1351 |
lemma word_pred_0_n1: "word_pred 0 = word_of_int (- 1)"
|
huffman@47374
|
1352 |
unfolding word_pred_m1 by simp
|
haftmann@37660
|
1353 |
|
haftmann@37660
|
1354 |
lemma succ_pred_no [simp]:
|
huffman@47108
|
1355 |
"word_succ (numeral w) = numeral w + 1"
|
huffman@47108
|
1356 |
"word_pred (numeral w) = numeral w - 1"
|
haftmann@54489
|
1357 |
"word_succ (- numeral w) = - numeral w + 1"
|
haftmann@54489
|
1358 |
"word_pred (- numeral w) = - numeral w - 1"
|
huffman@47108
|
1359 |
unfolding word_succ_p1 word_pred_m1 by simp_all
|
haftmann@37660
|
1360 |
|
haftmann@37660
|
1361 |
lemma word_sp_01 [simp] :
|
haftmann@58410
|
1362 |
"word_succ (- 1) = 0 & word_succ 0 = 1 & word_pred 0 = - 1 & word_pred 1 = 0"
|
huffman@47108
|
1363 |
unfolding word_succ_p1 word_pred_m1 by simp_all
|
haftmann@37660
|
1364 |
|
haftmann@37660
|
1365 |
(* alternative approach to lifting arithmetic equalities *)
|
haftmann@37660
|
1366 |
lemma word_of_int_Ex:
|
haftmann@37660
|
1367 |
"\<exists>y. x = word_of_int y"
|
haftmann@37660
|
1368 |
by (rule_tac x="uint x" in exI) simp
|
haftmann@37660
|
1369 |
|
haftmann@37660
|
1370 |
|
wenzelm@61799
|
1371 |
subsection \<open>Order on fixed-length words\<close>
|
haftmann@37660
|
1372 |
|
haftmann@37660
|
1373 |
lemma word_zero_le [simp] :
|
haftmann@37660
|
1374 |
"0 <= (y :: 'a :: len0 word)"
|
haftmann@37660
|
1375 |
unfolding word_le_def by auto
|
haftmann@37660
|
1376 |
|
huffman@45816
|
1377 |
lemma word_m1_ge [simp] : "word_pred 0 >= y" (* FIXME: delete *)
|
haftmann@37660
|
1378 |
unfolding word_le_def
|
haftmann@37660
|
1379 |
by (simp only : word_pred_0_n1 word_uint.eq_norm m1mod2k) auto
|
haftmann@37660
|
1380 |
|
huffman@45816
|
1381 |
lemma word_n1_ge [simp]: "y \<le> (-1::'a::len0 word)"
|
huffman@45816
|
1382 |
unfolding word_le_def
|
huffman@45816
|
1383 |
by (simp only: word_m1_wi word_uint.eq_norm m1mod2k) auto
|
haftmann@37660
|
1384 |
|
haftmann@37660
|
1385 |
lemmas word_not_simps [simp] =
|
haftmann@37660
|
1386 |
word_zero_le [THEN leD] word_m1_ge [THEN leD] word_n1_ge [THEN leD]
|
haftmann@37660
|
1387 |
|
huffman@47108
|
1388 |
lemma word_gt_0: "0 < y \<longleftrightarrow> 0 \<noteq> (y :: 'a :: len0 word)"
|
huffman@47108
|
1389 |
by (simp add: less_le)
|
huffman@47108
|
1390 |
|
huffman@47108
|
1391 |
lemmas word_gt_0_no [simp] = word_gt_0 [of "numeral y"] for y
|
haftmann@37660
|
1392 |
|
haftmann@40827
|
1393 |
lemma word_sless_alt: "(a <s b) = (sint a < sint b)"
|
haftmann@37660
|
1394 |
unfolding word_sle_def word_sless_def
|
haftmann@37660
|
1395 |
by (auto simp add: less_le)
|
haftmann@37660
|
1396 |
|
haftmann@37660
|
1397 |
lemma word_le_nat_alt: "(a <= b) = (unat a <= unat b)"
|
haftmann@37660
|
1398 |
unfolding unat_def word_le_def
|
haftmann@37660
|
1399 |
by (rule nat_le_eq_zle [symmetric]) simp
|
haftmann@37660
|
1400 |
|
haftmann@37660
|
1401 |
lemma word_less_nat_alt: "(a < b) = (unat a < unat b)"
|
haftmann@37660
|
1402 |
unfolding unat_def word_less_alt
|
haftmann@37660
|
1403 |
by (rule nat_less_eq_zless [symmetric]) simp
|
haftmann@37660
|
1404 |
|
haftmann@37660
|
1405 |
lemma wi_less:
|
haftmann@37660
|
1406 |
"(word_of_int n < (word_of_int m :: 'a :: len0 word)) =
|
haftmann@37660
|
1407 |
(n mod 2 ^ len_of TYPE('a) < m mod 2 ^ len_of TYPE('a))"
|
haftmann@37660
|
1408 |
unfolding word_less_alt by (simp add: word_uint.eq_norm)
|
haftmann@37660
|
1409 |
|
haftmann@37660
|
1410 |
lemma wi_le:
|
haftmann@37660
|
1411 |
"(word_of_int n <= (word_of_int m :: 'a :: len0 word)) =
|
haftmann@37660
|
1412 |
(n mod 2 ^ len_of TYPE('a) <= m mod 2 ^ len_of TYPE('a))"
|
haftmann@37660
|
1413 |
unfolding word_le_def by (simp add: word_uint.eq_norm)
|
haftmann@37660
|
1414 |
|
haftmann@37660
|
1415 |
lemma udvd_nat_alt: "a udvd b = (EX n>=0. unat b = n * unat a)"
|
haftmann@37660
|
1416 |
apply (unfold udvd_def)
|
haftmann@37660
|
1417 |
apply safe
|
haftmann@37660
|
1418 |
apply (simp add: unat_def nat_mult_distrib)
|
haftmann@37660
|
1419 |
apply (simp add: uint_nat int_mult)
|
haftmann@37660
|
1420 |
apply (rule exI)
|
haftmann@37660
|
1421 |
apply safe
|
haftmann@37660
|
1422 |
prefer 2
|
haftmann@37660
|
1423 |
apply (erule notE)
|
haftmann@37660
|
1424 |
apply (rule refl)
|
haftmann@37660
|
1425 |
apply force
|
haftmann@37660
|
1426 |
done
|
haftmann@37660
|
1427 |
|
haftmann@37660
|
1428 |
lemma udvd_iff_dvd: "x udvd y <-> unat x dvd unat y"
|
haftmann@37660
|
1429 |
unfolding dvd_def udvd_nat_alt by force
|
haftmann@37660
|
1430 |
|
wenzelm@45604
|
1431 |
lemmas unat_mono = word_less_nat_alt [THEN iffD1]
|
haftmann@37660
|
1432 |
|
haftmann@55816
|
1433 |
lemma unat_minus_one:
|
haftmann@55816
|
1434 |
assumes "w \<noteq> 0"
|
haftmann@55816
|
1435 |
shows "unat (w - 1) = unat w - 1"
|
haftmann@55816
|
1436 |
proof -
|
haftmann@55816
|
1437 |
have "0 \<le> uint w" by (fact uint_nonnegative)
|
haftmann@55816
|
1438 |
moreover from assms have "0 \<noteq> uint w" by (simp add: uint_0_iff)
|
haftmann@55816
|
1439 |
ultimately have "1 \<le> uint w" by arith
|
haftmann@55816
|
1440 |
from uint_lt2p [of w] have "uint w - 1 < 2 ^ len_of TYPE('a)" by arith
|
wenzelm@61799
|
1441 |
with \<open>1 \<le> uint w\<close> have "(uint w - 1) mod 2 ^ len_of TYPE('a) = uint w - 1"
|
haftmann@55816
|
1442 |
by (auto intro: mod_pos_pos_trivial)
|
wenzelm@61799
|
1443 |
with \<open>1 \<le> uint w\<close> have "nat ((uint w - 1) mod 2 ^ len_of TYPE('a)) = nat (uint w) - 1"
|
haftmann@55816
|
1444 |
by auto
|
haftmann@55816
|
1445 |
then show ?thesis
|
haftmann@55818
|
1446 |
by (simp only: unat_def int_word_uint word_arith_wis mod_diff_right_eq [symmetric])
|
haftmann@55816
|
1447 |
qed
|
haftmann@55816
|
1448 |
|
haftmann@40827
|
1449 |
lemma measure_unat: "p ~= 0 \<Longrightarrow> unat (p - 1) < unat p"
|
haftmann@37660
|
1450 |
by (simp add: unat_minus_one) (simp add: unat_0_iff [symmetric])
|
haftmann@37660
|
1451 |
|
wenzelm@45604
|
1452 |
lemmas uint_add_ge0 [simp] = add_nonneg_nonneg [OF uint_ge_0 uint_ge_0]
|
wenzelm@45604
|
1453 |
lemmas uint_mult_ge0 [simp] = mult_nonneg_nonneg [OF uint_ge_0 uint_ge_0]
|
haftmann@37660
|
1454 |
|
haftmann@37660
|
1455 |
lemma uint_sub_lt2p [simp]:
|
haftmann@37660
|
1456 |
"uint (x :: 'a :: len0 word) - uint (y :: 'b :: len0 word) <
|
haftmann@37660
|
1457 |
2 ^ len_of TYPE('a)"
|
haftmann@37660
|
1458 |
using uint_ge_0 [of y] uint_lt2p [of x] by arith
|
haftmann@37660
|
1459 |
|
haftmann@37660
|
1460 |
|
wenzelm@61799
|
1461 |
subsection \<open>Conditions for the addition (etc) of two words to overflow\<close>
|
haftmann@37660
|
1462 |
|
haftmann@37660
|
1463 |
lemma uint_add_lem:
|
haftmann@37660
|
1464 |
"(uint x + uint y < 2 ^ len_of TYPE('a)) =
|
haftmann@37660
|
1465 |
(uint (x + y :: 'a :: len0 word) = uint x + uint y)"
|
haftmann@37660
|
1466 |
by (unfold uint_word_ariths) (auto intro!: trans [OF _ int_mod_lem])
|
haftmann@37660
|
1467 |
|
haftmann@37660
|
1468 |
lemma uint_mult_lem:
|
haftmann@37660
|
1469 |
"(uint x * uint y < 2 ^ len_of TYPE('a)) =
|
haftmann@37660
|
1470 |
(uint (x * y :: 'a :: len0 word) = uint x * uint y)"
|
haftmann@37660
|
1471 |
by (unfold uint_word_ariths) (auto intro!: trans [OF _ int_mod_lem])
|
haftmann@37660
|
1472 |
|
haftmann@37660
|
1473 |
lemma uint_sub_lem:
|
haftmann@37660
|
1474 |
"(uint x >= uint y) = (uint (x - y) = uint x - uint y)"
|
haftmann@37660
|
1475 |
by (unfold uint_word_ariths) (auto intro!: trans [OF _ int_mod_lem])
|
haftmann@37660
|
1476 |
|
haftmann@37660
|
1477 |
lemma uint_add_le: "uint (x + y) <= uint x + uint y"
|
haftmann@55816
|
1478 |
unfolding uint_word_ariths by (metis uint_add_ge0 zmod_le_nonneg_dividend)
|
haftmann@37660
|
1479 |
|
haftmann@37660
|
1480 |
lemma uint_sub_ge: "uint (x - y) >= uint x - uint y"
|
haftmann@55816
|
1481 |
unfolding uint_word_ariths by (metis int_mod_ge uint_sub_lt2p zless2p)
|
haftmann@55816
|
1482 |
|
haftmann@55816
|
1483 |
lemma mod_add_if_z:
|
haftmann@55816
|
1484 |
"(x :: int) < z ==> y < z ==> 0 <= y ==> 0 <= x ==> 0 <= z ==>
|
haftmann@55816
|
1485 |
(x + y) mod z = (if x + y < z then x + y else x + y - z)"
|
haftmann@55816
|
1486 |
by (auto intro: int_mod_eq)
|
haftmann@55816
|
1487 |
|
haftmann@55816
|
1488 |
lemma uint_plus_if':
|
haftmann@55816
|
1489 |
"uint ((a::'a word) + b) =
|
haftmann@55816
|
1490 |
(if uint a + uint b < 2 ^ len_of TYPE('a::len0) then uint a + uint b
|
haftmann@55816
|
1491 |
else uint a + uint b - 2 ^ len_of TYPE('a))"
|
haftmann@55816
|
1492 |
using mod_add_if_z [of "uint a" _ "uint b"] by (simp add: uint_word_ariths)
|
haftmann@55816
|
1493 |
|
haftmann@55816
|
1494 |
lemma mod_sub_if_z:
|
haftmann@55816
|
1495 |
"(x :: int) < z ==> y < z ==> 0 <= y ==> 0 <= x ==> 0 <= z ==>
|
haftmann@55816
|
1496 |
(x - y) mod z = (if y <= x then x - y else x - y + z)"
|
haftmann@55816
|
1497 |
by (auto intro: int_mod_eq)
|
haftmann@55816
|
1498 |
|
haftmann@55816
|
1499 |
lemma uint_sub_if':
|
haftmann@55816
|
1500 |
"uint ((a::'a word) - b) =
|
haftmann@55816
|
1501 |
(if uint b \<le> uint a then uint a - uint b
|
haftmann@55816
|
1502 |
else uint a - uint b + 2 ^ len_of TYPE('a::len0))"
|
haftmann@55816
|
1503 |
using mod_sub_if_z [of "uint a" _ "uint b"] by (simp add: uint_word_ariths)
|
haftmann@55816
|
1504 |
|
haftmann@55816
|
1505 |
|
wenzelm@61799
|
1506 |
subsection \<open>Definition of \<open>uint_arith\<close>\<close>
|
haftmann@37660
|
1507 |
|
haftmann@37660
|
1508 |
lemma word_of_int_inverse:
|
haftmann@40827
|
1509 |
"word_of_int r = a \<Longrightarrow> 0 <= r \<Longrightarrow> r < 2 ^ len_of TYPE('a) \<Longrightarrow>
|
haftmann@37660
|
1510 |
uint (a::'a::len0 word) = r"
|
haftmann@37660
|
1511 |
apply (erule word_uint.Abs_inverse' [rotated])
|
haftmann@37660
|
1512 |
apply (simp add: uints_num)
|
haftmann@37660
|
1513 |
done
|
haftmann@37660
|
1514 |
|
haftmann@37660
|
1515 |
lemma uint_split:
|
haftmann@37660
|
1516 |
fixes x::"'a::len0 word"
|
haftmann@37660
|
1517 |
shows "P (uint x) =
|
haftmann@37660
|
1518 |
(ALL i. word_of_int i = x & 0 <= i & i < 2^len_of TYPE('a) --> P i)"
|
haftmann@37660
|
1519 |
apply (fold word_int_case_def)
|
haftmann@55816
|
1520 |
apply (auto dest!: word_of_int_inverse simp: int_word_uint mod_pos_pos_trivial
|
haftmann@37660
|
1521 |
split: word_int_split)
|
haftmann@37660
|
1522 |
done
|
haftmann@37660
|
1523 |
|
haftmann@37660
|
1524 |
lemma uint_split_asm:
|
haftmann@37660
|
1525 |
fixes x::"'a::len0 word"
|
haftmann@37660
|
1526 |
shows "P (uint x) =
|
haftmann@37660
|
1527 |
(~(EX i. word_of_int i = x & 0 <= i & i < 2^len_of TYPE('a) & ~ P i))"
|
haftmann@37660
|
1528 |
by (auto dest!: word_of_int_inverse
|
haftmann@55816
|
1529 |
simp: int_word_uint mod_pos_pos_trivial
|
haftmann@37660
|
1530 |
split: uint_split)
|
haftmann@37660
|
1531 |
|
haftmann@37660
|
1532 |
lemmas uint_splits = uint_split uint_split_asm
|
haftmann@37660
|
1533 |
|
haftmann@37660
|
1534 |
lemmas uint_arith_simps =
|
haftmann@37660
|
1535 |
word_le_def word_less_alt
|
haftmann@37660
|
1536 |
word_uint.Rep_inject [symmetric]
|
haftmann@37660
|
1537 |
uint_sub_if' uint_plus_if'
|
haftmann@37660
|
1538 |
|
haftmann@37660
|
1539 |
(* use this to stop, eg, 2 ^ len_of TYPE (32) being simplified *)
|
haftmann@40827
|
1540 |
lemma power_False_cong: "False \<Longrightarrow> a ^ b = c ^ d"
|
haftmann@37660
|
1541 |
by auto
|
haftmann@37660
|
1542 |
|
haftmann@37660
|
1543 |
(* uint_arith_tac: reduce to arithmetic on int, try to solve by arith *)
|
wenzelm@61799
|
1544 |
ML \<open>
|
wenzelm@51717
|
1545 |
fun uint_arith_simpset ctxt =
|
wenzelm@51717
|
1546 |
ctxt addsimps @{thms uint_arith_simps}
|
haftmann@37660
|
1547 |
delsimps @{thms word_uint.Rep_inject}
|
wenzelm@45620
|
1548 |
|> fold Splitter.add_split @{thms split_if_asm}
|
wenzelm@45620
|
1549 |
|> fold Simplifier.add_cong @{thms power_False_cong}
|
haftmann@37660
|
1550 |
|
haftmann@37660
|
1551 |
fun uint_arith_tacs ctxt =
|
haftmann@37660
|
1552 |
let
|
haftmann@37660
|
1553 |
fun arith_tac' n t =
|
wenzelm@59657
|
1554 |
Arith_Data.arith_tac ctxt n t
|
haftmann@37660
|
1555 |
handle Cooper.COOPER _ => Seq.empty;
|
haftmann@37660
|
1556 |
in
|
wenzelm@42793
|
1557 |
[ clarify_tac ctxt 1,
|
wenzelm@51717
|
1558 |
full_simp_tac (uint_arith_simpset ctxt) 1,
|
wenzelm@51717
|
1559 |
ALLGOALS (full_simp_tac
|
wenzelm@51717
|
1560 |
(put_simpset HOL_ss ctxt
|
wenzelm@51717
|
1561 |
|> fold Splitter.add_split @{thms uint_splits}
|
wenzelm@51717
|
1562 |
|> fold Simplifier.add_cong @{thms power_False_cong})),
|
wenzelm@54742
|
1563 |
rewrite_goals_tac ctxt @{thms word_size},
|
wenzelm@59498
|
1564 |
ALLGOALS (fn n => REPEAT (resolve_tac ctxt [allI, impI] n) THEN
|
wenzelm@60754
|
1565 |
REPEAT (eresolve_tac ctxt [conjE] n) THEN
|
wenzelm@60754
|
1566 |
REPEAT (dresolve_tac ctxt @{thms word_of_int_inverse} n
|
wenzelm@58963
|
1567 |
THEN assume_tac ctxt n
|
wenzelm@58963
|
1568 |
THEN assume_tac ctxt n)),
|
haftmann@37660
|
1569 |
TRYALL arith_tac' ]
|
haftmann@37660
|
1570 |
end
|
haftmann@37660
|
1571 |
|
haftmann@37660
|
1572 |
fun uint_arith_tac ctxt = SELECT_GOAL (EVERY (uint_arith_tacs ctxt))
|
wenzelm@61799
|
1573 |
\<close>
|
haftmann@37660
|
1574 |
|
haftmann@37660
|
1575 |
method_setup uint_arith =
|
wenzelm@61799
|
1576 |
\<open>Scan.succeed (SIMPLE_METHOD' o uint_arith_tac)\<close>
|
haftmann@37660
|
1577 |
"solving word arithmetic via integers and arith"
|
haftmann@37660
|
1578 |
|
haftmann@37660
|
1579 |
|
wenzelm@61799
|
1580 |
subsection \<open>More on overflows and monotonicity\<close>
|
haftmann@37660
|
1581 |
|
haftmann@37660
|
1582 |
lemma no_plus_overflow_uint_size:
|
haftmann@37660
|
1583 |
"((x :: 'a :: len0 word) <= x + y) = (uint x + uint y < 2 ^ size x)"
|
haftmann@37660
|
1584 |
unfolding word_size by uint_arith
|
haftmann@37660
|
1585 |
|
haftmann@37660
|
1586 |
lemmas no_olen_add = no_plus_overflow_uint_size [unfolded word_size]
|
haftmann@37660
|
1587 |
|
haftmann@37660
|
1588 |
lemma no_ulen_sub: "((x :: 'a :: len0 word) >= x - y) = (uint y <= uint x)"
|
haftmann@37660
|
1589 |
by uint_arith
|
haftmann@37660
|
1590 |
|
haftmann@37660
|
1591 |
lemma no_olen_add':
|
haftmann@37660
|
1592 |
fixes x :: "'a::len0 word"
|
haftmann@37660
|
1593 |
shows "(x \<le> y + x) = (uint y + uint x < 2 ^ len_of TYPE('a))"
|
haftmann@57514
|
1594 |
by (simp add: ac_simps no_olen_add)
|
haftmann@37660
|
1595 |
|
wenzelm@45604
|
1596 |
lemmas olen_add_eqv = trans [OF no_olen_add no_olen_add' [symmetric]]
|
wenzelm@45604
|
1597 |
|
wenzelm@45604
|
1598 |
lemmas uint_plus_simple_iff = trans [OF no_olen_add uint_add_lem]
|
wenzelm@45604
|
1599 |
lemmas uint_plus_simple = uint_plus_simple_iff [THEN iffD1]
|
wenzelm@45604
|
1600 |
lemmas uint_minus_simple_iff = trans [OF no_ulen_sub uint_sub_lem]
|
haftmann@37660
|
1601 |
lemmas uint_minus_simple_alt = uint_sub_lem [folded word_le_def]
|
haftmann@37660
|
1602 |
lemmas word_sub_le_iff = no_ulen_sub [folded word_le_def]
|
wenzelm@45604
|
1603 |
lemmas word_sub_le = word_sub_le_iff [THEN iffD2]
|
haftmann@37660
|
1604 |
|
haftmann@37660
|
1605 |
lemma word_less_sub1:
|
haftmann@40827
|
1606 |
"(x :: 'a :: len word) ~= 0 \<Longrightarrow> (1 < x) = (0 < x - 1)"
|
haftmann@37660
|
1607 |
by uint_arith
|
haftmann@37660
|
1608 |
|
haftmann@37660
|
1609 |
lemma word_le_sub1:
|
haftmann@40827
|
1610 |
"(x :: 'a :: len word) ~= 0 \<Longrightarrow> (1 <= x) = (0 <= x - 1)"
|
haftmann@37660
|
1611 |
by uint_arith
|
haftmann@37660
|
1612 |
|
haftmann@37660
|
1613 |
lemma sub_wrap_lt:
|
haftmann@37660
|
1614 |
"((x :: 'a :: len0 word) < x - z) = (x < z)"
|
haftmann@37660
|
1615 |
by uint_arith
|
haftmann@37660
|
1616 |
|
haftmann@37660
|
1617 |
lemma sub_wrap:
|
haftmann@37660
|
1618 |
"((x :: 'a :: len0 word) <= x - z) = (z = 0 | x < z)"
|
haftmann@37660
|
1619 |
by uint_arith
|
haftmann@37660
|
1620 |
|
haftmann@37660
|
1621 |
lemma plus_minus_not_NULL_ab:
|
haftmann@40827
|
1622 |
"(x :: 'a :: len0 word) <= ab - c \<Longrightarrow> c <= ab \<Longrightarrow> c ~= 0 \<Longrightarrow> x + c ~= 0"
|
haftmann@37660
|
1623 |
by uint_arith
|
haftmann@37660
|
1624 |
|
haftmann@37660
|
1625 |
lemma plus_minus_no_overflow_ab:
|
haftmann@40827
|
1626 |
"(x :: 'a :: len0 word) <= ab - c \<Longrightarrow> c <= ab \<Longrightarrow> x <= x + c"
|
haftmann@37660
|
1627 |
by uint_arith
|
haftmann@37660
|
1628 |
|
haftmann@37660
|
1629 |
lemma le_minus':
|
haftmann@40827
|
1630 |
"(a :: 'a :: len0 word) + c <= b \<Longrightarrow> a <= a + c \<Longrightarrow> c <= b - a"
|
haftmann@37660
|
1631 |
by uint_arith
|
haftmann@37660
|
1632 |
|
haftmann@37660
|
1633 |
lemma le_plus':
|
haftmann@40827
|
1634 |
"(a :: 'a :: len0 word) <= b \<Longrightarrow> c <= b - a \<Longrightarrow> a + c <= b"
|
haftmann@37660
|
1635 |
by uint_arith
|
haftmann@37660
|
1636 |
|
haftmann@37660
|
1637 |
lemmas le_plus = le_plus' [rotated]
|
haftmann@37660
|
1638 |
|
huffman@46011
|
1639 |
lemmas le_minus = leD [THEN thin_rl, THEN le_minus'] (* FIXME *)
|
haftmann@37660
|
1640 |
|
haftmann@37660
|
1641 |
lemma word_plus_mono_right:
|
haftmann@40827
|
1642 |
"(y :: 'a :: len0 word) <= z \<Longrightarrow> x <= x + z \<Longrightarrow> x + y <= x + z"
|
haftmann@37660
|
1643 |
by uint_arith
|
haftmann@37660
|
1644 |
|
haftmann@37660
|
1645 |
lemma word_less_minus_cancel:
|
haftmann@40827
|
1646 |
"y - x < z - x \<Longrightarrow> x <= z \<Longrightarrow> (y :: 'a :: len0 word) < z"
|
haftmann@37660
|
1647 |
by uint_arith
|
haftmann@37660
|
1648 |
|
haftmann@37660
|
1649 |
lemma word_less_minus_mono_left:
|
haftmann@40827
|
1650 |
"(y :: 'a :: len0 word) < z \<Longrightarrow> x <= y \<Longrightarrow> y - x < z - x"
|
haftmann@37660
|
1651 |
by uint_arith
|
haftmann@37660
|
1652 |
|
haftmann@37660
|
1653 |
lemma word_less_minus_mono:
|
haftmann@40827
|
1654 |
"a < c \<Longrightarrow> d < b \<Longrightarrow> a - b < a \<Longrightarrow> c - d < c
|
haftmann@40827
|
1655 |
\<Longrightarrow> a - b < c - (d::'a::len word)"
|
haftmann@37660
|
1656 |
by uint_arith
|
haftmann@37660
|
1657 |
|
haftmann@37660
|
1658 |
lemma word_le_minus_cancel:
|
haftmann@40827
|
1659 |
"y - x <= z - x \<Longrightarrow> x <= z \<Longrightarrow> (y :: 'a :: len0 word) <= z"
|
haftmann@37660
|
1660 |
by uint_arith
|
haftmann@37660
|
1661 |
|
haftmann@37660
|
1662 |
lemma word_le_minus_mono_left:
|
haftmann@40827
|
1663 |
"(y :: 'a :: len0 word) <= z \<Longrightarrow> x <= y \<Longrightarrow> y - x <= z - x"
|
haftmann@37660
|
1664 |
by uint_arith
|
haftmann@37660
|
1665 |
|
haftmann@37660
|
1666 |
lemma word_le_minus_mono:
|
haftmann@40827
|
1667 |
"a <= c \<Longrightarrow> d <= b \<Longrightarrow> a - b <= a \<Longrightarrow> c - d <= c
|
haftmann@40827
|
1668 |
\<Longrightarrow> a - b <= c - (d::'a::len word)"
|
haftmann@37660
|
1669 |
by uint_arith
|
haftmann@37660
|
1670 |
|
haftmann@37660
|
1671 |
lemma plus_le_left_cancel_wrap:
|
haftmann@40827
|
1672 |
"(x :: 'a :: len0 word) + y' < x \<Longrightarrow> x + y < x \<Longrightarrow> (x + y' < x + y) = (y' < y)"
|
haftmann@37660
|
1673 |
by uint_arith
|
haftmann@37660
|
1674 |
|
haftmann@37660
|
1675 |
lemma plus_le_left_cancel_nowrap:
|
haftmann@40827
|
1676 |
"(x :: 'a :: len0 word) <= x + y' \<Longrightarrow> x <= x + y \<Longrightarrow>
|
haftmann@37660
|
1677 |
(x + y' < x + y) = (y' < y)"
|
haftmann@37660
|
1678 |
by uint_arith
|
haftmann@37660
|
1679 |
|
haftmann@37660
|
1680 |
lemma word_plus_mono_right2:
|
haftmann@40827
|
1681 |
"(a :: 'a :: len0 word) <= a + b \<Longrightarrow> c <= b \<Longrightarrow> a <= a + c"
|
haftmann@37660
|
1682 |
by uint_arith
|
haftmann@37660
|
1683 |
|
haftmann@37660
|
1684 |
lemma word_less_add_right:
|
haftmann@40827
|
1685 |
"(x :: 'a :: len0 word) < y - z \<Longrightarrow> z <= y \<Longrightarrow> x + z < y"
|
haftmann@37660
|
1686 |
by uint_arith
|
haftmann@37660
|
1687 |
|
haftmann@37660
|
1688 |
lemma word_less_sub_right:
|
haftmann@40827
|
1689 |
"(x :: 'a :: len0 word) < y + z \<Longrightarrow> y <= x \<Longrightarrow> x - y < z"
|
haftmann@37660
|
1690 |
by uint_arith
|
haftmann@37660
|
1691 |
|
haftmann@37660
|
1692 |
lemma word_le_plus_either:
|
haftmann@40827
|
1693 |
"(x :: 'a :: len0 word) <= y | x <= z \<Longrightarrow> y <= y + z \<Longrightarrow> x <= y + z"
|
haftmann@37660
|
1694 |
by uint_arith
|
haftmann@37660
|
1695 |
|
haftmann@37660
|
1696 |
lemma word_less_nowrapI:
|
haftmann@40827
|
1697 |
"(x :: 'a :: len0 word) < z - k \<Longrightarrow> k <= z \<Longrightarrow> 0 < k \<Longrightarrow> x < x + k"
|
haftmann@37660
|
1698 |
by uint_arith
|
haftmann@37660
|
1699 |
|
haftmann@40827
|
1700 |
lemma inc_le: "(i :: 'a :: len word) < m \<Longrightarrow> i + 1 <= m"
|
haftmann@37660
|
1701 |
by uint_arith
|
haftmann@37660
|
1702 |
|
haftmann@37660
|
1703 |
lemma inc_i:
|
haftmann@40827
|
1704 |
"(1 :: 'a :: len word) <= i \<Longrightarrow> i < m \<Longrightarrow> 1 <= (i + 1) & i + 1 <= m"
|
haftmann@37660
|
1705 |
by uint_arith
|
haftmann@37660
|
1706 |
|
haftmann@37660
|
1707 |
lemma udvd_incr_lem:
|
haftmann@40827
|
1708 |
"up < uq \<Longrightarrow> up = ua + n * uint K \<Longrightarrow>
|
haftmann@40827
|
1709 |
uq = ua + n' * uint K \<Longrightarrow> up + uint K <= uq"
|
haftmann@37660
|
1710 |
apply clarsimp
|
haftmann@55816
|
1711 |
|
haftmann@37660
|
1712 |
apply (drule less_le_mult)
|
haftmann@37660
|
1713 |
apply safe
|
haftmann@37660
|
1714 |
done
|
haftmann@37660
|
1715 |
|
haftmann@37660
|
1716 |
lemma udvd_incr':
|
haftmann@40827
|
1717 |
"p < q \<Longrightarrow> uint p = ua + n * uint K \<Longrightarrow>
|
haftmann@40827
|
1718 |
uint q = ua + n' * uint K \<Longrightarrow> p + K <= q"
|
haftmann@37660
|
1719 |
apply (unfold word_less_alt word_le_def)
|
haftmann@37660
|
1720 |
apply (drule (2) udvd_incr_lem)
|
haftmann@37660
|
1721 |
apply (erule uint_add_le [THEN order_trans])
|
haftmann@37660
|
1722 |
done
|
haftmann@37660
|
1723 |
|
haftmann@37660
|
1724 |
lemma udvd_decr':
|
haftmann@40827
|
1725 |
"p < q \<Longrightarrow> uint p = ua + n * uint K \<Longrightarrow>
|
haftmann@40827
|
1726 |
uint q = ua + n' * uint K \<Longrightarrow> p <= q - K"
|
haftmann@37660
|
1727 |
apply (unfold word_less_alt word_le_def)
|
haftmann@37660
|
1728 |
apply (drule (2) udvd_incr_lem)
|
haftmann@37660
|
1729 |
apply (drule le_diff_eq [THEN iffD2])
|
haftmann@37660
|
1730 |
apply (erule order_trans)
|
haftmann@37660
|
1731 |
apply (rule uint_sub_ge)
|
haftmann@37660
|
1732 |
done
|
haftmann@37660
|
1733 |
|
huffman@45816
|
1734 |
lemmas udvd_incr_lem0 = udvd_incr_lem [where ua=0, unfolded add_0_left]
|
huffman@45816
|
1735 |
lemmas udvd_incr0 = udvd_incr' [where ua=0, unfolded add_0_left]
|
huffman@45816
|
1736 |
lemmas udvd_decr0 = udvd_decr' [where ua=0, unfolded add_0_left]
|
haftmann@37660
|
1737 |
|
haftmann@37660
|
1738 |
lemma udvd_minus_le':
|
haftmann@40827
|
1739 |
"xy < k \<Longrightarrow> z udvd xy \<Longrightarrow> z udvd k \<Longrightarrow> xy <= k - z"
|
haftmann@37660
|
1740 |
apply (unfold udvd_def)
|
haftmann@37660
|
1741 |
apply clarify
|
haftmann@37660
|
1742 |
apply (erule (2) udvd_decr0)
|
haftmann@37660
|
1743 |
done
|
haftmann@37660
|
1744 |
|
haftmann@37660
|
1745 |
lemma udvd_incr2_K:
|
haftmann@40827
|
1746 |
"p < a + s \<Longrightarrow> a <= a + s \<Longrightarrow> K udvd s \<Longrightarrow> K udvd p - a \<Longrightarrow> a <= p \<Longrightarrow>
|
haftmann@40827
|
1747 |
0 < K \<Longrightarrow> p <= p + K & p + K <= a + s"
|
wenzelm@51286
|
1748 |
using [[simproc del: linordered_ring_less_cancel_factor]]
|
haftmann@37660
|
1749 |
apply (unfold udvd_def)
|
haftmann@37660
|
1750 |
apply clarify
|
haftmann@37660
|
1751 |
apply (simp add: uint_arith_simps split: split_if_asm)
|
haftmann@37660
|
1752 |
prefer 2
|
haftmann@37660
|
1753 |
apply (insert uint_range' [of s])[1]
|
haftmann@37660
|
1754 |
apply arith
|
haftmann@57512
|
1755 |
apply (drule add.commute [THEN xtr1])
|
haftmann@37660
|
1756 |
apply (simp add: diff_less_eq [symmetric])
|
haftmann@37660
|
1757 |
apply (drule less_le_mult)
|
haftmann@37660
|
1758 |
apply arith
|
haftmann@37660
|
1759 |
apply simp
|
haftmann@37660
|
1760 |
done
|
haftmann@37660
|
1761 |
|
haftmann@37660
|
1762 |
(* links with rbl operations *)
|
haftmann@37660
|
1763 |
lemma word_succ_rbl:
|
haftmann@40827
|
1764 |
"to_bl w = bl \<Longrightarrow> to_bl (word_succ w) = (rev (rbl_succ (rev bl)))"
|
haftmann@37660
|
1765 |
apply (unfold word_succ_def)
|
haftmann@37660
|
1766 |
apply clarify
|
haftmann@37660
|
1767 |
apply (simp add: to_bl_of_bin)
|
huffman@46654
|
1768 |
apply (simp add: to_bl_def rbl_succ)
|
haftmann@37660
|
1769 |
done
|
haftmann@37660
|
1770 |
|
haftmann@37660
|
1771 |
lemma word_pred_rbl:
|
haftmann@40827
|
1772 |
"to_bl w = bl \<Longrightarrow> to_bl (word_pred w) = (rev (rbl_pred (rev bl)))"
|
haftmann@37660
|
1773 |
apply (unfold word_pred_def)
|
haftmann@37660
|
1774 |
apply clarify
|
haftmann@37660
|
1775 |
apply (simp add: to_bl_of_bin)
|
huffman@46654
|
1776 |
apply (simp add: to_bl_def rbl_pred)
|
haftmann@37660
|
1777 |
done
|
haftmann@37660
|
1778 |
|
haftmann@37660
|
1779 |
lemma word_add_rbl:
|
haftmann@40827
|
1780 |
"to_bl v = vbl \<Longrightarrow> to_bl w = wbl \<Longrightarrow>
|
haftmann@37660
|
1781 |
to_bl (v + w) = (rev (rbl_add (rev vbl) (rev wbl)))"
|
haftmann@37660
|
1782 |
apply (unfold word_add_def)
|
haftmann@37660
|
1783 |
apply clarify
|
haftmann@37660
|
1784 |
apply (simp add: to_bl_of_bin)
|
haftmann@37660
|
1785 |
apply (simp add: to_bl_def rbl_add)
|
haftmann@37660
|
1786 |
done
|
haftmann@37660
|
1787 |
|
haftmann@37660
|
1788 |
lemma word_mult_rbl:
|
haftmann@40827
|
1789 |
"to_bl v = vbl \<Longrightarrow> to_bl w = wbl \<Longrightarrow>
|
haftmann@37660
|
1790 |
to_bl (v * w) = (rev (rbl_mult (rev vbl) (rev wbl)))"
|
haftmann@37660
|
1791 |
apply (unfold word_mult_def)
|
haftmann@37660
|
1792 |
apply clarify
|
haftmann@37660
|
1793 |
apply (simp add: to_bl_of_bin)
|
haftmann@37660
|
1794 |
apply (simp add: to_bl_def rbl_mult)
|
haftmann@37660
|
1795 |
done
|
haftmann@37660
|
1796 |
|
haftmann@37660
|
1797 |
lemma rtb_rbl_ariths:
|
haftmann@37660
|
1798 |
"rev (to_bl w) = ys \<Longrightarrow> rev (to_bl (word_succ w)) = rbl_succ ys"
|
haftmann@37660
|
1799 |
"rev (to_bl w) = ys \<Longrightarrow> rev (to_bl (word_pred w)) = rbl_pred ys"
|
haftmann@40827
|
1800 |
"rev (to_bl v) = ys \<Longrightarrow> rev (to_bl w) = xs \<Longrightarrow> rev (to_bl (v * w)) = rbl_mult ys xs"
|
haftmann@40827
|
1801 |
"rev (to_bl v) = ys \<Longrightarrow> rev (to_bl w) = xs \<Longrightarrow> rev (to_bl (v + w)) = rbl_add ys xs"
|
haftmann@37660
|
1802 |
by (auto simp: rev_swap [symmetric] word_succ_rbl
|
haftmann@37660
|
1803 |
word_pred_rbl word_mult_rbl word_add_rbl)
|
haftmann@37660
|
1804 |
|
haftmann@37660
|
1805 |
|
wenzelm@61799
|
1806 |
subsection \<open>Arithmetic type class instantiations\<close>
|
haftmann@37660
|
1807 |
|
haftmann@37660
|
1808 |
lemmas word_le_0_iff [simp] =
|
haftmann@37660
|
1809 |
word_zero_le [THEN leD, THEN linorder_antisym_conv1]
|
haftmann@37660
|
1810 |
|
haftmann@37660
|
1811 |
lemma word_of_int_nat:
|
haftmann@40827
|
1812 |
"0 <= x \<Longrightarrow> word_of_int x = of_nat (nat x)"
|
haftmann@37660
|
1813 |
by (simp add: of_nat_nat word_of_int)
|
haftmann@37660
|
1814 |
|
huffman@46603
|
1815 |
(* note that iszero_def is only for class comm_semiring_1_cancel,
|
huffman@46603
|
1816 |
which requires word length >= 1, ie 'a :: len word *)
|
huffman@46603
|
1817 |
lemma iszero_word_no [simp]:
|
huffman@47108
|
1818 |
"iszero (numeral bin :: 'a :: len word) =
|
huffman@47108
|
1819 |
iszero (bintrunc (len_of TYPE('a)) (numeral bin))"
|
huffman@47108
|
1820 |
using word_ubin.norm_eq_iff [where 'a='a, of "numeral bin" 0]
|
huffman@46603
|
1821 |
by (simp add: iszero_def [symmetric])
|
huffman@47108
|
1822 |
|
wenzelm@61799
|
1823 |
text \<open>Use \<open>iszero\<close> to simplify equalities between word numerals.\<close>
|
huffman@47108
|
1824 |
|
huffman@47108
|
1825 |
lemmas word_eq_numeral_iff_iszero [simp] =
|
huffman@47108
|
1826 |
eq_numeral_iff_iszero [where 'a="'a::len word"]
|
huffman@46603
|
1827 |
|
haftmann@37660
|
1828 |
|
wenzelm@61799
|
1829 |
subsection \<open>Word and nat\<close>
|
haftmann@37660
|
1830 |
|
huffman@45811
|
1831 |
lemma td_ext_unat [OF refl]:
|
haftmann@40827
|
1832 |
"n = len_of TYPE ('a :: len) \<Longrightarrow>
|
haftmann@37660
|
1833 |
td_ext (unat :: 'a word => nat) of_nat
|
haftmann@37660
|
1834 |
(unats n) (%i. i mod 2 ^ n)"
|
haftmann@37660
|
1835 |
apply (unfold td_ext_def' unat_def word_of_nat unats_uints)
|
haftmann@37660
|
1836 |
apply (auto intro!: imageI simp add : word_of_int_hom_syms)
|
haftmann@37660
|
1837 |
apply (erule word_uint.Abs_inverse [THEN arg_cong])
|
haftmann@37660
|
1838 |
apply (simp add: int_word_uint nat_mod_distrib nat_power_eq)
|
haftmann@37660
|
1839 |
done
|
haftmann@37660
|
1840 |
|
wenzelm@45604
|
1841 |
lemmas unat_of_nat = td_ext_unat [THEN td_ext.eq_norm]
|
haftmann@37660
|
1842 |
|
haftmann@37660
|
1843 |
interpretation word_unat:
|
haftmann@37660
|
1844 |
td_ext "unat::'a::len word => nat"
|
haftmann@37660
|
1845 |
of_nat
|
haftmann@37660
|
1846 |
"unats (len_of TYPE('a::len))"
|
haftmann@37660
|
1847 |
"%i. i mod 2 ^ len_of TYPE('a::len)"
|
haftmann@37660
|
1848 |
by (rule td_ext_unat)
|
haftmann@37660
|
1849 |
|
haftmann@37660
|
1850 |
lemmas td_unat = word_unat.td_thm
|
haftmann@37660
|
1851 |
|
haftmann@37660
|
1852 |
lemmas unat_lt2p [iff] = word_unat.Rep [unfolded unats_def mem_Collect_eq]
|
haftmann@37660
|
1853 |
|
haftmann@40827
|
1854 |
lemma unat_le: "y <= unat (z :: 'a :: len word) \<Longrightarrow> y : unats (len_of TYPE ('a))"
|
haftmann@37660
|
1855 |
apply (unfold unats_def)
|
haftmann@37660
|
1856 |
apply clarsimp
|
haftmann@37660
|
1857 |
apply (rule xtrans, rule unat_lt2p, assumption)
|
haftmann@37660
|
1858 |
done
|
haftmann@37660
|
1859 |
|
haftmann@37660
|
1860 |
lemma word_nchotomy:
|
haftmann@37660
|
1861 |
"ALL w. EX n. (w :: 'a :: len word) = of_nat n & n < 2 ^ len_of TYPE ('a)"
|
haftmann@37660
|
1862 |
apply (rule allI)
|
haftmann@37660
|
1863 |
apply (rule word_unat.Abs_cases)
|
haftmann@37660
|
1864 |
apply (unfold unats_def)
|
haftmann@37660
|
1865 |
apply auto
|
haftmann@37660
|
1866 |
done
|
haftmann@37660
|
1867 |
|
haftmann@37660
|
1868 |
lemma of_nat_eq:
|
haftmann@37660
|
1869 |
fixes w :: "'a::len word"
|
haftmann@37660
|
1870 |
shows "(of_nat n = w) = (\<exists>q. n = unat w + q * 2 ^ len_of TYPE('a))"
|
haftmann@37660
|
1871 |
apply (rule trans)
|
haftmann@37660
|
1872 |
apply (rule word_unat.inverse_norm)
|
haftmann@37660
|
1873 |
apply (rule iffI)
|
haftmann@37660
|
1874 |
apply (rule mod_eqD)
|
haftmann@37660
|
1875 |
apply simp
|
haftmann@37660
|
1876 |
apply clarsimp
|
haftmann@37660
|
1877 |
done
|
haftmann@37660
|
1878 |
|
haftmann@37660
|
1879 |
lemma of_nat_eq_size:
|
haftmann@37660
|
1880 |
"(of_nat n = w) = (EX q. n = unat w + q * 2 ^ size w)"
|
haftmann@37660
|
1881 |
unfolding word_size by (rule of_nat_eq)
|
haftmann@37660
|
1882 |
|
haftmann@37660
|
1883 |
lemma of_nat_0:
|
haftmann@37660
|
1884 |
"(of_nat m = (0::'a::len word)) = (\<exists>q. m = q * 2 ^ len_of TYPE('a))"
|
haftmann@37660
|
1885 |
by (simp add: of_nat_eq)
|
haftmann@37660
|
1886 |
|
huffman@45805
|
1887 |
lemma of_nat_2p [simp]:
|
huffman@45805
|
1888 |
"of_nat (2 ^ len_of TYPE('a)) = (0::'a::len word)"
|
huffman@45805
|
1889 |
by (fact mult_1 [symmetric, THEN iffD2 [OF of_nat_0 exI]])
|
haftmann@37660
|
1890 |
|
haftmann@40827
|
1891 |
lemma of_nat_gt_0: "of_nat k ~= 0 \<Longrightarrow> 0 < k"
|
haftmann@37660
|
1892 |
by (cases k) auto
|
haftmann@37660
|
1893 |
|
haftmann@37660
|
1894 |
lemma of_nat_neq_0:
|
haftmann@40827
|
1895 |
"0 < k \<Longrightarrow> k < 2 ^ len_of TYPE ('a :: len) \<Longrightarrow> of_nat k ~= (0 :: 'a word)"
|
haftmann@37660
|
1896 |
by (clarsimp simp add : of_nat_0)
|
haftmann@37660
|
1897 |
|
haftmann@37660
|
1898 |
lemma Abs_fnat_hom_add:
|
haftmann@37660
|
1899 |
"of_nat a + of_nat b = of_nat (a + b)"
|
haftmann@37660
|
1900 |
by simp
|
haftmann@37660
|
1901 |
|
haftmann@37660
|
1902 |
lemma Abs_fnat_hom_mult:
|
haftmann@37660
|
1903 |
"of_nat a * of_nat b = (of_nat (a * b) :: 'a :: len word)"
|
lp15@61649
|
1904 |
by (simp add: word_of_nat wi_hom_mult)
|
haftmann@37660
|
1905 |
|
haftmann@37660
|
1906 |
lemma Abs_fnat_hom_Suc:
|
haftmann@37660
|
1907 |
"word_succ (of_nat a) = of_nat (Suc a)"
|
haftmann@57514
|
1908 |
by (simp add: word_of_nat wi_hom_succ ac_simps)
|
haftmann@37660
|
1909 |
|
haftmann@37660
|
1910 |
lemma Abs_fnat_hom_0: "(0::'a::len word) = of_nat 0"
|
huffman@45995
|
1911 |
by simp
|
haftmann@37660
|
1912 |
|
haftmann@37660
|
1913 |
lemma Abs_fnat_hom_1: "(1::'a::len word) = of_nat (Suc 0)"
|
huffman@45995
|
1914 |
by simp
|
haftmann@37660
|
1915 |
|
haftmann@37660
|
1916 |
lemmas Abs_fnat_homs =
|
haftmann@37660
|
1917 |
Abs_fnat_hom_add Abs_fnat_hom_mult Abs_fnat_hom_Suc
|
haftmann@37660
|
1918 |
Abs_fnat_hom_0 Abs_fnat_hom_1
|
haftmann@37660
|
1919 |
|
haftmann@37660
|
1920 |
lemma word_arith_nat_add:
|
haftmann@37660
|
1921 |
"a + b = of_nat (unat a + unat b)"
|
haftmann@37660
|
1922 |
by simp
|
haftmann@37660
|
1923 |
|
haftmann@37660
|
1924 |
lemma word_arith_nat_mult:
|
haftmann@37660
|
1925 |
"a * b = of_nat (unat a * unat b)"
|
huffman@45995
|
1926 |
by (simp add: of_nat_mult)
|
haftmann@37660
|
1927 |
|
haftmann@37660
|
1928 |
lemma word_arith_nat_Suc:
|
haftmann@37660
|
1929 |
"word_succ a = of_nat (Suc (unat a))"
|
haftmann@37660
|
1930 |
by (subst Abs_fnat_hom_Suc [symmetric]) simp
|
haftmann@37660
|
1931 |
|
haftmann@37660
|
1932 |
lemma word_arith_nat_div:
|
haftmann@37660
|
1933 |
"a div b = of_nat (unat a div unat b)"
|
haftmann@37660
|
1934 |
by (simp add: word_div_def word_of_nat zdiv_int uint_nat)
|
haftmann@37660
|
1935 |
|
haftmann@37660
|
1936 |
lemma word_arith_nat_mod:
|
haftmann@37660
|
1937 |
"a mod b = of_nat (unat a mod unat b)"
|
haftmann@37660
|
1938 |
by (simp add: word_mod_def word_of_nat zmod_int uint_nat)
|
haftmann@37660
|
1939 |
|
haftmann@37660
|
1940 |
lemmas word_arith_nat_defs =
|
haftmann@37660
|
1941 |
word_arith_nat_add word_arith_nat_mult
|
haftmann@37660
|
1942 |
word_arith_nat_Suc Abs_fnat_hom_0
|
haftmann@37660
|
1943 |
Abs_fnat_hom_1 word_arith_nat_div
|
haftmann@37660
|
1944 |
word_arith_nat_mod
|
haftmann@37660
|
1945 |
|
huffman@45816
|
1946 |
lemma unat_cong: "x = y \<Longrightarrow> unat x = unat y"
|
huffman@45816
|
1947 |
by simp
|
haftmann@37660
|
1948 |
|
haftmann@37660
|
1949 |
lemmas unat_word_ariths = word_arith_nat_defs
|
wenzelm@45604
|
1950 |
[THEN trans [OF unat_cong unat_of_nat]]
|
haftmann@37660
|
1951 |
|
haftmann@37660
|
1952 |
lemmas word_sub_less_iff = word_sub_le_iff
|
huffman@45816
|
1953 |
[unfolded linorder_not_less [symmetric] Not_eq_iff]
|
haftmann@37660
|
1954 |
|
haftmann@37660
|
1955 |
lemma unat_add_lem:
|
haftmann@37660
|
1956 |
"(unat x + unat y < 2 ^ len_of TYPE('a)) =
|
haftmann@37660
|
1957 |
(unat (x + y :: 'a :: len word) = unat x + unat y)"
|
haftmann@37660
|
1958 |
unfolding unat_word_ariths
|
haftmann@37660
|
1959 |
by (auto intro!: trans [OF _ nat_mod_lem])
|
haftmann@37660
|
1960 |
|
haftmann@37660
|
1961 |
lemma unat_mult_lem:
|
haftmann@37660
|
1962 |
"(unat x * unat y < 2 ^ len_of TYPE('a)) =
|
haftmann@37660
|
1963 |
(unat (x * y :: 'a :: len word) = unat x * unat y)"
|
haftmann@37660
|
1964 |
unfolding unat_word_ariths
|
haftmann@37660
|
1965 |
by (auto intro!: trans [OF _ nat_mod_lem])
|
haftmann@37660
|
1966 |
|
wenzelm@45604
|
1967 |
lemmas unat_plus_if' = trans [OF unat_word_ariths(1) mod_nat_add, simplified]
|
haftmann@37660
|
1968 |
|
haftmann@37660
|
1969 |
lemma le_no_overflow:
|
haftmann@40827
|
1970 |
"x <= b \<Longrightarrow> a <= a + b \<Longrightarrow> x <= a + (b :: 'a :: len0 word)"
|
haftmann@37660
|
1971 |
apply (erule order_trans)
|
haftmann@37660
|
1972 |
apply (erule olen_add_eqv [THEN iffD1])
|
haftmann@37660
|
1973 |
done
|
haftmann@37660
|
1974 |
|
wenzelm@45604
|
1975 |
lemmas un_ui_le = trans [OF word_le_nat_alt [symmetric] word_le_def]
|
haftmann@37660
|
1976 |
|
haftmann@37660
|
1977 |
lemma unat_sub_if_size:
|
haftmann@37660
|
1978 |
"unat (x - y) = (if unat y <= unat x
|
haftmann@37660
|
1979 |
then unat x - unat y
|
haftmann@37660
|
1980 |
else unat x + 2 ^ size x - unat y)"
|
haftmann@37660
|
1981 |
apply (unfold word_size)
|
haftmann@37660
|
1982 |
apply (simp add: un_ui_le)
|
haftmann@37660
|
1983 |
apply (auto simp add: unat_def uint_sub_if')
|
haftmann@37660
|
1984 |
apply (rule nat_diff_distrib)
|
haftmann@37660
|
1985 |
prefer 3
|
haftmann@37660
|
1986 |
apply (simp add: algebra_simps)
|
haftmann@37660
|
1987 |
apply (rule nat_diff_distrib [THEN trans])
|
haftmann@37660
|
1988 |
prefer 3
|
haftmann@37660
|
1989 |
apply (subst nat_add_distrib)
|
haftmann@37660
|
1990 |
prefer 3
|
haftmann@37660
|
1991 |
apply (simp add: nat_power_eq)
|
haftmann@37660
|
1992 |
apply auto
|
haftmann@37660
|
1993 |
apply uint_arith
|
haftmann@37660
|
1994 |
done
|
haftmann@37660
|
1995 |
|
haftmann@37660
|
1996 |
lemmas unat_sub_if' = unat_sub_if_size [unfolded word_size]
|
haftmann@37660
|
1997 |
|
haftmann@37660
|
1998 |
lemma unat_div: "unat ((x :: 'a :: len word) div y) = unat x div unat y"
|
haftmann@37660
|
1999 |
apply (simp add : unat_word_ariths)
|
haftmann@37660
|
2000 |
apply (rule unat_lt2p [THEN xtr7, THEN nat_mod_eq'])
|
haftmann@37660
|
2001 |
apply (rule div_le_dividend)
|
haftmann@37660
|
2002 |
done
|
haftmann@37660
|
2003 |
|
haftmann@37660
|
2004 |
lemma unat_mod: "unat ((x :: 'a :: len word) mod y) = unat x mod unat y"
|
haftmann@37660
|
2005 |
apply (clarsimp simp add : unat_word_ariths)
|
haftmann@37660
|
2006 |
apply (cases "unat y")
|
haftmann@37660
|
2007 |
prefer 2
|
haftmann@37660
|
2008 |
apply (rule unat_lt2p [THEN xtr7, THEN nat_mod_eq'])
|
haftmann@37660
|
2009 |
apply (rule mod_le_divisor)
|
haftmann@37660
|
2010 |
apply auto
|
haftmann@37660
|
2011 |
done
|
haftmann@37660
|
2012 |
|
haftmann@37660
|
2013 |
lemma uint_div: "uint ((x :: 'a :: len word) div y) = uint x div uint y"
|
haftmann@37660
|
2014 |
unfolding uint_nat by (simp add : unat_div zdiv_int)
|
haftmann@37660
|
2015 |
|
haftmann@37660
|
2016 |
lemma uint_mod: "uint ((x :: 'a :: len word) mod y) = uint x mod uint y"
|
haftmann@37660
|
2017 |
unfolding uint_nat by (simp add : unat_mod zmod_int)
|
haftmann@37660
|
2018 |
|
haftmann@37660
|
2019 |
|
wenzelm@61799
|
2020 |
subsection \<open>Definition of \<open>unat_arith\<close> tactic\<close>
|
haftmann@37660
|
2021 |
|
haftmann@37660
|
2022 |
lemma unat_split:
|
haftmann@37660
|
2023 |
fixes x::"'a::len word"
|
haftmann@37660
|
2024 |
shows "P (unat x) =
|
haftmann@37660
|
2025 |
(ALL n. of_nat n = x & n < 2^len_of TYPE('a) --> P n)"
|
haftmann@37660
|
2026 |
by (auto simp: unat_of_nat)
|
haftmann@37660
|
2027 |
|
haftmann@37660
|
2028 |
lemma unat_split_asm:
|
haftmann@37660
|
2029 |
fixes x::"'a::len word"
|
haftmann@37660
|
2030 |
shows "P (unat x) =
|
haftmann@37660
|
2031 |
(~(EX n. of_nat n = x & n < 2^len_of TYPE('a) & ~ P n))"
|
haftmann@37660
|
2032 |
by (auto simp: unat_of_nat)
|
haftmann@37660
|
2033 |
|
haftmann@37660
|
2034 |
lemmas of_nat_inverse =
|
haftmann@37660
|
2035 |
word_unat.Abs_inverse' [rotated, unfolded unats_def, simplified]
|
haftmann@37660
|
2036 |
|
haftmann@37660
|
2037 |
lemmas unat_splits = unat_split unat_split_asm
|
haftmann@37660
|
2038 |
|
haftmann@37660
|
2039 |
lemmas unat_arith_simps =
|
haftmann@37660
|
2040 |
word_le_nat_alt word_less_nat_alt
|
haftmann@37660
|
2041 |
word_unat.Rep_inject [symmetric]
|
haftmann@37660
|
2042 |
unat_sub_if' unat_plus_if' unat_div unat_mod
|
haftmann@37660
|
2043 |
|
haftmann@37660
|
2044 |
(* unat_arith_tac: tactic to reduce word arithmetic to nat,
|
haftmann@37660
|
2045 |
try to solve via arith *)
|
wenzelm@61799
|
2046 |
ML \<open>
|
wenzelm@51717
|
2047 |
fun unat_arith_simpset ctxt =
|
wenzelm@51717
|
2048 |
ctxt addsimps @{thms unat_arith_simps}
|
haftmann@37660
|
2049 |
delsimps @{thms word_unat.Rep_inject}
|
wenzelm@45620
|
2050 |
|> fold Splitter.add_split @{thms split_if_asm}
|
wenzelm@45620
|
2051 |
|> fold Simplifier.add_cong @{thms power_False_cong}
|
haftmann@37660
|
2052 |
|
haftmann@37660
|
2053 |
fun unat_arith_tacs ctxt =
|
haftmann@37660
|
2054 |
let
|
haftmann@37660
|
2055 |
fun arith_tac' n t =
|
wenzelm@59657
|
2056 |
Arith_Data.arith_tac ctxt n t
|
haftmann@37660
|
2057 |
handle Cooper.COOPER _ => Seq.empty;
|
haftmann@37660
|
2058 |
in
|
wenzelm@42793
|
2059 |
[ clarify_tac ctxt 1,
|
wenzelm@51717
|
2060 |
full_simp_tac (unat_arith_simpset ctxt) 1,
|
wenzelm@51717
|
2061 |
ALLGOALS (full_simp_tac
|
wenzelm@51717
|
2062 |
(put_simpset HOL_ss ctxt
|
wenzelm@51717
|
2063 |
|> fold Splitter.add_split @{thms unat_splits}
|
wenzelm@51717
|
2064 |
|> fold Simplifier.add_cong @{thms power_False_cong})),
|
wenzelm@54742
|
2065 |
rewrite_goals_tac ctxt @{thms word_size},
|
wenzelm@60754
|
2066 |
ALLGOALS (fn n => REPEAT (resolve_tac ctxt [allI, impI] n) THEN
|
wenzelm@60754
|
2067 |
REPEAT (eresolve_tac ctxt [conjE] n) THEN
|
wenzelm@60754
|
2068 |
REPEAT (dresolve_tac ctxt @{thms of_nat_inverse} n THEN assume_tac ctxt n)),
|
haftmann@37660
|
2069 |
TRYALL arith_tac' ]
|
haftmann@37660
|
2070 |
end
|
haftmann@37660
|
2071 |
|
haftmann@37660
|
2072 |
fun unat_arith_tac ctxt = SELECT_GOAL (EVERY (unat_arith_tacs ctxt))
|
wenzelm@61799
|
2073 |
\<close>
|
haftmann@37660
|
2074 |
|
haftmann@37660
|
2075 |
method_setup unat_arith =
|
wenzelm@61799
|
2076 |
\<open>Scan.succeed (SIMPLE_METHOD' o unat_arith_tac)\<close>
|
haftmann@37660
|
2077 |
"solving word arithmetic via natural numbers and arith"
|
haftmann@37660
|
2078 |
|
haftmann@37660
|
2079 |
lemma no_plus_overflow_unat_size:
|
haftmann@37660
|
2080 |
"((x :: 'a :: len word) <= x + y) = (unat x + unat y < 2 ^ size x)"
|
haftmann@37660
|
2081 |
unfolding word_size by unat_arith
|
haftmann@37660
|
2082 |
|
haftmann@37660
|
2083 |
lemmas no_olen_add_nat = no_plus_overflow_unat_size [unfolded word_size]
|
haftmann@37660
|
2084 |
|
wenzelm@45604
|
2085 |
lemmas unat_plus_simple = trans [OF no_olen_add_nat unat_add_lem]
|
haftmann@37660
|
2086 |
|
haftmann@37660
|
2087 |
lemma word_div_mult:
|
haftmann@40827
|
2088 |
"(0 :: 'a :: len word) < y \<Longrightarrow> unat x * unat y < 2 ^ len_of TYPE('a) \<Longrightarrow>
|
haftmann@37660
|
2089 |
x * y div y = x"
|
haftmann@37660
|
2090 |
apply unat_arith
|
haftmann@37660
|
2091 |
apply clarsimp
|
haftmann@37660
|
2092 |
apply (subst unat_mult_lem [THEN iffD1])
|
haftmann@37660
|
2093 |
apply auto
|
haftmann@37660
|
2094 |
done
|
haftmann@37660
|
2095 |
|
haftmann@40827
|
2096 |
lemma div_lt': "(i :: 'a :: len word) <= k div x \<Longrightarrow>
|
haftmann@37660
|
2097 |
unat i * unat x < 2 ^ len_of TYPE('a)"
|
haftmann@37660
|
2098 |
apply unat_arith
|
haftmann@37660
|
2099 |
apply clarsimp
|
haftmann@37660
|
2100 |
apply (drule mult_le_mono1)
|
haftmann@37660
|
2101 |
apply (erule order_le_less_trans)
|
haftmann@37660
|
2102 |
apply (rule xtr7 [OF unat_lt2p div_mult_le])
|
haftmann@37660
|
2103 |
done
|
haftmann@37660
|
2104 |
|
haftmann@37660
|
2105 |
lemmas div_lt'' = order_less_imp_le [THEN div_lt']
|
haftmann@37660
|
2106 |
|
haftmann@40827
|
2107 |
lemma div_lt_mult: "(i :: 'a :: len word) < k div x \<Longrightarrow> 0 < x \<Longrightarrow> i * x < k"
|
haftmann@37660
|
2108 |
apply (frule div_lt'' [THEN unat_mult_lem [THEN iffD1]])
|
haftmann@37660
|
2109 |
apply (simp add: unat_arith_simps)
|
haftmann@37660
|
2110 |
apply (drule (1) mult_less_mono1)
|
haftmann@37660
|
2111 |
apply (erule order_less_le_trans)
|
haftmann@37660
|
2112 |
apply (rule div_mult_le)
|
haftmann@37660
|
2113 |
done
|
haftmann@37660
|
2114 |
|
haftmann@37660
|
2115 |
lemma div_le_mult:
|
haftmann@40827
|
2116 |
"(i :: 'a :: len word) <= k div x \<Longrightarrow> 0 < x \<Longrightarrow> i * x <= k"
|
haftmann@37660
|
2117 |
apply (frule div_lt' [THEN unat_mult_lem [THEN iffD1]])
|
haftmann@37660
|
2118 |
apply (simp add: unat_arith_simps)
|
haftmann@37660
|
2119 |
apply (drule mult_le_mono1)
|
haftmann@37660
|
2120 |
apply (erule order_trans)
|
haftmann@37660
|
2121 |
apply (rule div_mult_le)
|
haftmann@37660
|
2122 |
done
|
haftmann@37660
|
2123 |
|
haftmann@37660
|
2124 |
lemma div_lt_uint':
|
haftmann@40827
|
2125 |
"(i :: 'a :: len word) <= k div x \<Longrightarrow> uint i * uint x < 2 ^ len_of TYPE('a)"
|
haftmann@37660
|
2126 |
apply (unfold uint_nat)
|
haftmann@37660
|
2127 |
apply (drule div_lt')
|
lp15@61649
|
2128 |
by (metis of_nat_less_iff of_nat_mult of_nat_numeral of_nat_power)
|
haftmann@37660
|
2129 |
|
haftmann@37660
|
2130 |
lemmas div_lt_uint'' = order_less_imp_le [THEN div_lt_uint']
|
haftmann@37660
|
2131 |
|
haftmann@37660
|
2132 |
lemma word_le_exists':
|
haftmann@40827
|
2133 |
"(x :: 'a :: len0 word) <= y \<Longrightarrow>
|
haftmann@37660
|
2134 |
(EX z. y = x + z & uint x + uint z < 2 ^ len_of TYPE('a))"
|
haftmann@37660
|
2135 |
apply (rule exI)
|
haftmann@37660
|
2136 |
apply (rule conjI)
|
haftmann@37660
|
2137 |
apply (rule zadd_diff_inverse)
|
haftmann@37660
|
2138 |
apply uint_arith
|
haftmann@37660
|
2139 |
done
|
haftmann@37660
|
2140 |
|
haftmann@37660
|
2141 |
lemmas plus_minus_not_NULL = order_less_imp_le [THEN plus_minus_not_NULL_ab]
|
haftmann@37660
|
2142 |
|
haftmann@37660
|
2143 |
lemmas plus_minus_no_overflow =
|
haftmann@37660
|
2144 |
order_less_imp_le [THEN plus_minus_no_overflow_ab]
|
haftmann@37660
|
2145 |
|
haftmann@37660
|
2146 |
lemmas mcs = word_less_minus_cancel word_less_minus_mono_left
|
haftmann@37660
|
2147 |
word_le_minus_cancel word_le_minus_mono_left
|
haftmann@37660
|
2148 |
|
wenzelm@45604
|
2149 |
lemmas word_l_diffs = mcs [where y = "w + x", unfolded add_diff_cancel] for w x
|
wenzelm@45604
|
2150 |
lemmas word_diff_ls = mcs [where z = "w + x", unfolded add_diff_cancel] for w x
|
wenzelm@45604
|
2151 |
lemmas word_plus_mcs = word_diff_ls [where y = "v + x", unfolded add_diff_cancel] for v x
|
haftmann@37660
|
2152 |
|
haftmann@37660
|
2153 |
lemmas le_unat_uoi = unat_le [THEN word_unat.Abs_inverse]
|
haftmann@37660
|
2154 |
|
haftmann@37660
|
2155 |
lemmas thd = refl [THEN [2] split_div_lemma [THEN iffD2], THEN conjunct1]
|
haftmann@37660
|
2156 |
|
lp15@61649
|
2157 |
lemmas uno_simps [THEN le_unat_uoi] = mod_le_divisor div_le_dividend dtle
|
haftmann@37660
|
2158 |
|
haftmann@37660
|
2159 |
lemma word_mod_div_equality:
|
haftmann@37660
|
2160 |
"(n div b) * b + (n mod b) = (n :: 'a :: len word)"
|
haftmann@37660
|
2161 |
apply (unfold word_less_nat_alt word_arith_nat_defs)
|
haftmann@37660
|
2162 |
apply (cut_tac y="unat b" in gt_or_eq_0)
|
haftmann@37660
|
2163 |
apply (erule disjE)
|
lp15@61649
|
2164 |
apply (simp only: mod_div_equality uno_simps Word.word_unat.Rep_inverse)
|
haftmann@37660
|
2165 |
apply simp
|
haftmann@37660
|
2166 |
done
|
haftmann@37660
|
2167 |
|
haftmann@37660
|
2168 |
lemma word_div_mult_le: "a div b * b <= (a::'a::len word)"
|
haftmann@37660
|
2169 |
apply (unfold word_le_nat_alt word_arith_nat_defs)
|
haftmann@37660
|
2170 |
apply (cut_tac y="unat b" in gt_or_eq_0)
|
haftmann@37660
|
2171 |
apply (erule disjE)
|
lp15@61649
|
2172 |
apply (simp only: div_mult_le uno_simps Word.word_unat.Rep_inverse)
|
haftmann@37660
|
2173 |
apply simp
|
haftmann@37660
|
2174 |
done
|
haftmann@37660
|
2175 |
|
haftmann@40827
|
2176 |
lemma word_mod_less_divisor: "0 < n \<Longrightarrow> m mod n < (n :: 'a :: len word)"
|
haftmann@37660
|
2177 |
apply (simp only: word_less_nat_alt word_arith_nat_defs)
|
haftmann@37660
|
2178 |
apply (clarsimp simp add : uno_simps)
|
haftmann@37660
|
2179 |
done
|
haftmann@37660
|
2180 |
|
haftmann@37660
|
2181 |
lemma word_of_int_power_hom:
|
haftmann@37660
|
2182 |
"word_of_int a ^ n = (word_of_int (a ^ n) :: 'a :: len word)"
|
huffman@45995
|
2183 |
by (induct n) (simp_all add: wi_hom_mult [symmetric])
|
haftmann@37660
|
2184 |
|
haftmann@37660
|
2185 |
lemma word_arith_power_alt:
|
haftmann@37660
|
2186 |
"a ^ n = (word_of_int (uint a ^ n) :: 'a :: len word)"
|
haftmann@37660
|
2187 |
by (simp add : word_of_int_power_hom [symmetric])
|
haftmann@37660
|
2188 |
|
haftmann@37660
|
2189 |
lemma of_bl_length_less:
|
haftmann@40827
|
2190 |
"length x = k \<Longrightarrow> k < len_of TYPE('a) \<Longrightarrow> (of_bl x :: 'a :: len word) < 2 ^ k"
|
huffman@47108
|
2191 |
apply (unfold of_bl_def word_less_alt word_numeral_alt)
|
haftmann@37660
|
2192 |
apply safe
|
haftmann@37660
|
2193 |
apply (simp (no_asm) add: word_of_int_power_hom word_uint.eq_norm
|
huffman@47108
|
2194 |
del: word_of_int_numeral)
|
haftmann@37660
|
2195 |
apply (simp add: mod_pos_pos_trivial)
|
haftmann@37660
|
2196 |
apply (subst mod_pos_pos_trivial)
|
haftmann@37660
|
2197 |
apply (rule bl_to_bin_ge0)
|
haftmann@37660
|
2198 |
apply (rule order_less_trans)
|
haftmann@37660
|
2199 |
apply (rule bl_to_bin_lt2p)
|
haftmann@37660
|
2200 |
apply simp
|
huffman@46646
|
2201 |
apply (rule bl_to_bin_lt2p)
|
haftmann@37660
|
2202 |
done
|
haftmann@37660
|
2203 |
|
haftmann@37660
|
2204 |
|
wenzelm@61799
|
2205 |
subsection \<open>Cardinality, finiteness of set of words\<close>
|
haftmann@37660
|
2206 |
|
huffman@45809
|
2207 |
instance word :: (len0) finite
|
wenzelm@61169
|
2208 |
by standard (simp add: type_definition.univ [OF type_definition_word])
|
huffman@45809
|
2209 |
|
huffman@45809
|
2210 |
lemma card_word: "CARD('a::len0 word) = 2 ^ len_of TYPE('a)"
|
huffman@45809
|
2211 |
by (simp add: type_definition.card [OF type_definition_word] nat_power_eq)
|
haftmann@37660
|
2212 |
|
haftmann@37660
|
2213 |
lemma card_word_size:
|
huffman@45809
|
2214 |
"card (UNIV :: 'a :: len0 word set) = (2 ^ size (x :: 'a word))"
|
haftmann@37660
|
2215 |
unfolding word_size by (rule card_word)
|
haftmann@37660
|
2216 |
|
haftmann@37660
|
2217 |
|
wenzelm@61799
|
2218 |
subsection \<open>Bitwise Operations on Words\<close>
|
haftmann@37660
|
2219 |
|
haftmann@37660
|
2220 |
lemmas bin_log_bintrs = bin_trunc_not bin_trunc_xor bin_trunc_and bin_trunc_or
|
haftmann@37660
|
2221 |
|
haftmann@37660
|
2222 |
(* following definitions require both arithmetic and bit-wise word operations *)
|
haftmann@37660
|
2223 |
|
haftmann@37660
|
2224 |
(* to get word_no_log_defs from word_log_defs, using bin_log_bintrs *)
|
haftmann@37660
|
2225 |
lemmas wils1 = bin_log_bintrs [THEN word_ubin.norm_eq_iff [THEN iffD1],
|
wenzelm@45604
|
2226 |
folded word_ubin.eq_norm, THEN eq_reflection]
|
haftmann@37660
|
2227 |
|
haftmann@37660
|
2228 |
(* the binary operations only *)
|
huffman@46013
|
2229 |
(* BH: why is this needed? *)
|
haftmann@37660
|
2230 |
lemmas word_log_binary_defs =
|
haftmann@37660
|
2231 |
word_and_def word_or_def word_xor_def
|
haftmann@37660
|
2232 |
|
huffman@46011
|
2233 |
lemma word_wi_log_defs:
|
huffman@46011
|
2234 |
"NOT word_of_int a = word_of_int (NOT a)"
|
huffman@46011
|
2235 |
"word_of_int a AND word_of_int b = word_of_int (a AND b)"
|
huffman@46011
|
2236 |
"word_of_int a OR word_of_int b = word_of_int (a OR b)"
|
huffman@46011
|
2237 |
"word_of_int a XOR word_of_int b = word_of_int (a XOR b)"
|
huffman@47374
|
2238 |
by (transfer, rule refl)+
|
huffman@47372
|
2239 |
|
huffman@46011
|
2240 |
lemma word_no_log_defs [simp]:
|
huffman@47108
|
2241 |
"NOT (numeral a) = word_of_int (NOT (numeral a))"
|
haftmann@54489
|
2242 |
"NOT (- numeral a) = word_of_int (NOT (- numeral a))"
|
huffman@47108
|
2243 |
"numeral a AND numeral b = word_of_int (numeral a AND numeral b)"
|
haftmann@54489
|
2244 |
"numeral a AND - numeral b = word_of_int (numeral a AND - numeral b)"
|
haftmann@54489
|
2245 |
"- numeral a AND numeral b = word_of_int (- numeral a AND numeral b)"
|
haftmann@54489
|
2246 |
"- numeral a AND - numeral b = word_of_int (- numeral a AND - numeral b)"
|
huffman@47108
|
2247 |
"numeral a OR numeral b = word_of_int (numeral a OR numeral b)"
|
haftmann@54489
|
2248 |
"numeral a OR - numeral b = word_of_int (numeral a OR - numeral b)"
|
haftmann@54489
|
2249 |
"- numeral a OR numeral b = word_of_int (- numeral a OR numeral b)"
|
haftmann@54489
|
2250 |
"- numeral a OR - numeral b = word_of_int (- numeral a OR - numeral b)"
|
huffman@47108
|
2251 |
"numeral a XOR numeral b = word_of_int (numeral a XOR numeral b)"
|
haftmann@54489
|
2252 |
"numeral a XOR - numeral b = word_of_int (numeral a XOR - numeral b)"
|
haftmann@54489
|
2253 |
"- numeral a XOR numeral b = word_of_int (- numeral a XOR numeral b)"
|
haftmann@54489
|
2254 |
"- numeral a XOR - numeral b = word_of_int (- numeral a XOR - numeral b)"
|
huffman@47372
|
2255 |
by (transfer, rule refl)+
|
haftmann@37660
|
2256 |
|
wenzelm@61799
|
2257 |
text \<open>Special cases for when one of the arguments equals 1.\<close>
|
huffman@46064
|
2258 |
|
huffman@46064
|
2259 |
lemma word_bitwise_1_simps [simp]:
|
huffman@46064
|
2260 |
"NOT (1::'a::len0 word) = -2"
|
huffman@47108
|
2261 |
"1 AND numeral b = word_of_int (1 AND numeral b)"
|
haftmann@54489
|
2262 |
"1 AND - numeral b = word_of_int (1 AND - numeral b)"
|
huffman@47108
|
2263 |
"numeral a AND 1 = word_of_int (numeral a AND 1)"
|
haftmann@54489
|
2264 |
"- numeral a AND 1 = word_of_int (- numeral a AND 1)"
|
huffman@47108
|
2265 |
"1 OR numeral b = word_of_int (1 OR numeral b)"
|
haftmann@54489
|
2266 |
"1 OR - numeral b = word_of_int (1 OR - numeral b)"
|
huffman@47108
|
2267 |
"numeral a OR 1 = word_of_int (numeral a OR 1)"
|
haftmann@54489
|
2268 |
"- numeral a OR 1 = word_of_int (- numeral a OR 1)"
|
huffman@47108
|
2269 |
"1 XOR numeral b = word_of_int (1 XOR numeral b)"
|
haftmann@54489
|
2270 |
"1 XOR - numeral b = word_of_int (1 XOR - numeral b)"
|
huffman@47108
|
2271 |
"numeral a XOR 1 = word_of_int (numeral a XOR 1)"
|
haftmann@54489
|
2272 |
"- numeral a XOR 1 = word_of_int (- numeral a XOR 1)"
|
huffman@47372
|
2273 |
by (transfer, simp)+
|
huffman@46064
|
2274 |
|
wenzelm@61799
|
2275 |
text \<open>Special cases for when one of the arguments equals -1.\<close>
|
noschinl@56979
|
2276 |
|
noschinl@56979
|
2277 |
lemma word_bitwise_m1_simps [simp]:
|
noschinl@56979
|
2278 |
"NOT (-1::'a::len0 word) = 0"
|
noschinl@56979
|
2279 |
"(-1::'a::len0 word) AND x = x"
|
noschinl@56979
|
2280 |
"x AND (-1::'a::len0 word) = x"
|
noschinl@56979
|
2281 |
"(-1::'a::len0 word) OR x = -1"
|
noschinl@56979
|
2282 |
"x OR (-1::'a::len0 word) = -1"
|
noschinl@56979
|
2283 |
" (-1::'a::len0 word) XOR x = NOT x"
|
noschinl@56979
|
2284 |
"x XOR (-1::'a::len0 word) = NOT x"
|
noschinl@56979
|
2285 |
by (transfer, simp)+
|
noschinl@56979
|
2286 |
|
haftmann@37660
|
2287 |
lemma uint_or: "uint (x OR y) = (uint x) OR (uint y)"
|
huffman@47372
|
2288 |
by (transfer, simp add: bin_trunc_ao)
|
haftmann@37660
|
2289 |
|
haftmann@37660
|
2290 |
lemma uint_and: "uint (x AND y) = (uint x) AND (uint y)"
|
huffman@47372
|
2291 |
by (transfer, simp add: bin_trunc_ao)
|
huffman@47372
|
2292 |
|
huffman@47372
|
2293 |
lemma test_bit_wi [simp]:
|
huffman@47372
|
2294 |
"(word_of_int x::'a::len0 word) !! n \<longleftrightarrow> n < len_of TYPE('a) \<and> bin_nth x n"
|
huffman@47372
|
2295 |
unfolding word_test_bit_def
|
huffman@47372
|
2296 |
by (simp add: word_ubin.eq_norm nth_bintr)
|
huffman@47372
|
2297 |
|
huffman@47372
|
2298 |
lemma word_test_bit_transfer [transfer_rule]:
|
blanchet@55945
|
2299 |
"(rel_fun pcr_word (rel_fun op = op =))
|
huffman@47372
|
2300 |
(\<lambda>x n. n < len_of TYPE('a) \<and> bin_nth x n) (test_bit :: 'a::len0 word \<Rightarrow> _)"
|
blanchet@55945
|
2301 |
unfolding rel_fun_def word.pcr_cr_eq cr_word_def by simp
|
haftmann@37660
|
2302 |
|
haftmann@37660
|
2303 |
lemma word_ops_nth_size:
|
haftmann@40827
|
2304 |
"n < size (x::'a::len0 word) \<Longrightarrow>
|
haftmann@37660
|
2305 |
(x OR y) !! n = (x !! n | y !! n) &
|
haftmann@37660
|
2306 |
(x AND y) !! n = (x !! n & y !! n) &
|
haftmann@37660
|
2307 |
(x XOR y) !! n = (x !! n ~= y !! n) &
|
haftmann@37660
|
2308 |
(NOT x) !! n = (~ x !! n)"
|
huffman@47372
|
2309 |
unfolding word_size by transfer (simp add: bin_nth_ops)
|
haftmann@37660
|
2310 |
|
haftmann@37660
|
2311 |
lemma word_ao_nth:
|
haftmann@37660
|
2312 |
fixes x :: "'a::len0 word"
|
haftmann@37660
|
2313 |
shows "(x OR y) !! n = (x !! n | y !! n) &
|
haftmann@37660
|
2314 |
(x AND y) !! n = (x !! n & y !! n)"
|
huffman@47372
|
2315 |
by transfer (auto simp add: bin_nth_ops)
|
huffman@46023
|
2316 |
|
huffman@47108
|
2317 |
lemma test_bit_numeral [simp]:
|
huffman@47108
|
2318 |
"(numeral w :: 'a::len0 word) !! n \<longleftrightarrow>
|
huffman@47108
|
2319 |
n < len_of TYPE('a) \<and> bin_nth (numeral w) n"
|
huffman@47372
|
2320 |
by transfer (rule refl)
|
huffman@47108
|
2321 |
|
huffman@47108
|
2322 |
lemma test_bit_neg_numeral [simp]:
|
haftmann@54489
|
2323 |
"(- numeral w :: 'a::len0 word) !! n \<longleftrightarrow>
|
haftmann@54489
|
2324 |
n < len_of TYPE('a) \<and> bin_nth (- numeral w) n"
|
huffman@47372
|
2325 |
by transfer (rule refl)
|
huffman@46023
|
2326 |
|
huffman@46172
|
2327 |
lemma test_bit_1 [simp]: "(1::'a::len word) !! n \<longleftrightarrow> n = 0"
|
huffman@47372
|
2328 |
by transfer auto
|
huffman@46172
|
2329 |
|
huffman@46023
|
2330 |
lemma nth_0 [simp]: "~ (0::'a::len0 word) !! n"
|
huffman@47372
|
2331 |
by transfer simp
|
huffman@46023
|
2332 |
|
huffman@47108
|
2333 |
lemma nth_minus1 [simp]: "(-1::'a::len0 word) !! n \<longleftrightarrow> n < len_of TYPE('a)"
|
huffman@47372
|
2334 |
by transfer simp
|
huffman@47108
|
2335 |
|
haftmann@37660
|
2336 |
(* get from commutativity, associativity etc of int_and etc
|
haftmann@37660
|
2337 |
to same for word_and etc *)
|
haftmann@37660
|
2338 |
|
haftmann@37660
|
2339 |
lemmas bwsimps =
|
huffman@46013
|
2340 |
wi_hom_add
|
haftmann@37660
|
2341 |
word_wi_log_defs
|
haftmann@37660
|
2342 |
|
haftmann@37660
|
2343 |
lemma word_bw_assocs:
|
haftmann@37660
|
2344 |
fixes x :: "'a::len0 word"
|
haftmann@37660
|
2345 |
shows
|
haftmann@37660
|
2346 |
"(x AND y) AND z = x AND y AND z"
|
haftmann@37660
|
2347 |
"(x OR y) OR z = x OR y OR z"
|
haftmann@37660
|
2348 |
"(x XOR y) XOR z = x XOR y XOR z"
|
huffman@46022
|
2349 |
by (auto simp: word_eq_iff word_ops_nth_size [unfolded word_size])
|
haftmann@37660
|
2350 |
|
haftmann@37660
|
2351 |
lemma word_bw_comms:
|
haftmann@37660
|
2352 |
fixes x :: "'a::len0 word"
|
haftmann@37660
|
2353 |
shows
|
haftmann@37660
|
2354 |
"x AND y = y AND x"
|
haftmann@37660
|
2355 |
"x OR y = y OR x"
|
haftmann@37660
|
2356 |
"x XOR y = y XOR x"
|
huffman@46022
|
2357 |
by (auto simp: word_eq_iff word_ops_nth_size [unfolded word_size])
|
haftmann@37660
|
2358 |
|
haftmann@37660
|
2359 |
lemma word_bw_lcs:
|
haftmann@37660
|
2360 |
fixes x :: "'a::len0 word"
|
haftmann@37660
|
2361 |
shows
|
haftmann@37660
|
2362 |
"y AND x AND z = x AND y AND z"
|
haftmann@37660
|
2363 |
"y OR x OR z = x OR y OR z"
|
haftmann@37660
|
2364 |
"y XOR x XOR z = x XOR y XOR z"
|
huffman@46022
|
2365 |
by (auto simp: word_eq_iff word_ops_nth_size [unfolded word_size])
|
haftmann@37660
|
2366 |
|
haftmann@37660
|
2367 |
lemma word_log_esimps [simp]:
|
haftmann@37660
|
2368 |
fixes x :: "'a::len0 word"
|
haftmann@37660
|
2369 |
shows
|
haftmann@37660
|
2370 |
"x AND 0 = 0"
|
haftmann@37660
|
2371 |
"x AND -1 = x"
|
haftmann@37660
|
2372 |
"x OR 0 = x"
|
haftmann@37660
|
2373 |
"x OR -1 = -1"
|
haftmann@37660
|
2374 |
"x XOR 0 = x"
|
haftmann@37660
|
2375 |
"x XOR -1 = NOT x"
|
haftmann@37660
|
2376 |
"0 AND x = 0"
|
haftmann@37660
|
2377 |
"-1 AND x = x"
|
haftmann@37660
|
2378 |
"0 OR x = x"
|
haftmann@37660
|
2379 |
"-1 OR x = -1"
|
haftmann@37660
|
2380 |
"0 XOR x = x"
|
haftmann@37660
|
2381 |
"-1 XOR x = NOT x"
|
huffman@46023
|
2382 |
by (auto simp: word_eq_iff word_ops_nth_size [unfolded word_size])
|
haftmann@37660
|
2383 |
|
haftmann@37660
|
2384 |
lemma word_not_dist:
|
haftmann@37660
|
2385 |
fixes x :: "'a::len0 word"
|
haftmann@37660
|
2386 |
shows
|
haftmann@37660
|
2387 |
"NOT (x OR y) = NOT x AND NOT y"
|
haftmann@37660
|
2388 |
"NOT (x AND y) = NOT x OR NOT y"
|
huffman@46022
|
2389 |
by (auto simp: word_eq_iff word_ops_nth_size [unfolded word_size])
|
haftmann@37660
|
2390 |
|
haftmann@37660
|
2391 |
lemma word_bw_same:
|
haftmann@37660
|
2392 |
fixes x :: "'a::len0 word"
|
haftmann@37660
|
2393 |
shows
|
haftmann@37660
|
2394 |
"x AND x = x"
|
haftmann@37660
|
2395 |
"x OR x = x"
|
haftmann@37660
|
2396 |
"x XOR x = 0"
|
huffman@46023
|
2397 |
by (auto simp: word_eq_iff word_ops_nth_size [unfolded word_size])
|
haftmann@37660
|
2398 |
|
haftmann@37660
|
2399 |
lemma word_ao_absorbs [simp]:
|
haftmann@37660
|
2400 |
fixes x :: "'a::len0 word"
|
haftmann@37660
|
2401 |
shows
|
haftmann@37660
|
2402 |
"x AND (y OR x) = x"
|
haftmann@37660
|
2403 |
"x OR y AND x = x"
|
haftmann@37660
|
2404 |
"x AND (x OR y) = x"
|
haftmann@37660
|
2405 |
"y AND x OR x = x"
|
haftmann@37660
|
2406 |
"(y OR x) AND x = x"
|
haftmann@37660
|
2407 |
"x OR x AND y = x"
|
haftmann@37660
|
2408 |
"(x OR y) AND x = x"
|
haftmann@37660
|
2409 |
"x AND y OR x = x"
|
huffman@46022
|
2410 |
by (auto simp: word_eq_iff word_ops_nth_size [unfolded word_size])
|
haftmann@37660
|
2411 |
|
haftmann@37660
|
2412 |
lemma word_not_not [simp]:
|
haftmann@37660
|
2413 |
"NOT NOT (x::'a::len0 word) = x"
|
huffman@46022
|
2414 |
by (auto simp: word_eq_iff word_ops_nth_size [unfolded word_size])
|
haftmann@37660
|
2415 |
|
haftmann@37660
|
2416 |
lemma word_ao_dist:
|
haftmann@37660
|
2417 |
fixes x :: "'a::len0 word"
|
haftmann@37660
|
2418 |
shows "(x OR y) AND z = x AND z OR y AND z"
|
huffman@46022
|
2419 |
by (auto simp: word_eq_iff word_ops_nth_size [unfolded word_size])
|
haftmann@37660
|
2420 |
|
haftmann@37660
|
2421 |
lemma word_oa_dist:
|
haftmann@37660
|
2422 |
fixes x :: "'a::len0 word"
|
haftmann@37660
|
2423 |
shows "x AND y OR z = (x OR z) AND (y OR z)"
|
huffman@46022
|
2424 |
by (auto simp: word_eq_iff word_ops_nth_size [unfolded word_size])
|
haftmann@37660
|
2425 |
|
haftmann@37660
|
2426 |
lemma word_add_not [simp]:
|
haftmann@37660
|
2427 |
fixes x :: "'a::len0 word"
|
haftmann@37660
|
2428 |
shows "x + NOT x = -1"
|
huffman@47372
|
2429 |
by transfer (simp add: bin_add_not)
|
haftmann@37660
|
2430 |
|
haftmann@37660
|
2431 |
lemma word_plus_and_or [simp]:
|
haftmann@37660
|
2432 |
fixes x :: "'a::len0 word"
|
haftmann@37660
|
2433 |
shows "(x AND y) + (x OR y) = x + y"
|
huffman@47372
|
2434 |
by transfer (simp add: plus_and_or)
|
haftmann@37660
|
2435 |
|
haftmann@37660
|
2436 |
lemma leoa:
|
haftmann@37660
|
2437 |
fixes x :: "'a::len0 word"
|
haftmann@40827
|
2438 |
shows "(w = (x OR y)) \<Longrightarrow> (y = (w AND y))" by auto
|
haftmann@37660
|
2439 |
lemma leao:
|
haftmann@37660
|
2440 |
fixes x' :: "'a::len0 word"
|
haftmann@40827
|
2441 |
shows "(w' = (x' AND y')) \<Longrightarrow> (x' = (x' OR w'))" by auto
|
haftmann@37660
|
2442 |
|
wenzelm@48196
|
2443 |
lemma word_ao_equiv:
|
wenzelm@48196
|
2444 |
fixes w w' :: "'a::len0 word"
|
wenzelm@48196
|
2445 |
shows "(w = w OR w') = (w' = w AND w')"
|
wenzelm@48196
|
2446 |
by (auto intro: leoa leao)
|
haftmann@37660
|
2447 |
|
haftmann@37660
|
2448 |
lemma le_word_or2: "x <= x OR (y::'a::len0 word)"
|
haftmann@37660
|
2449 |
unfolding word_le_def uint_or
|
haftmann@37660
|
2450 |
by (auto intro: le_int_or)
|
haftmann@37660
|
2451 |
|
wenzelm@45604
|
2452 |
lemmas le_word_or1 = xtr3 [OF word_bw_comms (2) le_word_or2]
|
wenzelm@45604
|
2453 |
lemmas word_and_le1 = xtr3 [OF word_ao_absorbs (4) [symmetric] le_word_or2]
|
wenzelm@45604
|
2454 |
lemmas word_and_le2 = xtr3 [OF word_ao_absorbs (8) [symmetric] le_word_or2]
|
haftmann@37660
|
2455 |
|
haftmann@37660
|
2456 |
lemma bl_word_not: "to_bl (NOT w) = map Not (to_bl w)"
|
huffman@45550
|
2457 |
unfolding to_bl_def word_log_defs bl_not_bin
|
huffman@45550
|
2458 |
by (simp add: word_ubin.eq_norm)
|
haftmann@37660
|
2459 |
|
haftmann@37660
|
2460 |
lemma bl_word_xor: "to_bl (v XOR w) = map2 op ~= (to_bl v) (to_bl w)"
|
haftmann@37660
|
2461 |
unfolding to_bl_def word_log_defs bl_xor_bin
|
huffman@45550
|
2462 |
by (simp add: word_ubin.eq_norm)
|
haftmann@37660
|
2463 |
|
haftmann@37660
|
2464 |
lemma bl_word_or: "to_bl (v OR w) = map2 op | (to_bl v) (to_bl w)"
|
huffman@45550
|
2465 |
unfolding to_bl_def word_log_defs bl_or_bin
|
huffman@45550
|
2466 |
by (simp add: word_ubin.eq_norm)
|
haftmann@37660
|
2467 |
|
haftmann@37660
|
2468 |
lemma bl_word_and: "to_bl (v AND w) = map2 op & (to_bl v) (to_bl w)"
|
huffman@45550
|
2469 |
unfolding to_bl_def word_log_defs bl_and_bin
|
huffman@45550
|
2470 |
by (simp add: word_ubin.eq_norm)
|
haftmann@37660
|
2471 |
|
haftmann@37660
|
2472 |
lemma word_lsb_alt: "lsb (w::'a::len0 word) = test_bit w 0"
|
haftmann@37660
|
2473 |
by (auto simp: word_test_bit_def word_lsb_def)
|
haftmann@37660
|
2474 |
|
huffman@45805
|
2475 |
lemma word_lsb_1_0 [simp]: "lsb (1::'a::len word) & ~ lsb (0::'b::len0 word)"
|
huffman@45550
|
2476 |
unfolding word_lsb_def uint_eq_0 uint_1 by simp
|
haftmann@37660
|
2477 |
|
haftmann@37660
|
2478 |
lemma word_lsb_last: "lsb (w::'a::len word) = last (to_bl w)"
|
haftmann@37660
|
2479 |
apply (unfold word_lsb_def uint_bl bin_to_bl_def)
|
haftmann@37660
|
2480 |
apply (rule_tac bin="uint w" in bin_exhaust)
|
haftmann@37660
|
2481 |
apply (cases "size w")
|
haftmann@37660
|
2482 |
apply auto
|
haftmann@37660
|
2483 |
apply (auto simp add: bin_to_bl_aux_alt)
|
haftmann@37660
|
2484 |
done
|
haftmann@37660
|
2485 |
|
haftmann@37660
|
2486 |
lemma word_lsb_int: "lsb w = (uint w mod 2 = 1)"
|
huffman@45529
|
2487 |
unfolding word_lsb_def bin_last_def by auto
|
haftmann@37660
|
2488 |
|
haftmann@37660
|
2489 |
lemma word_msb_sint: "msb w = (sint w < 0)"
|
huffman@46604
|
2490 |
unfolding word_msb_def sign_Min_lt_0 ..
|
haftmann@37660
|
2491 |
|
huffman@46173
|
2492 |
lemma msb_word_of_int:
|
huffman@46173
|
2493 |
"msb (word_of_int x::'a::len word) = bin_nth x (len_of TYPE('a) - 1)"
|
huffman@46173
|
2494 |
unfolding word_msb_def by (simp add: word_sbin.eq_norm bin_sign_lem)
|
huffman@46173
|
2495 |
|
huffman@47108
|
2496 |
lemma word_msb_numeral [simp]:
|
huffman@47108
|
2497 |
"msb (numeral w::'a::len word) = bin_nth (numeral w) (len_of TYPE('a) - 1)"
|
huffman@47108
|
2498 |
unfolding word_numeral_alt by (rule msb_word_of_int)
|
huffman@47108
|
2499 |
|
huffman@47108
|
2500 |
lemma word_msb_neg_numeral [simp]:
|
haftmann@54489
|
2501 |
"msb (- numeral w::'a::len word) = bin_nth (- numeral w) (len_of TYPE('a) - 1)"
|
huffman@47108
|
2502 |
unfolding word_neg_numeral_alt by (rule msb_word_of_int)
|
huffman@46173
|
2503 |
|
huffman@46173
|
2504 |
lemma word_msb_0 [simp]: "\<not> msb (0::'a::len word)"
|
huffman@46173
|
2505 |
unfolding word_msb_def by simp
|
huffman@46173
|
2506 |
|
huffman@46173
|
2507 |
lemma word_msb_1 [simp]: "msb (1::'a::len word) \<longleftrightarrow> len_of TYPE('a) = 1"
|
huffman@46173
|
2508 |
unfolding word_1_wi msb_word_of_int eq_iff [where 'a=nat]
|
huffman@46173
|
2509 |
by (simp add: Suc_le_eq)
|
huffman@45811
|
2510 |
|
huffman@45811
|
2511 |
lemma word_msb_nth:
|
huffman@45811
|
2512 |
"msb (w::'a::len word) = bin_nth (uint w) (len_of TYPE('a) - 1)"
|
huffman@46023
|
2513 |
unfolding word_msb_def sint_uint by (simp add: bin_sign_lem)
|
haftmann@37660
|
2514 |
|
haftmann@37660
|
2515 |
lemma word_msb_alt: "msb (w::'a::len word) = hd (to_bl w)"
|
haftmann@37660
|
2516 |
apply (unfold word_msb_nth uint_bl)
|
haftmann@37660
|
2517 |
apply (subst hd_conv_nth)
|
haftmann@37660
|
2518 |
apply (rule length_greater_0_conv [THEN iffD1])
|
haftmann@37660
|
2519 |
apply simp
|
haftmann@37660
|
2520 |
apply (simp add : nth_bin_to_bl word_size)
|
haftmann@37660
|
2521 |
done
|
haftmann@37660
|
2522 |
|
huffman@45805
|
2523 |
lemma word_set_nth [simp]:
|
haftmann@37660
|
2524 |
"set_bit w n (test_bit w n) = (w::'a::len0 word)"
|
haftmann@37660
|
2525 |
unfolding word_test_bit_def word_set_bit_def by auto
|
haftmann@37660
|
2526 |
|
haftmann@37660
|
2527 |
lemma bin_nth_uint':
|
haftmann@37660
|
2528 |
"bin_nth (uint w) n = (rev (bin_to_bl (size w) (uint w)) ! n & n < size w)"
|
haftmann@37660
|
2529 |
apply (unfold word_size)
|
haftmann@37660
|
2530 |
apply (safe elim!: bin_nth_uint_imp)
|
haftmann@37660
|
2531 |
apply (frule bin_nth_uint_imp)
|
haftmann@37660
|
2532 |
apply (fast dest!: bin_nth_bl)+
|
haftmann@37660
|
2533 |
done
|
haftmann@37660
|
2534 |
|
haftmann@37660
|
2535 |
lemmas bin_nth_uint = bin_nth_uint' [unfolded word_size]
|
haftmann@37660
|
2536 |
|
haftmann@37660
|
2537 |
lemma test_bit_bl: "w !! n = (rev (to_bl w) ! n & n < size w)"
|
haftmann@37660
|
2538 |
unfolding to_bl_def word_test_bit_def word_size
|
haftmann@37660
|
2539 |
by (rule bin_nth_uint)
|
haftmann@37660
|
2540 |
|
haftmann@40827
|
2541 |
lemma to_bl_nth: "n < size w \<Longrightarrow> to_bl w ! n = w !! (size w - Suc n)"
|
haftmann@37660
|
2542 |
apply (unfold test_bit_bl)
|
haftmann@37660
|
2543 |
apply clarsimp
|
haftmann@37660
|
2544 |
apply (rule trans)
|
haftmann@37660
|
2545 |
apply (rule nth_rev_alt)
|
haftmann@37660
|
2546 |
apply (auto simp add: word_size)
|
haftmann@37660
|
2547 |
done
|
haftmann@37660
|
2548 |
|
haftmann@37660
|
2549 |
lemma test_bit_set:
|
haftmann@37660
|
2550 |
fixes w :: "'a::len0 word"
|
haftmann@37660
|
2551 |
shows "(set_bit w n x) !! n = (n < size w & x)"
|
haftmann@37660
|
2552 |
unfolding word_size word_test_bit_def word_set_bit_def
|
haftmann@37660
|
2553 |
by (clarsimp simp add : word_ubin.eq_norm nth_bintr)
|
haftmann@37660
|
2554 |
|
haftmann@37660
|
2555 |
lemma test_bit_set_gen:
|
haftmann@37660
|
2556 |
fixes w :: "'a::len0 word"
|
haftmann@37660
|
2557 |
shows "test_bit (set_bit w n x) m =
|
haftmann@37660
|
2558 |
(if m = n then n < size w & x else test_bit w m)"
|
haftmann@37660
|
2559 |
apply (unfold word_size word_test_bit_def word_set_bit_def)
|
haftmann@37660
|
2560 |
apply (clarsimp simp add: word_ubin.eq_norm nth_bintr bin_nth_sc_gen)
|
haftmann@37660
|
2561 |
apply (auto elim!: test_bit_size [unfolded word_size]
|
haftmann@37660
|
2562 |
simp add: word_test_bit_def [symmetric])
|
haftmann@37660
|
2563 |
done
|
haftmann@37660
|
2564 |
|
haftmann@37660
|
2565 |
lemma of_bl_rep_False: "of_bl (replicate n False @ bs) = of_bl bs"
|
haftmann@37660
|
2566 |
unfolding of_bl_def bl_to_bin_rep_F by auto
|
haftmann@37660
|
2567 |
|
huffman@45811
|
2568 |
lemma msb_nth:
|
haftmann@37660
|
2569 |
fixes w :: "'a::len word"
|
huffman@45811
|
2570 |
shows "msb w = w !! (len_of TYPE('a) - 1)"
|
huffman@45811
|
2571 |
unfolding word_msb_nth word_test_bit_def by simp
|
haftmann@37660
|
2572 |
|
wenzelm@45604
|
2573 |
lemmas msb0 = len_gt_0 [THEN diff_Suc_less, THEN word_ops_nth_size [unfolded word_size]]
|
haftmann@37660
|
2574 |
lemmas msb1 = msb0 [where i = 0]
|
haftmann@37660
|
2575 |
lemmas word_ops_msb = msb1 [unfolded msb_nth [symmetric, unfolded One_nat_def]]
|
haftmann@37660
|
2576 |
|
wenzelm@45604
|
2577 |
lemmas lsb0 = len_gt_0 [THEN word_ops_nth_size [unfolded word_size]]
|
haftmann@37660
|
2578 |
lemmas word_ops_lsb = lsb0 [unfolded word_lsb_alt]
|
haftmann@37660
|
2579 |
|
huffman@45811
|
2580 |
lemma td_ext_nth [OF refl refl refl, unfolded word_size]:
|
haftmann@40827
|
2581 |
"n = size (w::'a::len0 word) \<Longrightarrow> ofn = set_bits \<Longrightarrow> [w, ofn g] = l \<Longrightarrow>
|
haftmann@37660
|
2582 |
td_ext test_bit ofn {f. ALL i. f i --> i < n} (%h i. h i & i < n)"
|
haftmann@37660
|
2583 |
apply (unfold word_size td_ext_def')
|
wenzelm@46008
|
2584 |
apply safe
|
haftmann@37660
|
2585 |
apply (rule_tac [3] ext)
|
haftmann@37660
|
2586 |
apply (rule_tac [4] ext)
|
haftmann@37660
|
2587 |
apply (unfold word_size of_nth_def test_bit_bl)
|
haftmann@37660
|
2588 |
apply safe
|
haftmann@37660
|
2589 |
defer
|
haftmann@37660
|
2590 |
apply (clarsimp simp: word_bl.Abs_inverse)+
|
haftmann@37660
|
2591 |
apply (rule word_bl.Rep_inverse')
|
haftmann@37660
|
2592 |
apply (rule sym [THEN trans])
|
haftmann@37660
|
2593 |
apply (rule bl_of_nth_nth)
|
haftmann@37660
|
2594 |
apply simp
|
haftmann@37660
|
2595 |
apply (rule bl_of_nth_inj)
|
haftmann@37660
|
2596 |
apply (clarsimp simp add : test_bit_bl word_size)
|
haftmann@37660
|
2597 |
done
|
haftmann@37660
|
2598 |
|
haftmann@37660
|
2599 |
interpretation test_bit:
|
haftmann@37660
|
2600 |
td_ext "op !! :: 'a::len0 word => nat => bool"
|
|