haftmann@31048
|
1 |
(* Author: Florian Haftmann, TU Muenchen *)
|
haftmann@26168
|
2 |
|
haftmann@26168
|
3 |
header {* Reflecting Pure types into HOL *}
|
haftmann@26168
|
4 |
|
haftmann@28952
|
5 |
theory Typerep
|
haftmann@51112
|
6 |
imports String
|
haftmann@26168
|
7 |
begin
|
haftmann@26168
|
8 |
|
haftmann@31205
|
9 |
datatype typerep = Typerep String.literal "typerep list"
|
haftmann@26168
|
10 |
|
haftmann@28335
|
11 |
class typerep =
|
haftmann@31031
|
12 |
fixes typerep :: "'a itself \<Rightarrow> typerep"
|
haftmann@26168
|
13 |
begin
|
haftmann@26168
|
14 |
|
haftmann@29574
|
15 |
definition typerep_of :: "'a \<Rightarrow> typerep" where
|
haftmann@28335
|
16 |
[simp]: "typerep_of x = typerep TYPE('a)"
|
haftmann@26168
|
17 |
|
haftmann@26168
|
18 |
end
|
haftmann@26168
|
19 |
|
wenzelm@35115
|
20 |
syntax
|
wenzelm@35115
|
21 |
"_TYPEREP" :: "type => logic" ("(1TYPEREP/(1'(_')))")
|
wenzelm@35115
|
22 |
|
wenzelm@35115
|
23 |
parse_translation {*
|
wenzelm@52143
|
24 |
let
|
wenzelm@52143
|
25 |
fun typerep_tr (*"_TYPEREP"*) [ty] =
|
wenzelm@52143
|
26 |
Syntax.const @{const_syntax typerep} $
|
wenzelm@52143
|
27 |
(Syntax.const @{syntax_const "_constrain"} $ Syntax.const @{const_syntax "TYPE"} $
|
wenzelm@52143
|
28 |
(Syntax.const @{type_syntax itself} $ ty))
|
wenzelm@52143
|
29 |
| typerep_tr (*"_TYPEREP"*) ts = raise TERM ("typerep_tr", ts);
|
wenzelm@52143
|
30 |
in [(@{syntax_const "_TYPEREP"}, K typerep_tr)] end
|
wenzelm@35115
|
31 |
*}
|
wenzelm@35115
|
32 |
|
wenzelm@52143
|
33 |
typed_print_translation {*
|
wenzelm@52143
|
34 |
let
|
wenzelm@52143
|
35 |
fun typerep_tr' ctxt (*"typerep"*)
|
wenzelm@52143
|
36 |
(Type (@{type_name fun}, [Type (@{type_name itself}, [T]), _]))
|
wenzelm@52143
|
37 |
(Const (@{const_syntax TYPE}, _) :: ts) =
|
wenzelm@52143
|
38 |
Term.list_comb
|
wenzelm@52143
|
39 |
(Syntax.const @{syntax_const "_TYPEREP"} $ Syntax_Phases.term_of_typ ctxt T, ts)
|
wenzelm@52143
|
40 |
| typerep_tr' _ T ts = raise Match;
|
wenzelm@52143
|
41 |
in [(@{const_syntax typerep}, typerep_tr')] end
|
haftmann@26168
|
42 |
*}
|
haftmann@26168
|
43 |
|
haftmann@31137
|
44 |
setup {*
|
haftmann@31137
|
45 |
let
|
haftmann@26168
|
46 |
|
haftmann@31137
|
47 |
fun add_typerep tyco thy =
|
haftmann@26168
|
48 |
let
|
haftmann@28335
|
49 |
val sorts = replicate (Sign.arity_number thy tyco) @{sort typerep};
|
wenzelm@43329
|
50 |
val vs = Name.invent_names Name.context "'a" sorts;
|
haftmann@26168
|
51 |
val ty = Type (tyco, map TFree vs);
|
haftmann@28335
|
52 |
val lhs = Const (@{const_name typerep}, Term.itselfT ty --> @{typ typerep})
|
haftmann@26168
|
53 |
$ Free ("T", Term.itselfT ty);
|
haftmann@31205
|
54 |
val rhs = @{term Typerep} $ HOLogic.mk_literal tyco
|
haftmann@31137
|
55 |
$ HOLogic.mk_list @{typ typerep} (map (HOLogic.mk_typerep o TFree) vs);
|
haftmann@26168
|
56 |
val eq = HOLogic.mk_Trueprop (HOLogic.mk_eq (lhs, rhs));
|
haftmann@26168
|
57 |
in
|
haftmann@26168
|
58 |
thy
|
haftmann@38348
|
59 |
|> Class.instantiation ([tyco], vs, @{sort typerep})
|
haftmann@26168
|
60 |
|> `(fn lthy => Syntax.check_term lthy eq)
|
haftmann@28965
|
61 |
|-> (fn eq => Specification.definition (NONE, (Attrib.empty_binding, eq)))
|
haftmann@26168
|
62 |
|> snd
|
haftmann@31137
|
63 |
|> Class.prove_instantiation_exit (K (Class.intro_classes_tac []))
|
haftmann@26168
|
64 |
end;
|
haftmann@26168
|
65 |
|
wenzelm@45693
|
66 |
fun ensure_typerep tyco thy =
|
wenzelm@48272
|
67 |
if not (Sorts.has_instance (Sign.classes_of thy) tyco @{sort typerep})
|
wenzelm@48272
|
68 |
andalso Sorts.has_instance (Sign.classes_of thy) tyco @{sort type}
|
haftmann@31137
|
69 |
then add_typerep tyco thy else thy;
|
haftmann@31137
|
70 |
|
haftmann@31137
|
71 |
in
|
haftmann@26168
|
72 |
|
haftmann@31137
|
73 |
add_typerep @{type_name fun}
|
haftmann@31723
|
74 |
#> Typedef.interpretation ensure_typerep
|
haftmann@35299
|
75 |
#> Code.datatype_interpretation (ensure_typerep o fst)
|
haftmann@35299
|
76 |
#> Code.abstype_interpretation (ensure_typerep o fst)
|
haftmann@26168
|
77 |
|
haftmann@31137
|
78 |
end
|
haftmann@26168
|
79 |
*}
|
haftmann@26168
|
80 |
|
haftmann@28562
|
81 |
lemma [code]:
|
haftmann@38857
|
82 |
"HOL.equal (Typerep tyco1 tys1) (Typerep tyco2 tys2) \<longleftrightarrow> HOL.equal tyco1 tyco2
|
haftmann@38857
|
83 |
\<and> list_all2 HOL.equal tys1 tys2"
|
haftmann@38857
|
84 |
by (auto simp add: eq_equal [symmetric] list_all2_eq [symmetric])
|
haftmann@38857
|
85 |
|
haftmann@38857
|
86 |
lemma [code nbe]:
|
haftmann@38857
|
87 |
"HOL.equal (x :: typerep) x \<longleftrightarrow> True"
|
haftmann@38857
|
88 |
by (fact equal_refl)
|
haftmann@26168
|
89 |
|
haftmann@28335
|
90 |
code_type typerep
|
haftmann@31031
|
91 |
(Eval "Term.typ")
|
haftmann@26168
|
92 |
|
haftmann@28335
|
93 |
code_const Typerep
|
haftmann@31031
|
94 |
(Eval "Term.Type/ (_, _)")
|
haftmann@26168
|
95 |
|
haftmann@31031
|
96 |
code_reserved Eval Term
|
haftmann@26168
|
97 |
|
wenzelm@36176
|
98 |
hide_const (open) typerep Typerep
|
haftmann@26168
|
99 |
|
haftmann@26168
|
100 |
end
|