| author | wenzelm | 
| Mon, 29 Sep 2008 11:46:47 +0200 | |
| changeset 28397 | 389c5e494605 | 
| parent 28394 | b9c8e3a12a98 | 
| child 28562 | 4e74209f113e | 
| permissions | -rw-r--r-- | 
| 28228 | 1  | 
(* Title: HOL/Code_Eval.thy  | 
2  | 
ID: $Id$  | 
|
3  | 
Author: Florian Haftmann, TU Muenchen  | 
|
4  | 
*)  | 
|
5  | 
||
6  | 
header {* Term evaluation using the generic code generator *}
 | 
|
7  | 
||
8  | 
theory Code_Eval  | 
|
| 28313 | 9  | 
imports Plain "~~/src/HOL/Library/RType"  | 
| 28228 | 10  | 
begin  | 
11  | 
||
12  | 
subsection {* Term representation *}
 | 
|
13  | 
||
14  | 
subsubsection {* Terms and class @{text term_of} *}
 | 
|
15  | 
||
16  | 
datatype "term" = dummy_term  | 
|
17  | 
||
18  | 
definition  | 
|
| 28335 | 19  | 
Const :: "message_string \<Rightarrow> typerep \<Rightarrow> term"  | 
| 28228 | 20  | 
where  | 
21  | 
"Const _ _ = dummy_term"  | 
|
22  | 
||
23  | 
definition  | 
|
24  | 
App :: "term \<Rightarrow> term \<Rightarrow> term"  | 
|
25  | 
where  | 
|
26  | 
"App _ _ = dummy_term"  | 
|
27  | 
||
28  | 
code_datatype Const App  | 
|
29  | 
||
| 28335 | 30  | 
class term_of = typerep +  | 
| 28228 | 31  | 
fixes term_of :: "'a \<Rightarrow> term"  | 
32  | 
||
33  | 
lemma term_of_anything: "term_of x \<equiv> t"  | 
|
34  | 
by (rule eq_reflection) (cases "term_of x", cases t, simp)  | 
|
35  | 
||
36  | 
ML {*
 | 
|
37  | 
structure Eval =  | 
|
38  | 
struct  | 
|
39  | 
||
40  | 
fun mk_term f g (Const (c, ty)) =  | 
|
41  | 
      @{term Const} $ Message_String.mk c $ g ty
 | 
|
42  | 
| mk_term f g (t1 $ t2) =  | 
|
43  | 
      @{term App} $ mk_term f g t1 $ mk_term f g t2
 | 
|
44  | 
| mk_term f g (Free v) = f v  | 
|
45  | 
| mk_term f g (Bound i) = Bound i  | 
|
46  | 
  | mk_term f g (Abs (v, _, t)) = Abs (v, @{typ term}, mk_term f g t);
 | 
|
47  | 
||
48  | 
fun mk_term_of ty t = Const (@{const_name term_of}, ty --> @{typ term}) $ t;
 | 
|
49  | 
||
50  | 
end;  | 
|
51  | 
*}  | 
|
52  | 
||
53  | 
||
54  | 
subsubsection {* @{text term_of} instances *}
 | 
