|     70     by arith |     70     by arith | 
|     71   then show ?thesis by simp |     71   then show ?thesis by simp | 
|     72 qed |     72 qed | 
|     73  |     73  | 
|     74 lemma UNIV_char_of_nat: |     74 lemma UNIV_char_of_nat: | 
|     75   "UNIV = char_of_nat ` {0..<256}" |     75   "UNIV = char_of_nat ` {..<256}" | 
|     76 proof - |     76 proof - | 
|     77   { fix c |     77   { fix c | 
|     78     have "c \<in> char_of_nat ` {0..<256}" |     78     have "c \<in> char_of_nat ` {..<256}" | 
|     79       by (cases c) auto |     79       by (cases c) auto | 
|     80   } then show ?thesis by auto |     80   } then show ?thesis by auto | 
|     81 qed |     81 qed | 
|     82  |     82  | 
|     83  |     83 lemma card_UNIV_char: | 
|     84 subsubsection \<open>Traditional concrete representation of characters\<close> |     84   "card (UNIV :: char set) = 256" | 
|     85  |     85   by (auto simp add: UNIV_char_of_nat card_image) | 
|     86 datatype (plugins del: transfer) nibble = |     86  | 
|     87     Nibble0 | Nibble1 | Nibble2 | Nibble3 | Nibble4 | Nibble5 | Nibble6 | Nibble7 |     87 lemma range_nat_of_char: | 
|     88   | Nibble8 | Nibble9 | NibbleA | NibbleB | NibbleC | NibbleD | NibbleE | NibbleF |     88   "range nat_of_char = {..<256}" | 
|     89  |     89   by (auto simp add: UNIV_char_of_nat image_image image_def) | 
|     90 lemma UNIV_nibble: |     90  | 
|     91   "UNIV = {Nibble0, Nibble1, Nibble2, Nibble3, Nibble4, Nibble5, Nibble6, Nibble7, |     91  | 
|     92     Nibble8, Nibble9, NibbleA, NibbleB, NibbleC, NibbleD, NibbleE, NibbleF}" (is "_ = ?A") |     92 subsubsection \<open>Character literals as variant of numerals\<close> | 
|     93 proof (rule UNIV_eq_I) |     93  | 
|     94   fix x show "x \<in> ?A" by (cases x) simp_all |     94 instantiation char :: zero | 
|     95 qed |     95 begin | 
|     96  |     96  | 
|     97 lemma size_nibble [code, simp]: |     97 definition zero_char :: char | 
|     98   "size_nibble (x::nibble) = 0" |     98   where "0 = char_of_nat 0" | 
|     99   "size (x::nibble) = 0" |     99  | 
|    100   by (cases x, simp_all)+ |    100 instance .. | 
|    101  |    101  | 
|    102 instantiation nibble :: enum |    102 end | 
|    103 begin |    103  | 
|    104  |    104 definition Char :: "num \<Rightarrow> char" | 
|    105 definition |    105   where "Char k = char_of_nat (numeral k)" | 
|    106   "Enum.enum = [Nibble0, Nibble1, Nibble2, Nibble3, Nibble4, Nibble5, Nibble6, Nibble7, |    106  | 
|    107     Nibble8, Nibble9, NibbleA, NibbleB, NibbleC, NibbleD, NibbleE, NibbleF]" |    107 code_datatype "0 :: char" Char | 
|    108  |    108  | 
|    109 definition |    109 lemma nat_of_char_zero [simp]: | 
|    110   "Enum.enum_all P \<longleftrightarrow> P Nibble0 \<and> P Nibble1 \<and> P Nibble2 \<and> P Nibble3 \<and> P Nibble4 \<and> P Nibble5 \<and> P Nibble6 \<and> P Nibble7 |    110   "nat_of_char 0 = 0" | 
|    111      \<and> P Nibble8 \<and> P Nibble9 \<and> P NibbleA \<and> P NibbleB \<and> P NibbleC \<and> P NibbleD \<and> P NibbleE \<and> P NibbleF" |    111   by (simp add: zero_char_def) | 
|    112  |    112  | 
|    113 definition |    113 lemma nat_of_char_Char [simp]: | 
|    114   "Enum.enum_ex P \<longleftrightarrow> P Nibble0 \<or> P Nibble1 \<or> P Nibble2 \<or> P Nibble3 \<or> P Nibble4 \<or> P Nibble5 \<or> P Nibble6 \<or> P Nibble7 |    114   "nat_of_char (Char k) = numeral k mod 256" | 
|    115      \<or> P Nibble8 \<or> P Nibble9 \<or> P NibbleA \<or> P NibbleB \<or> P NibbleC \<or> P NibbleD \<or> P NibbleE \<or> P NibbleF" |    115   by (simp add: Char_def) | 
|    116  |    116  | 
|    117 instance proof |    117 lemma Char_eq_Char_iff [simp]: | 
|    118 qed (simp_all only: enum_nibble_def enum_all_nibble_def enum_ex_nibble_def UNIV_nibble, simp_all) |    118   "Char k = Char l \<longleftrightarrow> numeral k mod (256 :: nat) = numeral l mod 256" (is "?P \<longleftrightarrow> ?Q") | 
|    119  |    119 proof - | 
|    120 end |    120   have "?P \<longleftrightarrow> nat_of_char (Char k) = nat_of_char (Char l)" | 
|    121  |    121     by (rule sym, rule inj_eq) (fact inj_nat_of_char) | 
|    122 lemma card_UNIV_nibble: |    122   also have "nat_of_char (Char k) = nat_of_char (Char l) \<longleftrightarrow> ?Q" | 
|    123   "card (UNIV :: nibble set) = 16" |    123     by (simp only: Char_def nat_of_char_of_nat) | 
|    124   by (simp add: card_UNIV_length_enum enum_nibble_def) |    124   finally show ?thesis . | 
|    125  |    125 qed | 
|    126 primrec nat_of_nibble :: "nibble \<Rightarrow> nat" |    126  | 
|         |    127 lemma zero_eq_Char_iff [simp]: | 
|         |    128   "0 = Char k \<longleftrightarrow> numeral k mod (256 :: nat) = 0" | 
|         |    129   by (auto simp add: zero_char_def Char_def) | 
|         |    130  | 
|         |    131 lemma Char_eq_zero_iff [simp]: | 
|         |    132   "Char k = 0 \<longleftrightarrow> numeral k mod (256 :: nat) = 0" | 
|         |    133   by (auto simp add: zero_char_def Char_def)  | 
|         |    134  | 
|         |    135 definition integer_of_char :: "char \<Rightarrow> integer" | 
|    127 where |    136 where | 
|    128   "nat_of_nibble Nibble0 = 0" |    137   "integer_of_char = integer_of_nat \<circ> nat_of_char" | 
|    129 | "nat_of_nibble Nibble1 = 1" |    138  | 
|    130 | "nat_of_nibble Nibble2 = 2" |    139 definition char_of_integer :: "integer \<Rightarrow> char" | 
|    131 | "nat_of_nibble Nibble3 = 3" |         | 
|    132 | "nat_of_nibble Nibble4 = 4" |         | 
|    133 | "nat_of_nibble Nibble5 = 5" |         | 
|    134 | "nat_of_nibble Nibble6 = 6" |         | 
|    135 | "nat_of_nibble Nibble7 = 7" |         | 
|    136 | "nat_of_nibble Nibble8 = 8" |         | 
|    137 | "nat_of_nibble Nibble9 = 9" |         | 
|    138 | "nat_of_nibble NibbleA = 10" |         | 
|    139 | "nat_of_nibble NibbleB = 11" |         | 
|    140 | "nat_of_nibble NibbleC = 12" |         | 
|    141 | "nat_of_nibble NibbleD = 13" |         | 
|    142 | "nat_of_nibble NibbleE = 14" |         | 
|    143 | "nat_of_nibble NibbleF = 15" |         | 
|    144  |         | 
|    145 definition nibble_of_nat :: "nat \<Rightarrow> nibble" where |         | 
|    146   "nibble_of_nat n = Enum.enum ! (n mod 16)" |         | 
|    147  |         | 
|    148 lemma nibble_of_nat_simps [simp]: |         | 
|    149   "nibble_of_nat  0 = Nibble0" |         | 
|    150   "nibble_of_nat  1 = Nibble1" |         | 
|    151   "nibble_of_nat  2 = Nibble2" |         | 
|    152   "nibble_of_nat  3 = Nibble3" |         | 
|    153   "nibble_of_nat  4 = Nibble4" |         | 
|    154   "nibble_of_nat  5 = Nibble5" |         | 
|    155   "nibble_of_nat  6 = Nibble6" |         | 
|    156   "nibble_of_nat  7 = Nibble7" |         | 
|    157   "nibble_of_nat  8 = Nibble8" |         | 
|    158   "nibble_of_nat  9 = Nibble9" |         | 
|    159   "nibble_of_nat 10 = NibbleA" |         | 
|    160   "nibble_of_nat 11 = NibbleB" |         | 
|    161   "nibble_of_nat 12 = NibbleC" |         | 
|    162   "nibble_of_nat 13 = NibbleD" |         | 
|    163   "nibble_of_nat 14 = NibbleE" |         | 
|    164   "nibble_of_nat 15 = NibbleF" |         | 
|    165   unfolding nibble_of_nat_def by (simp_all add: enum_nibble_def) |         | 
|    166  |         | 
|    167 lemma nibble_of_nat_of_nibble [simp]: |         | 
|    168   "nibble_of_nat (nat_of_nibble x) = x" |         | 
|    169   by (cases x) (simp_all add: nibble_of_nat_def enum_nibble_def) |         | 
|    170  |         | 
|    171 lemma nat_of_nibble_of_nat [simp]: |         | 
|    172   "nat_of_nibble (nibble_of_nat n) = n mod 16" |         | 
|    173   by (cases "nibble_of_nat n") |         | 
|    174      (simp_all add: nibble_of_nat_def enum_nibble_def nth_equal_first_eq nth_non_equal_first_eq, arith) |         | 
|    175  |         | 
|    176 lemma inj_nat_of_nibble: |         | 
|    177   "inj nat_of_nibble" |         | 
|    178   by (rule inj_on_inverseI) (rule nibble_of_nat_of_nibble) |         | 
|    179  |         | 
|    180 lemma nat_of_nibble_eq_iff: |         | 
|    181   "nat_of_nibble x = nat_of_nibble y \<longleftrightarrow> x = y" |         | 
|    182   by (rule inj_eq) (rule inj_nat_of_nibble) |         | 
|    183  |         | 
|    184 lemma nat_of_nibble_less_16: |         | 
|    185   "nat_of_nibble x < 16" |         | 
|    186   by (cases x) auto |         | 
|    187  |         | 
|    188 lemma nibble_of_nat_mod_16: |         | 
|    189   "nibble_of_nat (n mod 16) = nibble_of_nat n" |         | 
|    190   by (simp add: nibble_of_nat_def) |         | 
|    191  |         | 
|    192 context |         | 
|    193 begin |         | 
|    194  |         | 
|    195 local_setup \<open>Local_Theory.map_background_naming (Name_Space.add_path "char")\<close> |         | 
|    196  |         | 
|    197 definition Char :: "nibble \<Rightarrow> nibble \<Rightarrow> char" |         | 
|    198 where |    140 where | 
|    199   "Char x y = char_of_nat (nat_of_nibble x * 16 + nat_of_nibble y)" |    141   "char_of_integer = char_of_nat \<circ> nat_of_integer" | 
|    200   \<comment> "Note: canonical order of character encoding coincides with standard term ordering" |    142  | 
|    201  |    143 lemma integer_of_char_zero [simp, code]: | 
|    202 end |    144   "integer_of_char 0 = 0" | 
|    203  |    145   by (simp add: integer_of_char_def integer_of_nat_def) | 
|    204 lemma nat_of_char_Char: |    146  | 
|    205   "nat_of_char (Char x y) = nat_of_nibble x * 16 + nat_of_nibble y" (is "_ = ?rhs") |    147 lemma integer_of_char_Char [simp]: | 
|         |    148   "integer_of_char (Char k) = numeral k mod 256" | 
|         |    149   by (simp only: integer_of_char_def integer_of_nat_def comp_apply nat_of_char_Char map_fun_def | 
|         |    150     id_apply zmod_int mod_integer.abs_eq [symmetric]) simp | 
|         |    151  | 
|         |    152 lemma less_256_integer_of_char_Char: | 
|         |    153   assumes "numeral k < (256 :: integer)" | 
|         |    154   shows "integer_of_char (Char k) = numeral k" | 
|    206 proof - |    155 proof - | 
|    207   have "?rhs < 256" |    156   have "numeral k mod 256 = (numeral k :: integer)" | 
|    208     using nat_of_nibble_less_16 [of x] nat_of_nibble_less_16 [of y] |    157     by (rule semiring_numeral_div_class.mod_less) (insert assms, simp_all) | 
|    209     by arith |    158   then show ?thesis using integer_of_char_Char [of k] | 
|    210   then show ?thesis by (simp add: Char_def) |    159     by (simp only:) | 
|    211 qed |    160 qed | 
|    212  |    161  | 
|    213 lemma char_of_nat_Char_nibbles: |    162 setup \<open> | 
|    214   "char_of_nat n = Char (nibble_of_nat (n div 16)) (nibble_of_nat n)" |    163 let | 
|    215 proof - |    164   val chars = map_range (Thm.cterm_of @{context} o HOLogic.mk_numeral o curry (op +) 1) 255; | 
|    216   from mod_mult2_eq [of n 16 16] |    165   val simpset = | 
|    217   have "n mod 256 = 16 * (n div 16 mod 16) + n mod 16" by simp |    166     put_simpset HOL_ss @{context} | 
|    218   then show ?thesis |    167       addsimps @{thms numeral_less_iff less_num_simps}; | 
|    219     by (simp add: Char_def) |    168   fun mk_code_eqn ct = | 
|    220 qed |    169     Thm.instantiate' [] [SOME ct] @{thm less_256_integer_of_char_Char} | 
|    221  |    170     |> full_simplify simpset; | 
|    222 lemma char_of_nat_nibble_pair [simp]: |    171   val code_eqns = map mk_code_eqn chars; | 
|    223   "char_of_nat (nat_of_nibble a * 16 + nat_of_nibble b) = Char a b" |    172 in | 
|    224   by (simp add: nat_of_char_Char [symmetric]) |    173   Global_Theory.note_thmss "" | 
|    225  |    174     [((@{binding integer_of_char_simps}, []), [(code_eqns, [])])] | 
|    226 free_constructors char for Char |    175   #> snd | 
|    227 proof - |    176 end | 
|    228   fix P c |    177 \<close> | 
|    229   assume hyp: "\<And>x y. c = Char x y \<Longrightarrow> P" |    178  | 
|    230   have "nat_of_char c \<le> 255" |    179 declare integer_of_char_simps [code] | 
|    231     using nat_of_char_less_256 [of c] by arith |    180  | 
|    232   then have "nat_of_char c div 16 \<le> 255 div 16" |    181 lemma nat_of_char_code [code]: | 
|    233     by (auto intro: div_le_mono2) |    182   "nat_of_char = nat_of_integer \<circ> integer_of_char" | 
|    234   then have "nat_of_char c div 16 < 16" |    183   by (simp add: integer_of_char_def fun_eq_iff) | 
|    235     by auto |    184  | 
|    236   then have "nat_of_char c div 16 mod 16 = nat_of_char c div 16" |    185 lemma char_of_nat_code [code]: | 
|    237     by simp |    186   "char_of_nat = char_of_integer \<circ> integer_of_nat" | 
|    238   then have "c = Char (nibble_of_nat (nat_of_char c div 16)) |    187   by (simp add: char_of_integer_def fun_eq_iff) | 
|    239     (nibble_of_nat (nat_of_char c mod 16))" |    188  | 
|    240     by (simp add: Char_def) |    189 instantiation char :: equal | 
|    241   then show P by (rule hyp) |    190 begin | 
|    242 next |    191  | 
|    243   fix x y z w |    192 definition equal_char | 
|    244   have "Char x y = Char z w |    193   where "equal_char (c :: char) d \<longleftrightarrow> c = d" | 
|    245     \<longleftrightarrow> nat_of_char (Char x y) = nat_of_char (Char z w)" |    194  | 
|    246     by auto |    195 instance | 
|    247   also have "\<dots> \<longleftrightarrow> nat_of_nibble x = nat_of_nibble z \<and> nat_of_nibble y = nat_of_nibble w" (is "?P \<longleftrightarrow> ?Q \<and> ?R") |    196   by standard (simp add: equal_char_def) | 
|    248   proof |    197  | 
|    249     assume "?Q \<and> ?R" |    198 end | 
|    250     then show ?P by (simp add: nat_of_char_Char) |    199  | 
|    251   next |    200 lemma equal_char_simps [code]: | 
|    252     assume ?P |    201   "HOL.equal (0::char) 0 \<longleftrightarrow> True" | 
|    253     then have ?Q |    202   "HOL.equal (Char k) (Char l) \<longleftrightarrow> HOL.equal (numeral k mod 256 :: nat) (numeral l mod 256)" | 
|    254       using nat_of_nibble_less_16 [of y] nat_of_nibble_less_16 [of w] |    203   "HOL.equal 0 (Char k) \<longleftrightarrow> HOL.equal (numeral k mod 256 :: nat) 0" | 
|    255       by (simp add: nat_of_char_Char) |    204   "HOL.equal (Char k) 0 \<longleftrightarrow> HOL.equal (numeral k mod 256 :: nat) 0" | 
|    256     moreover with \<open>?P\<close> have ?R by (simp add: nat_of_char_Char) |    205   by (simp_all only: equal refl Char_eq_Char_iff zero_eq_Char_iff Char_eq_zero_iff) | 
|    257     ultimately show "?Q \<and> ?R" .. |         | 
|    258   qed |         | 
|    259   also have "\<dots> \<longleftrightarrow> x = z \<and> y = w" |         | 
|    260     by (simp add: nat_of_nibble_eq_iff) |         | 
|    261   finally show "Char x y = Char z w \<longleftrightarrow> x = z \<and> y = w" . |         | 
|    262 qed |         | 
|    263  |    206  | 
|    264 syntax |    207 syntax | 
|    265   "_Char" :: "str_position => char"    ("CHR _") |    208   "_Char" :: "str_position \<Rightarrow> char"    ("CHR _") | 
|         |    209  | 
|         |    210 syntax | 
|         |    211   "_Char_ord" :: "num_const \<Rightarrow> char"     ("CHAR _") | 
|    266  |    212  | 
|    267 type_synonym string = "char list" |    213 type_synonym string = "char list" | 
|    268  |    214  | 
|    269 syntax |    215 syntax | 
|    270   "_String" :: "str_position => string"    ("_") |    216   "_String" :: "str_position => string"    ("_") | 
|    271  |    217  | 
|    272 ML_file "Tools/string_syntax.ML" |    218 ML_file "Tools/string_syntax.ML" | 
|    273  |    219  | 
|    274 lemma UNIV_char: |         | 
|    275   "UNIV = image (case_prod Char) (UNIV \<times> UNIV)" |         | 
|    276 proof (rule UNIV_eq_I) |         | 
|    277   fix x show "x \<in> image (case_prod Char) (UNIV \<times> UNIV)" by (cases x) auto |         | 
|    278 qed |         | 
|    279  |         | 
|    280 instantiation char :: enum |    220 instantiation char :: enum | 
|    281 begin |    221 begin | 
|    282  |    222  | 
|    283 definition |    223 definition | 
|    284   "Enum.enum = [Char Nibble0 Nibble0, Char Nibble0 Nibble1, Char Nibble0 Nibble2, |    224   "Enum.enum = [0, CHAR 0x01, CHAR 0x02, CHAR 0x03, | 
|    285   Char Nibble0 Nibble3, Char Nibble0 Nibble4, Char Nibble0 Nibble5, |    225     CHAR 0x04, CHAR 0x05, CHAR 0x06, CHAR 0x07, | 
|    286   Char Nibble0 Nibble6, Char Nibble0 Nibble7, Char Nibble0 Nibble8, |    226     CHAR 0x08, CHAR 0x09, CHR ''\<newline>'', CHAR 0x0B, | 
|    287   Char Nibble0 Nibble9, CHR ''\<newline>'', Char Nibble0 NibbleB, |    227     CHAR 0x0C, CHAR 0x0D, CHAR 0x0E, CHAR 0x0F, | 
|    288   Char Nibble0 NibbleC, Char Nibble0 NibbleD, Char Nibble0 NibbleE, |    228     CHAR 0x10, CHAR 0x11, CHAR 0x12, CHAR 0x13, | 
|    289   Char Nibble0 NibbleF, Char Nibble1 Nibble0, Char Nibble1 Nibble1, |    229     CHAR 0x14, CHAR 0x15, CHAR 0x16, CHAR 0x17, | 
|    290   Char Nibble1 Nibble2, Char Nibble1 Nibble3, Char Nibble1 Nibble4, |    230     CHAR 0x18, CHAR 0x19, CHAR 0x1A, CHAR 0x1B, | 
|    291   Char Nibble1 Nibble5, Char Nibble1 Nibble6, Char Nibble1 Nibble7, |    231     CHAR 0x1C, CHAR 0x1D, CHAR 0x1E, CHAR 0x1F, | 
|    292   Char Nibble1 Nibble8, Char Nibble1 Nibble9, Char Nibble1 NibbleA, |    232     CHR '' '', CHR ''!'', CHAR 0x22, CHR ''#'', | 
|    293   Char Nibble1 NibbleB, Char Nibble1 NibbleC, Char Nibble1 NibbleD, |    233     CHR ''$'', CHR ''%'', CHR ''&'', CHAR 0x27, | 
|    294   Char Nibble1 NibbleE, Char Nibble1 NibbleF, CHR '' '', CHR ''!'', |    234     CHR ''('', CHR '')'', CHR ''*'', CHR ''+'', | 
|    295   Char Nibble2 Nibble2, CHR ''#'', CHR ''$'', CHR ''%'', CHR ''&'', |    235     CHR '','', CHR ''-'', CHR ''.'', CHR ''/'', | 
|    296   Char Nibble2 Nibble7, CHR ''('', CHR '')'', CHR ''*'', CHR ''+'', CHR '','', |    236     CHR ''0'', CHR ''1'', CHR ''2'', CHR ''3'', | 
|    297   CHR ''-'', CHR ''.'', CHR ''/'', CHR ''0'', CHR ''1'', CHR ''2'', CHR ''3'', |    237     CHR ''4'', CHR ''5'', CHR ''6'', CHR ''7'', | 
|    298   CHR ''4'', CHR ''5'', CHR ''6'', CHR ''7'', CHR ''8'', CHR ''9'', CHR '':'', |    238     CHR ''8'', CHR ''9'', CHR '':'', CHR '';'', | 
|    299   CHR '';'', CHR ''<'', CHR ''='', CHR ''>'', CHR ''?'', CHR ''@'', CHR ''A'', |    239     CHR ''<'', CHR ''='', CHR ''>'', CHR ''?'', | 
|    300   CHR ''B'', CHR ''C'', CHR ''D'', CHR ''E'', CHR ''F'', CHR ''G'', CHR ''H'', |    240     CHR ''@'', CHR ''A'', CHR ''B'', CHR ''C'', | 
|    301   CHR ''I'', CHR ''J'', CHR ''K'', CHR ''L'', CHR ''M'', CHR ''N'', CHR ''O'', |    241     CHR ''D'', CHR ''E'', CHR ''F'', CHR ''G'', | 
|    302   CHR ''P'', CHR ''Q'', CHR ''R'', CHR ''S'', CHR ''T'', CHR ''U'', CHR ''V'', |    242     CHR ''H'', CHR ''I'', CHR ''J'', CHR ''K'', | 
|    303   CHR ''W'', CHR ''X'', CHR ''Y'', CHR ''Z'', CHR ''['', Char Nibble5 NibbleC, |    243     CHR ''L'', CHR ''M'', CHR ''N'', CHR ''O'', | 
|    304   CHR '']'', CHR ''^'', CHR ''_'', Char Nibble6 Nibble0, CHR ''a'', CHR ''b'', |    244     CHR ''P'', CHR ''Q'', CHR ''R'', CHR ''S'', | 
|    305   CHR ''c'', CHR ''d'', CHR ''e'', CHR ''f'', CHR ''g'', CHR ''h'', CHR ''i'', |    245     CHR ''T'', CHR ''U'', CHR ''V'', CHR ''W'', | 
|    306   CHR ''j'', CHR ''k'', CHR ''l'', CHR ''m'', CHR ''n'', CHR ''o'', CHR ''p'', |    246     CHR ''X'', CHR ''Y'', CHR ''Z'', CHR ''['', | 
|    307   CHR ''q'', CHR ''r'', CHR ''s'', CHR ''t'', CHR ''u'', CHR ''v'', CHR ''w'', |    247     CHAR 0x5C, CHR '']'', CHR ''^'', CHR ''_'', | 
|    308   CHR ''x'', CHR ''y'', CHR ''z'', CHR ''{'', CHR ''|'', CHR ''}'', CHR ''~'', |    248     CHAR 0x60, CHR ''a'', CHR ''b'', CHR ''c'', | 
|    309   Char Nibble7 NibbleF, Char Nibble8 Nibble0, Char Nibble8 Nibble1, |    249     CHR ''d'', CHR ''e'', CHR ''f'', CHR ''g'', | 
|    310   Char Nibble8 Nibble2, Char Nibble8 Nibble3, Char Nibble8 Nibble4, |    250     CHR ''h'', CHR ''i'', CHR ''j'', CHR ''k'', | 
|    311   Char Nibble8 Nibble5, Char Nibble8 Nibble6, Char Nibble8 Nibble7, |    251     CHR ''l'', CHR ''m'', CHR ''n'', CHR ''o'', | 
|    312   Char Nibble8 Nibble8, Char Nibble8 Nibble9, Char Nibble8 NibbleA, |    252     CHR ''p'', CHR ''q'', CHR ''r'', CHR ''s'', | 
|    313   Char Nibble8 NibbleB, Char Nibble8 NibbleC, Char Nibble8 NibbleD, |    253     CHR ''t'', CHR ''u'', CHR ''v'', CHR ''w'', | 
|    314   Char Nibble8 NibbleE, Char Nibble8 NibbleF, Char Nibble9 Nibble0, |    254     CHR ''x'', CHR ''y'', CHR ''z'', CHR ''{'', | 
|    315   Char Nibble9 Nibble1, Char Nibble9 Nibble2, Char Nibble9 Nibble3, |    255     CHR ''|'', CHR ''}'', CHR ''~'', CHAR 0x7F, | 
|    316   Char Nibble9 Nibble4, Char Nibble9 Nibble5, Char Nibble9 Nibble6, |    256     CHAR 0x80, CHAR 0x81, CHAR 0x82, CHAR 0x83, | 
|    317   Char Nibble9 Nibble7, Char Nibble9 Nibble8, Char Nibble9 Nibble9, |    257     CHAR 0x84, CHAR 0x85, CHAR 0x86, CHAR 0x87, | 
|    318   Char Nibble9 NibbleA, Char Nibble9 NibbleB, Char Nibble9 NibbleC, |    258     CHAR 0x88, CHAR 0x89, CHAR 0x8A, CHAR 0x8B, | 
|    319   Char Nibble9 NibbleD, Char Nibble9 NibbleE, Char Nibble9 NibbleF, |    259     CHAR 0x8C, CHAR 0x8D, CHAR 0x8E, CHAR 0x8F, | 
|    320   Char NibbleA Nibble0, Char NibbleA Nibble1, Char NibbleA Nibble2, |    260     CHAR 0x90, CHAR 0x91, CHAR 0x92, CHAR 0x93, | 
|    321   Char NibbleA Nibble3, Char NibbleA Nibble4, Char NibbleA Nibble5, |    261     CHAR 0x94, CHAR 0x95, CHAR 0x96, CHAR 0x97, | 
|    322   Char NibbleA Nibble6, Char NibbleA Nibble7, Char NibbleA Nibble8, |    262     CHAR 0x98, CHAR 0x99, CHAR 0x9A, CHAR 0x9B, | 
|    323   Char NibbleA Nibble9, Char NibbleA NibbleA, Char NibbleA NibbleB, |    263     CHAR 0x9C, CHAR 0x9D, CHAR 0x9E, CHAR 0x9F, | 
|    324   Char NibbleA NibbleC, Char NibbleA NibbleD, Char NibbleA NibbleE, |    264     CHAR 0xA0, CHAR 0xA1, CHAR 0xA2, CHAR 0xA3, | 
|    325   Char NibbleA NibbleF, Char NibbleB Nibble0, Char NibbleB Nibble1, |    265     CHAR 0xA4, CHAR 0xA5, CHAR 0xA6, CHAR 0xA7, | 
|    326   Char NibbleB Nibble2, Char NibbleB Nibble3, Char NibbleB Nibble4, |    266     CHAR 0xA8, CHAR 0xA9, CHAR 0xAA, CHAR 0xAB, | 
|    327   Char NibbleB Nibble5, Char NibbleB Nibble6, Char NibbleB Nibble7, |    267     CHAR 0xAC, CHAR 0xAD, CHAR 0xAE, CHAR 0xAF, | 
|    328   Char NibbleB Nibble8, Char NibbleB Nibble9, Char NibbleB NibbleA, |    268     CHAR 0xB0, CHAR 0xB1, CHAR 0xB2, CHAR 0xB3, | 
|    329   Char NibbleB NibbleB, Char NibbleB NibbleC, Char NibbleB NibbleD, |    269     CHAR 0xB4, CHAR 0xB5, CHAR 0xB6, CHAR 0xB7, | 
|    330   Char NibbleB NibbleE, Char NibbleB NibbleF, Char NibbleC Nibble0, |    270     CHAR 0xB8, CHAR 0xB9, CHAR 0xBA, CHAR 0xBB, | 
|    331   Char NibbleC Nibble1, Char NibbleC Nibble2, Char NibbleC Nibble3, |    271     CHAR 0xBC, CHAR 0xBD, CHAR 0xBE, CHAR 0xBF, | 
|    332   Char NibbleC Nibble4, Char NibbleC Nibble5, Char NibbleC Nibble6, |    272     CHAR 0xC0, CHAR 0xC1, CHAR 0xC2, CHAR 0xC3, | 
|    333   Char NibbleC Nibble7, Char NibbleC Nibble8, Char NibbleC Nibble9, |    273     CHAR 0xC4, CHAR 0xC5, CHAR 0xC6, CHAR 0xC7, | 
|    334   Char NibbleC NibbleA, Char NibbleC NibbleB, Char NibbleC NibbleC, |    274     CHAR 0xC8, CHAR 0xC9, CHAR 0xCA, CHAR 0xCB, | 
|    335   Char NibbleC NibbleD, Char NibbleC NibbleE, Char NibbleC NibbleF, |    275     CHAR 0xCC, CHAR 0xCD, CHAR 0xCE, CHAR 0xCF, | 
|    336   Char NibbleD Nibble0, Char NibbleD Nibble1, Char NibbleD Nibble2, |    276     CHAR 0xD0, CHAR 0xD1, CHAR 0xD2, CHAR 0xD3, | 
|    337   Char NibbleD Nibble3, Char NibbleD Nibble4, Char NibbleD Nibble5, |    277     CHAR 0xD4, CHAR 0xD5, CHAR 0xD6, CHAR 0xD7, | 
|    338   Char NibbleD Nibble6, Char NibbleD Nibble7, Char NibbleD Nibble8, |    278     CHAR 0xD8, CHAR 0xD9, CHAR 0xDA, CHAR 0xDB, | 
|    339   Char NibbleD Nibble9, Char NibbleD NibbleA, Char NibbleD NibbleB, |    279     CHAR 0xDC, CHAR 0xDD, CHAR 0xDE, CHAR 0xDF, | 
|    340   Char NibbleD NibbleC, Char NibbleD NibbleD, Char NibbleD NibbleE, |    280     CHAR 0xE0, CHAR 0xE1, CHAR 0xE2, CHAR 0xE3, | 
|    341   Char NibbleD NibbleF, Char NibbleE Nibble0, Char NibbleE Nibble1, |    281     CHAR 0xE4, CHAR 0xE5, CHAR 0xE6, CHAR 0xE7, | 
|    342   Char NibbleE Nibble2, Char NibbleE Nibble3, Char NibbleE Nibble4, |    282     CHAR 0xE8, CHAR 0xE9, CHAR 0xEA, CHAR 0xEB, | 
|    343   Char NibbleE Nibble5, Char NibbleE Nibble6, Char NibbleE Nibble7, |    283     CHAR 0xEC, CHAR 0xED, CHAR 0xEE, CHAR 0xEF, | 
|    344   Char NibbleE Nibble8, Char NibbleE Nibble9, Char NibbleE NibbleA, |    284     CHAR 0xF0, CHAR 0xF1, CHAR 0xF2, CHAR 0xF3, | 
|    345   Char NibbleE NibbleB, Char NibbleE NibbleC, Char NibbleE NibbleD, |    285     CHAR 0xF4, CHAR 0xF5, CHAR 0xF6, CHAR 0xF7, | 
|    346   Char NibbleE NibbleE, Char NibbleE NibbleF, Char NibbleF Nibble0, |    286     CHAR 0xF8, CHAR 0xF9, CHAR 0xFA, CHAR 0xFB, | 
|    347   Char NibbleF Nibble1, Char NibbleF Nibble2, Char NibbleF Nibble3, |    287     CHAR 0xFC, CHAR 0xFD, CHAR 0xFE, CHAR 0xFF]" | 
|    348   Char NibbleF Nibble4, Char NibbleF Nibble5, Char NibbleF Nibble6, |         | 
|    349   Char NibbleF Nibble7, Char NibbleF Nibble8, Char NibbleF Nibble9, |         | 
|    350   Char NibbleF NibbleA, Char NibbleF NibbleB, Char NibbleF NibbleC, |         | 
|    351   Char NibbleF NibbleD, Char NibbleF NibbleE, Char NibbleF NibbleF]" |         | 
|    352  |    288  | 
|    353 definition |    289 definition | 
|    354   "Enum.enum_all P \<longleftrightarrow> list_all P (Enum.enum :: char list)" |    290   "Enum.enum_all P \<longleftrightarrow> list_all P (Enum.enum :: char list)" | 
|    355  |    291  | 
|    356 definition |    292 definition | 
|    357   "Enum.enum_ex P \<longleftrightarrow> list_ex P (Enum.enum :: char list)" |    293   "Enum.enum_ex P \<longleftrightarrow> list_ex P (Enum.enum :: char list)" | 
|    358  |         | 
|    359 lemma enum_char_product_enum_nibble: |         | 
|    360   "(Enum.enum :: char list) = map (case_prod Char) (List.product Enum.enum Enum.enum)" |         | 
|    361   by (simp add: enum_char_def enum_nibble_def) |         | 
|    362  |         | 
|    363 instance proof |         | 
|    364   show UNIV: "UNIV = set (Enum.enum :: char list)" |         | 
|    365     by (simp add: enum_char_product_enum_nibble UNIV_char enum_UNIV) |         | 
|    366   show "distinct (Enum.enum :: char list)" |         | 
|    367     by (auto intro: inj_onI simp add: enum_char_product_enum_nibble distinct_map distinct_product enum_distinct) |         | 
|    368   show "\<And>P. Enum.enum_all P \<longleftrightarrow> Ball (UNIV :: char set) P" |         | 
|    369     by (simp add: UNIV enum_all_char_def list_all_iff) |         | 
|    370   show "\<And>P. Enum.enum_ex P \<longleftrightarrow> Bex (UNIV :: char set) P" |         | 
|    371     by (simp add: UNIV enum_ex_char_def list_ex_iff) |         | 
|    372 qed |         | 
|    373  |         | 
|    374 end |         | 
|    375  |         | 
|    376 lemma card_UNIV_char: |         | 
|    377   "card (UNIV :: char set) = 256" |         | 
|    378   by (simp add: card_UNIV_length_enum enum_char_def) |         | 
|    379  |    294  | 
|    380 lemma enum_char_unfold: |    295 lemma enum_char_unfold: | 
|    381   "Enum.enum = map char_of_nat [0..<256]" |    296   "Enum.enum = map char_of_nat [0..<256]" | 
|    382 proof - |    297 proof - | 
|    383   have *: "Suc (Suc 0) = 2" by simp |    298   have *: "Suc (Suc 0) = 2" by simp | 
|    384   have "map nat_of_char Enum.enum = [0..<256]" |    299   have "map nat_of_char Enum.enum = [0..<256]" | 
|    385     by (simp add: enum_char_def nat_of_char_Char upt_conv_Cons_Cons *) |    300     by (simp add: enum_char_def upt_conv_Cons_Cons *) | 
|    386   then have "map char_of_nat (map nat_of_char Enum.enum) = |    301   then have "map char_of_nat (map nat_of_char Enum.enum) = | 
|    387     map char_of_nat [0..<256]" by simp |    302     map char_of_nat [0..<256]" by simp | 
|    388   then show ?thesis by (simp add: comp_def) |    303   then show ?thesis by (simp add: comp_def) | 
|    389 qed |    304 qed | 
|    390  |    305  | 
|    391 setup \<open> |    306 instance proof | 
|    392 let |    307   show UNIV: "UNIV = set (Enum.enum :: char list)" | 
|    393   val nibbles = map_range (Thm.cterm_of @{context} o HOLogic.mk_nibble) 16; |    308     by (simp add: enum_char_unfold UNIV_char_of_nat atLeast0LessThan) | 
|    394   val simpset = |    309   show "distinct (Enum.enum :: char list)" | 
|    395     put_simpset HOL_ss @{context} |    310     by (auto simp add: enum_char_unfold distinct_map intro: inj_onI) | 
|    396       addsimps @{thms nat_of_nibble.simps mult_0 mult_1 add_0 add_0_right arith_simps numeral_plus_one}; |    311   show "\<And>P. Enum.enum_all P \<longleftrightarrow> Ball (UNIV :: char set) P" | 
|    397   fun mk_code_eqn x y = |    312     by (simp add: UNIV enum_all_char_def list_all_iff) | 
|    398     Thm.instantiate' [] [SOME x, SOME y] @{thm nat_of_char_Char} |    313   show "\<And>P. Enum.enum_ex P \<longleftrightarrow> Bex (UNIV :: char set) P" | 
|    399     |> simplify simpset; |    314     by (simp add: UNIV enum_ex_char_def list_ex_iff) | 
|    400   val code_eqns = map_product mk_code_eqn nibbles nibbles; |    315 qed | 
|    401 in |    316  | 
|    402   Global_Theory.note_thmss "" |    317 end | 
|    403     [((@{binding nat_of_char_simps}, []), [(code_eqns, [])])] |    318  | 
|    404   #> snd |    319 lemma char_of_integer_code [code]: | 
|    405 end |    320   "char_of_integer n = Enum.enum ! (nat_of_integer n mod 256)" | 
|    406 \<close> |    321   by (simp add: char_of_integer_def enum_char_unfold) | 
|    407  |         | 
|    408 declare nat_of_char_simps [code] |         | 
|    409  |         | 
|    410 lemma nibble_of_nat_of_char_div_16: |         | 
|    411   "nibble_of_nat (nat_of_char c div 16) = (case c of Char x y \<Rightarrow> x)" |         | 
|    412   by (cases c) |         | 
|    413     (simp add: nat_of_char_Char add.commute nat_of_nibble_less_16) |         | 
|    414  |         | 
|    415 lemma nibble_of_nat_nat_of_char: |         | 
|    416   "nibble_of_nat (nat_of_char c) = (case c of Char x y \<Rightarrow> y)" |         | 
|    417 proof (cases c) |         | 
|    418   case (Char x y) |         | 
|    419   then have *: "nibble_of_nat ((nat_of_nibble y + nat_of_nibble x * 16) mod 16) = y" |         | 
|    420     by (simp add: nibble_of_nat_mod_16) |         | 
|    421   then have "nibble_of_nat (nat_of_nibble y + nat_of_nibble x * 16) = y" |         | 
|    422     by (simp only: nibble_of_nat_mod_16) |         | 
|    423   with Char show ?thesis by (simp add: nat_of_char_Char add.commute) |         | 
|    424 qed |         | 
|    425  |         | 
|    426 code_datatype Char \<comment> \<open>drop case certificate for char\<close> |         | 
|    427  |         | 
|    428 lemma case_char_code [code]: |         | 
|    429   "char f c = (let n = nat_of_char c in f (nibble_of_nat (n div 16)) (nibble_of_nat n))" |         | 
|    430   by (cases c) |         | 
|    431     (simp only: Let_def nibble_of_nat_of_char_div_16 nibble_of_nat_nat_of_char char.case) |         | 
|    432  |         | 
|    433 lemma char_of_nat_enum [code]: |         | 
|    434   "char_of_nat n = Enum.enum ! (n mod 256)" |         | 
|    435   by (simp add: enum_char_unfold) |         | 
|    436  |    322  | 
|    437  |    323  | 
|    438 subsection \<open>Strings as dedicated type\<close> |    324 subsection \<open>Strings as dedicated type\<close> | 
|    439  |    325  | 
|    440 typedef literal = "UNIV :: string set" |    326 typedef literal = "UNIV :: string set" |