46 end |
46 end |
47 |
47 |
48 lemma card_UNIV_nibble: |
48 lemma card_UNIV_nibble: |
49 "card (UNIV :: nibble set) = 16" |
49 "card (UNIV :: nibble set) = 16" |
50 by (simp add: card_UNIV_length_enum enum_nibble_def) |
50 by (simp add: card_UNIV_length_enum enum_nibble_def) |
|
51 |
|
52 primrec nat_of_nibble :: "nibble \<Rightarrow> nat" |
|
53 where |
|
54 "nat_of_nibble Nibble0 = 0" |
|
55 | "nat_of_nibble Nibble1 = 1" |
|
56 | "nat_of_nibble Nibble2 = 2" |
|
57 | "nat_of_nibble Nibble3 = 3" |
|
58 | "nat_of_nibble Nibble4 = 4" |
|
59 | "nat_of_nibble Nibble5 = 5" |
|
60 | "nat_of_nibble Nibble6 = 6" |
|
61 | "nat_of_nibble Nibble7 = 7" |
|
62 | "nat_of_nibble Nibble8 = 8" |
|
63 | "nat_of_nibble Nibble9 = 9" |
|
64 | "nat_of_nibble NibbleA = 10" |
|
65 | "nat_of_nibble NibbleB = 11" |
|
66 | "nat_of_nibble NibbleC = 12" |
|
67 | "nat_of_nibble NibbleD = 13" |
|
68 | "nat_of_nibble NibbleE = 14" |
|
69 | "nat_of_nibble NibbleF = 15" |
|
70 |
|
71 definition nibble_of_nat :: "nat \<Rightarrow> nibble" where |
|
72 "nibble_of_nat n = Enum.enum ! (n mod 16)" |
|
73 |
|
74 lemma nibble_of_nat_simps [simp]: |
|
75 "nibble_of_nat 0 = Nibble0" |
|
76 "nibble_of_nat 1 = Nibble1" |
|
77 "nibble_of_nat 2 = Nibble2" |
|
78 "nibble_of_nat 3 = Nibble3" |
|
79 "nibble_of_nat 4 = Nibble4" |
|
80 "nibble_of_nat 5 = Nibble5" |
|
81 "nibble_of_nat 6 = Nibble6" |
|
82 "nibble_of_nat 7 = Nibble7" |
|
83 "nibble_of_nat 8 = Nibble8" |
|
84 "nibble_of_nat 9 = Nibble9" |
|
85 "nibble_of_nat 10 = NibbleA" |
|
86 "nibble_of_nat 11 = NibbleB" |
|
87 "nibble_of_nat 12 = NibbleC" |
|
88 "nibble_of_nat 13 = NibbleD" |
|
89 "nibble_of_nat 14 = NibbleE" |
|
90 "nibble_of_nat 15 = NibbleF" |
|
91 unfolding nibble_of_nat_def by (simp_all add: enum_nibble_def) |
|
92 |
|
93 lemma nibble_of_nat_of_nibble [simp]: |
|
94 "nibble_of_nat (nat_of_nibble x) = x" |
|
95 by (cases x) (simp_all add: nibble_of_nat_def enum_nibble_def) |
|
96 |
|
97 lemma nat_of_nibble_of_nat [simp]: |
|
98 "nat_of_nibble (nibble_of_nat n) = n mod 16" |
|
99 by (cases "nibble_of_nat n") |
|
100 (simp_all add: nibble_of_nat_def enum_nibble_def nth_equal_first_eq nth_non_equal_first_eq, arith) |
|
101 |
|
102 lemma inj_nat_of_nibble: |
|
103 "inj nat_of_nibble" |
|
104 by (rule inj_on_inverseI) (rule nibble_of_nat_of_nibble) |
|
105 |
|
106 lemma nat_of_nibble_eq_iff: |
|
107 "nat_of_nibble x = nat_of_nibble y \<longleftrightarrow> x = y" |
|
108 by (rule inj_eq) (rule inj_nat_of_nibble) |
|
109 |
|
110 lemma nat_of_nibble_less_16: |
|
111 "nat_of_nibble x < 16" |
|
112 by (cases x) auto |
|
113 |
|
114 lemma nibble_of_nat_mod_16: |
|
115 "nibble_of_nat (n mod 16) = nibble_of_nat n" |
|
116 by (simp add: nibble_of_nat_def) |
51 |
117 |
52 datatype char = Char nibble nibble |
118 datatype char = Char nibble nibble |
53 -- "Note: canonical order of character encoding coincides with standard term ordering" |
119 -- "Note: canonical order of character encoding coincides with standard term ordering" |
54 |
120 |
55 syntax |
121 syntax |
152 "Enum.enum_all P \<longleftrightarrow> list_all P (Enum.enum :: char list)" |
218 "Enum.enum_all P \<longleftrightarrow> list_all P (Enum.enum :: char list)" |
153 |
219 |
154 definition |
220 definition |
155 "Enum.enum_ex P \<longleftrightarrow> list_ex P (Enum.enum :: char list)" |
221 "Enum.enum_ex P \<longleftrightarrow> list_ex P (Enum.enum :: char list)" |
156 |
222 |
|
223 lemma enum_char_product_enum_nibble: |
|
224 "(Enum.enum :: char list) = map (split Char) (List.product Enum.enum Enum.enum)" |
|
225 by (simp add: enum_char_def enum_nibble_def) |
|
226 |
157 instance proof |
227 instance proof |
158 have enum: "(Enum.enum :: char list) = map (split Char) (List.product Enum.enum Enum.enum)" |
|
159 by (simp add: enum_char_def enum_nibble_def) |
|
160 show UNIV: "UNIV = set (Enum.enum :: char list)" |
228 show UNIV: "UNIV = set (Enum.enum :: char list)" |
161 by (simp add: enum UNIV_char product_list_set enum_UNIV) |
229 by (simp add: enum_char_product_enum_nibble UNIV_char product_list_set enum_UNIV) |
162 show "distinct (Enum.enum :: char list)" |
230 show "distinct (Enum.enum :: char list)" |
163 by (auto intro: inj_onI simp add: enum distinct_map distinct_product enum_distinct) |
231 by (auto intro: inj_onI simp add: enum_char_product_enum_nibble distinct_map distinct_product enum_distinct) |
164 show "\<And>P. Enum.enum_all P \<longleftrightarrow> Ball (UNIV :: char set) P" |
232 show "\<And>P. Enum.enum_all P \<longleftrightarrow> Ball (UNIV :: char set) P" |
165 by (simp add: UNIV enum_all_char_def list_all_iff) |
233 by (simp add: UNIV enum_all_char_def list_all_iff) |
166 show "\<And>P. Enum.enum_ex P \<longleftrightarrow> Bex (UNIV :: char set) P" |
234 show "\<And>P. Enum.enum_ex P \<longleftrightarrow> Bex (UNIV :: char set) P" |
167 by (simp add: UNIV enum_ex_char_def list_ex_iff) |
235 by (simp add: UNIV enum_ex_char_def list_ex_iff) |
168 qed |
236 qed |
171 |
239 |
172 lemma card_UNIV_char: |
240 lemma card_UNIV_char: |
173 "card (UNIV :: char set) = 256" |
241 "card (UNIV :: char set) = 256" |
174 by (simp add: card_UNIV_length_enum enum_char_def) |
242 by (simp add: card_UNIV_length_enum enum_char_def) |
175 |
243 |
176 primrec nibble_pair_of_char :: "char \<Rightarrow> nibble \<times> nibble" where |
244 definition nat_of_char :: "char \<Rightarrow> nat" |
177 "nibble_pair_of_char (Char n m) = (n, m)" |
245 where |
|
246 "nat_of_char c = (case c of Char x y \<Rightarrow> nat_of_nibble x * 16 + nat_of_nibble y)" |
|
247 |
|
248 lemma nat_of_char_Char: |
|
249 "nat_of_char (Char x y) = nat_of_nibble x * 16 + nat_of_nibble y" |
|
250 by (simp add: nat_of_char_def) |
178 |
251 |
179 setup {* |
252 setup {* |
180 let |
253 let |
181 val nibbles = map_range (Thm.cterm_of @{theory} o HOLogic.mk_nibble) 16; |
254 val nibbles = map_range (Thm.cterm_of @{theory} o HOLogic.mk_nibble) 16; |
182 val thms = map_product |
255 val simpset = HOL_ss addsimps |
183 (fn n => fn m => Drule.instantiate' [] [SOME n, SOME m] @{thm nibble_pair_of_char.simps}) |
256 @{thms nat_of_nibble.simps mult_0 mult_1 add_0 add_0_right arith_simps numeral_plus_one}; |
184 nibbles nibbles; |
257 fun mk_code_eqn x y = |
|
258 Drule.instantiate' [] [SOME x, SOME y] @{thm nat_of_char_Char} |
|
259 |> simplify simpset; |
|
260 val code_eqns = map_product mk_code_eqn nibbles nibbles; |
185 in |
261 in |
186 Global_Theory.note_thmss "" |
262 Global_Theory.note_thmss "" |
187 [((@{binding nibble_pair_of_char_simps}, []), [(thms, [])])] |
263 [((@{binding nat_of_char_simps}, []), [(code_eqns, [])])] |
188 #-> (fn [(_, thms)] => fold_rev Code.add_eqn thms) |
264 #> snd |
189 end |
265 end |
190 *} |
266 *} |
191 |
267 |
192 lemma char_case_nibble_pair [code, code_unfold]: |
268 declare nat_of_char_simps [code] |
193 "char_case f = split f o nibble_pair_of_char" |
269 |
|
270 lemma nibble_of_nat_of_char_div_16: |
|
271 "nibble_of_nat (nat_of_char c div 16) = (case c of Char x y \<Rightarrow> x)" |
|
272 by (cases c) |
|
273 (simp add: nat_of_char_def add_commute nat_of_nibble_less_16) |
|
274 |
|
275 lemma nibble_of_nat_nat_of_char: |
|
276 "nibble_of_nat (nat_of_char c) = (case c of Char x y \<Rightarrow> y)" |
|
277 proof (cases c) |
|
278 case (Char x y) |
|
279 then have *: "nibble_of_nat ((nat_of_nibble y + nat_of_nibble x * 16) mod 16) = y" |
|
280 by (simp add: nibble_of_nat_mod_16) |
|
281 then have "nibble_of_nat (nat_of_nibble y + nat_of_nibble x * 16) = y" |
|
282 by (simp only: nibble_of_nat_mod_16) |
|
283 with Char show ?thesis by (simp add: nat_of_char_def add_commute) |
|
284 qed |
|
285 |
|
286 code_datatype Char -- {* drop case certificate for char *} |
|
287 |
|
288 lemma char_case_code [code]: |
|
289 "char_case f c = (let n = nat_of_char c in f (nibble_of_nat (n div 16)) (nibble_of_nat n))" |
|
290 by (cases c) |
|
291 (simp only: Let_def nibble_of_nat_of_char_div_16 nibble_of_nat_nat_of_char char.cases) |
|
292 |
|
293 lemma [code]: |
|
294 "char_rec = char_case" |
194 by (simp add: fun_eq_iff split: char.split) |
295 by (simp add: fun_eq_iff split: char.split) |
195 |
296 |
196 lemma char_rec_nibble_pair [code, code_unfold]: |
297 definition char_of_nat :: "nat \<Rightarrow> char" where |
197 "char_rec f = split f o nibble_pair_of_char" |
298 "char_of_nat n = Enum.enum ! (n mod 256)" |
198 unfolding char_case_nibble_pair [symmetric] |
299 |
199 by (simp add: fun_eq_iff split: char.split) |
300 lemma char_of_nat_Char_nibbles: |
|
301 "char_of_nat n = Char (nibble_of_nat (n div 16)) (nibble_of_nat n)" |
|
302 proof - |
|
303 from mod_mult2_eq [of n 16 16] |
|
304 have "n mod 256 = 16 * (n div 16 mod 16) + n mod 16" by simp |
|
305 then show ?thesis |
|
306 by (simp add: char_of_nat_def enum_char_product_enum_nibble card_UNIV_nibble |
|
307 card_UNIV_length_enum [symmetric] nibble_of_nat_def product_nth add_commute) |
|
308 qed |
|
309 |
|
310 lemma char_of_nat_of_char [simp]: |
|
311 "char_of_nat (nat_of_char c) = c" |
|
312 by (cases c) |
|
313 (simp add: char_of_nat_Char_nibbles nibble_of_nat_of_char_div_16 nibble_of_nat_nat_of_char) |
|
314 |
|
315 lemma nat_of_char_of_nat [simp]: |
|
316 "nat_of_char (char_of_nat n) = n mod 256" |
|
317 proof - |
|
318 have "n mod 256 = n mod (16 * 16)" by simp |
|
319 then have "n div 16 mod 16 * 16 + n mod 16 = n mod 256" by (simp only: mod_mult2_eq) |
|
320 then show ?thesis |
|
321 by (cases "char_of_nat n") (auto simp add: nat_of_char_def char_of_nat_Char_nibbles) |
|
322 qed |
|
323 |
|
324 lemma inj_nat_of_char: |
|
325 "inj nat_of_char" |
|
326 by (rule inj_on_inverseI) (rule char_of_nat_of_char) |
|
327 |
|
328 lemma nat_of_char_eq_iff: |
|
329 "nat_of_char c = nat_of_char d \<longleftrightarrow> c = d" |
|
330 by (rule inj_eq) (rule inj_nat_of_char) |
|
331 |
|
332 lemma nat_of_char_less_256: |
|
333 "nat_of_char c < 256" |
|
334 proof (cases c) |
|
335 case (Char x y) |
|
336 with nat_of_nibble_less_16 [of x] nat_of_nibble_less_16 [of y] |
|
337 show ?thesis by (simp add: nat_of_char_def) |
|
338 qed |
|
339 |
|
340 lemma char_of_nat_mod_256: |
|
341 "char_of_nat (n mod 256) = char_of_nat n" |
|
342 proof - |
|
343 from nibble_of_nat_mod_16 [of "n mod 256"] |
|
344 have "nibble_of_nat (n mod 256) = nibble_of_nat (n mod 256 mod 16)" by simp |
|
345 with nibble_of_nat_mod_16 [of n] |
|
346 have *: "nibble_of_nat (n mod 256) = nibble_of_nat n" by (simp add: mod_mod_cancel) |
|
347 have "n mod 256 = n mod (16 * 16)" by simp |
|
348 then have **: "n mod 256 = n div 16 mod 16 * 16 + n mod 16" by (simp only: mod_mult2_eq) |
|
349 show ?thesis |
|
350 by (simp add: char_of_nat_Char_nibbles *) |
|
351 (simp add: div_add1_eq nibble_of_nat_mod_16 [of "n div 16"] **) |
|
352 qed |
200 |
353 |
201 |
354 |
202 subsection {* Strings as dedicated type *} |
355 subsection {* Strings as dedicated type *} |
203 |
356 |
204 typedef literal = "UNIV :: string set" |
357 typedef literal = "UNIV :: string set" |