|
55  | 
||
56  | 
setup {*
 | 
|
57  | 
let  | 
|
58  | 
fun add_term_of_def ty vs tyco thy =  | 
|
59  | 
let  | 
|
60  | 
      val lhs = Const (@{const_name term_of}, ty --> @{typ term})
 | 
|
61  | 
        $ Free ("x", ty);
 | 
|
62  | 
      val rhs = @{term "undefined \<Colon> term"};
 | 
|
63  | 
val eq = HOLogic.mk_Trueprop (HOLogic.mk_eq (lhs, rhs));  | 
|
| 28243 | 64  | 
fun triv_name_of t = (fst o dest_Free o fst o strip_comb o fst  | 
65  | 
o HOLogic.dest_eq o HOLogic.dest_Trueprop) t ^ "_triv";  | 
|
| 28228 | 66  | 
in  | 
67  | 
thy  | 
|
68  | 
      |> TheoryTarget.instantiation ([tyco], vs, @{sort term_of})
 | 
|
69  | 
|> `(fn lthy => Syntax.check_term lthy eq)  | 
|
| 28243 | 70  | 
|-> (fn eq => Specification.definition (NONE, ((Name.binding (triv_name_of eq), []), eq)))  | 
| 28228 | 71  | 
|> snd  | 
72  | 
|> Class.prove_instantiation_instance (K (Class.intro_classes_tac []))  | 
|
| 28394 | 73  | 
|> LocalTheory.exit_global  | 
| 28228 | 74  | 
end;  | 
75  | 
fun interpretator (tyco, (raw_vs, _)) thy =  | 
|
76  | 
let  | 
|
77  | 
      val has_inst = can (Sorts.mg_domain (Sign.classes_of thy) tyco) @{sort term_of};
 | 
|
78  | 
val constrain_sort =  | 
|
79  | 
        curry (Sorts.inter_sort (Sign.classes_of thy)) @{sort term_of};
 | 
|
80  | 
val vs = (map o apsnd) constrain_sort raw_vs;  | 
|
81  | 
val ty = Type (tyco, map TFree vs);  | 
|
82  | 
in  | 
|
83  | 
thy  | 
|
| 28335 | 84  | 
|> Typerep.perhaps_add_def tyco  | 
| 28228 | 85  | 
|> not has_inst ? add_term_of_def ty vs tyco  | 
86  | 
end;  | 
|
87  | 
in  | 
|
88  | 
Code.type_interpretation interpretator  | 
|
89  | 
end  | 
|
90  | 
*}  | 
|
91  | 
||
92  | 
setup {*
 | 
|
93  | 
let  | 
|
94  | 
fun mk_term_of_eq ty vs tyco (c, tys) =  | 
|
95  | 
let  | 
|
96  | 
val t = list_comb (Const (c, tys ---> ty),  | 
|
97  | 
map Free (Name.names Name.context "a" tys));  | 
|
98  | 
in (map_aterms (fn Free (v, ty) => Var ((v, 0), ty) | t => t) t, Eval.mk_term  | 
|
99  | 
(fn (v, ty) => Eval.mk_term_of ty (Var ((v, 0), ty)))  | 
|
| 28335 | 100  | 
(Typerep.mk (fn (v, sort) => Typerep.typerep (TFree (v, sort)))) t)  | 
| 28228 | 101  | 
end;  | 
102  | 
fun prove_term_of_eq ty eq thy =  | 
|
103  | 
let  | 
|
104  | 
val cty = Thm.ctyp_of thy ty;  | 
|
105  | 
val (arg, rhs) = pairself (Thm.cterm_of thy) eq;  | 
|
106  | 
      val thm = @{thm term_of_anything}
 | 
|
107  | 
|> Drule.instantiate' [SOME cty] [SOME arg, SOME rhs]  | 
|
108  | 
|> Thm.varifyT;  | 
|
109  | 
in  | 
|
110  | 
thy  | 
|
| 28370 | 111  | 
|> Code.add_eqn thm  | 
| 28228 | 112  | 
end;  | 
113  | 
fun interpretator (tyco, (raw_vs, raw_cs)) thy =  | 
|
114  | 
let  | 
|
115  | 
val constrain_sort =  | 
|
116  | 
        curry (Sorts.inter_sort (Sign.classes_of thy)) @{sort term_of};
 | 
|
117  | 
val vs = (map o apsnd) constrain_sort raw_vs;  | 
|
118  | 
val cs = (map o apsnd o map o map_atyps)  | 
|
119  | 
(fn TFree (v, sort) => TFree (v, constrain_sort sort)) raw_cs;  | 
|
120  | 
val ty = Type (tyco, map TFree vs);  | 
|
121  | 
val eqs = map (mk_term_of_eq ty vs tyco) cs;  | 
|
122  | 
      val const = AxClass.param_of_inst thy (@{const_name term_of}, tyco);
 | 
|
123  | 
in  | 
|
124  | 
thy  | 
|
| 28370 | 125  | 
|> Code.del_eqns const  | 
| 28228 | 126  | 
|> fold (prove_term_of_eq ty) eqs  | 
127  | 
end;  | 
|
128  | 
in  | 
|
129  | 
Code.type_interpretation interpretator  | 
|
130  | 
end  | 
|
131  | 
*}  | 
|
132  | 
||
133  | 
||
134  | 
subsubsection {* Code generator setup *}
 | 
|
135  | 
||
136  | 
lemmas [code func del] = term.recs term.cases term.size  | 
|
| 
28346
 
b8390cd56b8f
discontinued special treatment of op = vs. eq_class.eq
 
haftmann 
parents: 
28335 
diff
changeset
 | 
137  | 
lemma [code func, code func del]: "eq_class.eq (t1\<Colon>term) t2 \<longleftrightarrow> eq_class.eq t1 t2" ..  | 
| 28228 | 138  | 
|
| 28335 | 139  | 
lemma [code func, code func del]: "(term_of \<Colon> typerep \<Rightarrow> term) = term_of" ..  | 
| 28228 | 140  | 
lemma [code func, code func del]: "(term_of \<Colon> term \<Rightarrow> term) = term_of" ..  | 
141  | 
lemma [code func, code func del]: "(term_of \<Colon> message_string \<Rightarrow> term) = term_of" ..  | 
|
142  | 
||
| 28335 | 143  | 
lemma term_of_char [unfolded typerep_fun_def typerep_char_def typerep_nibble_def, code func]: "Code_Eval.term_of c =  | 
| 28243 | 144  | 
(let (n, m) = nibble_pair_of_char c  | 
| 28335 | 145  | 
in Code_Eval.App (Code_Eval.App (Code_Eval.Const (STR ''Pair'') (TYPEREP(nibble \<Rightarrow> nibble \<Rightarrow> char)))  | 
| 28243 | 146  | 
(Code_Eval.term_of n)) (Code_Eval.term_of m))"  | 
147  | 
by (subst term_of_anything) rule  | 
|
148  | 
||
| 28228 | 149  | 
code_type "term"  | 
150  | 
(SML "Term.term")  | 
|
151  | 
||
152  | 
code_const Const and App  | 
|
153  | 
(SML "Term.Const/ (_, _)" and "Term.$/ (_, _)")  | 
|
154  | 
||
155  | 
code_const "term_of \<Colon> message_string \<Rightarrow> term"  | 
|
156  | 
(SML "Message'_String.mk")  | 
|
157  | 
||
158  | 
||
159  | 
subsection {* Evaluation setup *}
 | 
|
160  | 
||
161  | 
ML {*
 | 
|
162  | 
signature EVAL =  | 
|
163  | 
sig  | 
|
164  | 
val mk_term: ((string * typ) -> term) -> (typ -> term) -> term -> term  | 
|
165  | 
val eval_ref: (unit -> term) option ref  | 
|
166  | 
val eval_term: theory -> term -> term  | 
|
167  | 
end;  | 
|
168  | 
||
169  | 
structure Eval : EVAL =  | 
|
170  | 
struct  | 
|
171  | 
||
172  | 
open Eval;  | 
|
173  | 
||
174  | 
val eval_ref = ref (NONE : (unit -> term) option);  | 
|
175  | 
||
176  | 
fun eval_term thy t =  | 
|
177  | 
t  | 
|
178  | 
|> Eval.mk_term_of (fastype_of t)  | 
|
179  | 
  |> (fn t => Code_ML.eval_term ("Eval.eval_ref", eval_ref) thy t [])
 | 
|
180  | 
|> Code.postprocess_term thy;  | 
|
181  | 
||
182  | 
end;  | 
|
183  | 
*}  | 
|
184  | 
||
185  | 
setup {*
 | 
|
186  | 
  Value.add_evaluator ("code", Eval.eval_term o ProofContext.theory_of)
 | 
|
187  | 
*}  | 
|
188  | 
||
| 28243 | 189  | 
|
190  | 
subsubsection {* Syntax *}
 | 
|
191  | 
||
192  | 
print_translation {*
 | 
|
193  | 
let  | 
|
194  | 
  val term = Const ("<TERM>", dummyT);
 | 
|
195  | 
fun tr1' [_, _] = term;  | 
|
196  | 
fun tr2' [] = term;  | 
|
197  | 
in  | 
|
198  | 
  [(@{const_syntax Const}, tr1'),
 | 
|
199  | 
    (@{const_syntax App}, tr1'),
 | 
|
200  | 
    (@{const_syntax dummy_term}, tr2')]
 | 
|
| 28228 | 201  | 
end  | 
| 28243 | 202  | 
*}  | 
203  | 
||
204  | 
hide const dummy_term  | 
|
205  | 
hide (open) const Const App  | 
|
206  | 
hide (open) const term_of  | 
|
207  | 
||
208  | 
end  |