src/HOL/String.thy
changeset 62597 b3f2b8c906a6
parent 62580 7011429f44f9
child 62678 843ff6f1de38
equal deleted inserted replaced
62596:cf79f8866bc3 62597:b3f2b8c906a6
    54 lemma char_of_nat_quasi_inj [simp]:
    54 lemma char_of_nat_quasi_inj [simp]:
    55   "char_of_nat m = char_of_nat n \<longleftrightarrow> m mod 256 = n mod 256"
    55   "char_of_nat m = char_of_nat n \<longleftrightarrow> m mod 256 = n mod 256"
    56   by (simp add: char_of_nat_def Abs_char_inject)
    56   by (simp add: char_of_nat_def Abs_char_inject)
    57 
    57 
    58 lemma inj_on_char_of_nat [simp]:
    58 lemma inj_on_char_of_nat [simp]:
    59   "inj_on char_of_nat {0..<256}"
    59   "inj_on char_of_nat {..<256}"
    60   by (rule inj_onI) simp
    60   by (rule inj_onI) simp
    61 
    61 
    62 lemma nat_of_char_mod_256 [simp]:
    62 lemma nat_of_char_mod_256 [simp]:
    63   "nat_of_char c mod 256 = nat_of_char c"
    63   "nat_of_char c mod 256 = nat_of_char c"
    64   by (cases c) simp
    64   by (cases c) simp
    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"