1 (* Title: HOL/Code_Setup.thy
3 Author: Florian Haftmann
6 header {* Setup of code generators and related tools *}
12 subsection {* Generic code generator foundation *}
16 code_datatype True False
18 code_datatype "TYPE('a\<Colon>{})"
20 code_datatype Trueprop "prop"
22 text {* Code equations *}
25 shows "(True \<Longrightarrow> PROP P) \<equiv> PROP P"
26 and "(False \<Longrightarrow> Q) \<equiv> Trueprop True"
27 and "(PROP P \<Longrightarrow> True) \<equiv> Trueprop True"
28 and "(Q \<Longrightarrow> False) \<equiv> Trueprop (\<not> Q)" by (auto intro!: equal_intr_rule)
31 shows "False \<and> x \<longleftrightarrow> False"
32 and "True \<and> x \<longleftrightarrow> x"
33 and "x \<and> False \<longleftrightarrow> False"
34 and "x \<and> True \<longleftrightarrow> x" by simp_all
37 shows "False \<or> x \<longleftrightarrow> x"
38 and "True \<or> x \<longleftrightarrow> True"
39 and "x \<or> False \<longleftrightarrow> x"
40 and "x \<or> True \<longleftrightarrow> True" by simp_all
43 shows "\<not> True \<longleftrightarrow> False"
44 and "\<not> False \<longleftrightarrow> True" by (rule HOL.simp_thms)+
46 lemmas [code] = Let_def if_True if_False
48 lemmas [code, code unfold, symmetric, code post] = imp_conv_disj
55 lemma equals_eq [code inline, code]: "op = \<equiv> eq"
56 by (rule eq_reflection) (rule ext, rule ext, rule sym, rule eq_equals)
58 declare eq [code unfold, code inline del]
60 declare equals_eq [symmetric, code post]
64 declare simp_thms(6) [code nbe]
70 Code_Unit.add_const_alias @{thm equals_eq}
76 assumes "CASE \<equiv> (\<lambda>x. Let x f)"
77 shows "CASE x \<equiv> f x"
78 using assms by simp_all
81 assumes "CASE \<equiv> (\<lambda>b. If b f g)"
82 shows "(CASE True \<equiv> f) &&& (CASE False \<equiv> g)"
83 using assms by simp_all
86 Code.add_case @{thm Let_case_cert}
87 #> Code.add_case @{thm If_case_cert}
88 #> Code.add_undefined @{const_name undefined}
94 subsection {* Generic code generator preprocessor *}
97 Code.map_pre (K HOL_basic_ss)
98 #> Code.map_post (K HOL_basic_ss)
102 subsection {* Generic code generator target languages *}
111 code_const True and False and Not and "op &" and "op |" and If
112 (SML "true" and "false" and "not"
113 and infixl 1 "andalso" and infixl 0 "orelse"
114 and "!(if (_)/ then (_)/ else (_))")
115 (OCaml "true" and "false" and "not"
116 and infixl 4 "&&" and infixl 2 "||"
117 and "!(if (_)/ then (_)/ else (_))")
118 (Haskell "True" and "False" and "not"
119 and infixl 3 "&&" and infixl 2 "||"
120 and "!(if (_)/ then (_)/ else (_))")
128 text {* using built-in Haskell equality *}
133 code_const "eq_class.eq"
134 (Haskell infixl 4 "==")
137 (Haskell infixl 4 "==")
142 (SML "!(raise/ Fail/ \"undefined\")")
143 (OCaml "failwith/ \"undefined\"")
144 (Haskell "error/ \"undefined\"")
147 subsection {* SML code generator setup *}
152 fun term_of_bool b = if b then HOLogic.true_const else HOLogic.false_const;
156 let val b = one_of [false, true]
157 in (b, fn () => term_of_bool b) end;
162 HOLogic.mk_Trueprop (if b then HOLogic.true_const else HOLogic.false_const);
170 "op |" ("(_ orelse/ _)")
171 "op &" ("(_ andalso/ _)")
172 "If" ("(if _/ then _/ else _)")
177 fun eq_codegen thy defs dep thyname b t gr =
178 (case strip_comb t of
179 (Const ("op =", Type (_, [Type ("fun", _), _])), _) => NONE
180 | (Const ("op =", _), [t, u]) =>
182 val (pt, gr') = Codegen.invoke_codegen thy defs dep thyname false t gr;
183 val (pu, gr'') = Codegen.invoke_codegen thy defs dep thyname false u gr';
184 val (_, gr''') = Codegen.invoke_tycodegen thy defs dep thyname false HOLogic.boolT gr'';
187 (Pretty.block [pt, Codegen.str " =", Pretty.brk 1, pu]), gr''')
189 | (t as Const ("op =", _), ts) => SOME (Codegen.invoke_codegen
190 thy defs dep thyname b (Codegen.eta_expand t ts 2) gr)
194 Codegen.add_codegen "eq_codegen" eq_codegen
199 subsection {* Evaluation and normalization by evaluation *}
202 Value.add_evaluator ("SML", Codegen.eval_term o ProofContext.theory_of)
206 structure Eval_Method =
209 val eval_ref : (unit -> bool) option ref = ref NONE;
214 oracle eval_oracle = {* fn ct =>
216 val thy = Thm.theory_of_cterm ct;
217 val t = Thm.term_of ct;
218 val dummy = @{cprop True};
219 in case try HOLogic.dest_Trueprop t
220 of SOME t' => if Code_ML.eval_term
221 ("Eval_Method.eval_ref", Eval_Method.eval_ref) thy t' []
222 then Thm.capply (Thm.capply @{cterm "op \<equiv> \<Colon> prop \<Rightarrow> prop \<Rightarrow> prop"} ct) dummy
229 fun gen_eval_method conv ctxt = SIMPLE_METHOD'
230 (CONVERSION (Conv.params_conv (~1) (K (Conv.concl_conv (~1) conv)) ctxt)
234 method_setup eval = {* Scan.succeed (gen_eval_method eval_oracle) *}
235 "solve goal by evaluation"
237 method_setup evaluation = {* Scan.succeed (gen_eval_method Codegen.evaluation_conv) *}
238 "solve goal by evaluation"
240 method_setup normalization = {*
241 Scan.succeed (K (SIMPLE_METHOD' (CONVERSION Nbe.norm_conv THEN' (fn k => TRY (rtac TrueI k)))))
242 *} "solve goal by normalization"
245 subsection {* Quickcheck *}
248 Quickcheck.add_generator ("SML", Codegen.test_term)
251 quickcheck_params [size = 5, iterations = 50]