theory LiveDemo13 imports Main "HOL-Library.Code_Target_Numeral" begin section \More Types\ codatatype 'a hlist = HNil | HCons 'a "'a hlist" text \The infinite list starting from a given value\ primcorec "from" :: "nat \ nat hlist" where "from x = HCons x (from (Suc x))" export_code "from" in Haskell module_name From record person = name :: string age :: nat record student = person + matrikel :: nat definition "sue = \ name = ''Sue'', age = 27 \" definition "bob = sue \ name := ''Bob'' \" definition "john = \ name = ''John'', age = 32, matrikel = 4711 \" definition "johns_name = name john" definition "bobs_name = name bob" section \Syntax\ definition infix_apply :: "('a \ 'b) \ 'a \ 'b" (infixr "$" 51) where "f $ x = f x" text \Precedence 51 is one above 50, which is the precedence of \<^term>\(=)\, but below 65, which is the precedence of \<^term>\(+)\}\ lemma "f $ g $ x = f (g (x))" unfolding infix_apply_def by auto lemma "f $ x + y = f (x + y)" unfolding infix_apply_def by auto text \Do you know the internal representation of numerals?\ term \100\ ML \@{term 100}\ term "numeral (num.Bit0 (num.Bit1 num.One))" text \Do you know the internal representation of chars and strings?\ typ char text \there is a complex setup for syntax of chars and strings, cf. @{file "~~/src/HOL/Tools/string_syntax.ML"}}\ term \CHR ''a''\ ML \@{term "CHR ''a''"}\ term "char.Char True False False False False True True False" ML \@{term "''abc''"}\ ML \@{term "STR ''abc''"}\ text \Quantifiers, Sums, ...\ text \Click on sum, to see several syntax translations.\ term sum term "\ x \ A. p x" term "\ x. x \ A \ p x" term "Ball A p" term "Ball A (\ x. p x)" term "\ i \ A. f i" term "sum f A" term "\ i \ A. i + 5" term "sum ((+) 5) A" term "sum (\ x. x) A" term "sum (\ x. x + 5) A" term "sum (\ x. 5 + x) A" text \For further information consult Chapter 8 (Inner Syntax) of @{doc "isar-ref"}.\ section \Isabelle/ML\ ML \ val num = 5 val t = HOLogic.mk_Trueprop (HOLogic.mk_eq (@{term "x :: nat"}, HOLogic.mk_number @{typ nat} 5)) val ct = Thm.cterm_of @{context} t val prop = Thm.prop_of @{lemma "(5 + x :: 'a :: {numeral,comm_ring}) = x + 5" by auto} \ ML \@{method auto}\ ML \Clasimp.auto_tac\ text \have a look at \mk_auto_tac\ in @{file \~~/src/Provers/clasimp.ML\}\ text \@{command fun}\ subsection \Example: Integer Implementation of Characters\ text \Observe non-efficient implementation of characters\ definition "test x = (''abc'', CHR ''a'', ''abc'' = x, String.explode (STR ''abc''))" export_code test in Haskell module_name Test_Before typedef char_int = "{x :: int . 0 \ x \ x < 256}" by auto setup_lifting type_definition_char_int lift_definition char_of_ci :: "char_int \ char" is char_of_int . lift_definition int_of_ci :: "char_int \ int" is "\ x. x" . lift_definition char_int_of_int :: "int \ char_int" is "\ x. if 0 \ x \ x < 256 then x else Code.abort (STR ''char_int_of_int argument must be in range 0 .. 255'') (\ _. int_of_char (char_of x))" using unique_euclidean_semiring_numeral_class.pos_mod_bound[of "256 :: int"] unique_euclidean_semiring_numeral_class.pos_mod_sign[of "256 :: int"] by (auto simp: int_of_char_def) lemma int_of_char_of_nat: "int_of_char c = int_of_nat (of_char c :: nat)" proof - define ds where "ds = [digit0 c, digit1 c, digit2 c, digit3 c, digit4 c, digit5 c, digit6 c, digit7 c]" show ?thesis unfolding int_of_char_def unfolding of_char_def ds_def[symmetric] by (induct ds, auto simp: int_of_nat_def) qed code_datatype char_of_ci declare [[code drop: int_of_char char_of_int char_of_integer String.asciis_of_literal ]] lemma int_of_char_code[code]: "int_of_char (char_of_ci x) = int_of_ci x" by (transfer, auto simp: int_of_char_def char_of_int_def unique_euclidean_semiring_numeral_class.mod_less) lemma char_of_int_code[code]: "char_of_int x = char_of_ci (char_int_of_int x)" by (transfer, auto simp: char_of_int_def int_of_char_def) lemma char_of_integer_code[code]: "char_of_integer x = char_of_int (int_of_integer x)" unfolding char_of_int_def char_of_integer_def by (simp add: bit_integer.rep_eq char_of_def) lemma equal_char_code[code]: "equal_class.equal c d = (int_of_char c = int_of_char d)" unfolding equal_char_def int_of_char_of_nat int_of_nat_def by simp (* finally we provide a separate implementation for all 256 characters *) (* we first define all 256 characters (x = 0 .. 255) following the following schema: lift_definition char_x :: char_int is x by simp *) local_setup \ let fun create_char x = Lifting_Def.lift_def Lifting_Def.default_config (Binding.name ("char_" ^ string_of_int x),Mixfix.NoSyn) @{typ char_int} (HOLogic.mk_number @{typ int} x) (fn ctxt => unfold_tac ctxt @{thms eq_onp_def} THEN simp_tac ctxt 1) [] #> #2 in fold create_char (0 upto 255) end \ print_theorems term char_65 (* and then prove code-unfold lemmas of the following shape lemma char_256_unfold[code_unfold]: "CHR 0x00 = char_of_ci char_0" ... "CHR 0xFF = char_of_ci char_255" to replace all concrete characters by their number, so that constructor Char vanishes. *) ML \@{term "CHR 0x00"}\ local_setup \ fn lthy => let val name_prefix = "LiveDemo13.char_" fun create_eq x = let val eq = HOLogic.mk_Trueprop (HOLogic.mk_eq (HOLogic.mk_char x, Const (@{const_name char_of_ci}, @{typ "char_int \ char"}) $ Const (name_prefix ^ string_of_int x, @{typ char_int}))); in Goal.prove_future lthy [] [] eq (fn {context = ctxt, ...} => Transfer.transfer_tac true ctxt 1 THEN unfold_tac ctxt @{thms char_of_int_def char_of_def} THEN simp_tac ctxt 1) end val thms = map create_eq (0 upto 255) in Local_Theory.note ((Binding.name "char_256_unfold", @{attributes [code_unfold]}), thms) lthy |> #2 end \ thm char_256_unfold export_code test in Haskell module_name Test_After end