src/HOL/String.thy
changeset 51160 599ff65b85e2
parent 49972 f11f8905d9fd
child 51717 9e7d1c139569
equal deleted inserted replaced
51159:3fe7242f8346 51160:599ff65b85e2
    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"
   226 proof
   379 proof
   227 qed (auto simp add: equal_literal_def explode_inject)
   380 qed (auto simp add: equal_literal_def explode_inject)
   228 
   381 
   229 end
   382 end
   230 
   383 
   231 lemma STR_inject' [simp]: "(STR xs = STR ys) = (xs = ys)"
   384 lemma STR_inject' [simp]:
   232 by(simp add: STR_inject)
   385   "STR xs = STR ys \<longleftrightarrow> xs = ys"
       
   386   by (simp add: STR_inject)
   233 
   387 
   234 
   388 
   235 subsection {* Code generator *}
   389 subsection {* Code generator *}
   236 
   390 
   237 ML_file "Tools/string_code.ML"
   391 ML_file "Tools/string_code.ML"