1 (* Author: Florian Haftmann, TU Muenchen *)
3 header {* Reflecting Pure types into HOL *}
9 datatype typerep = Typerep String.literal "typerep list"
12 fixes typerep :: "'a itself \<Rightarrow> typerep"
15 definition typerep_of :: "'a \<Rightarrow> typerep" where
16 [simp]: "typerep_of x = typerep TYPE('a)"
21 "_TYPEREP" :: "type => logic" ("(1TYPEREP/(1'(_')))")
25 fun typerep_tr (*"_TYPEREP"*) [ty] =
26 Syntax.const @{const_syntax typerep} $
27 (Syntax.const @{syntax_const "_constrain"} $ Syntax.const @{const_syntax "TYPE"} $
28 (Syntax.const @{type_syntax itself} $ ty))
29 | typerep_tr (*"_TYPEREP"*) ts = raise TERM ("typerep_tr", ts);
30 in [(@{syntax_const "_TYPEREP"}, K typerep_tr)] end
33 typed_print_translation {*
35 fun typerep_tr' ctxt (*"typerep"*)
36 (Type (@{type_name fun}, [Type (@{type_name itself}, [T]), _]))
37 (Const (@{const_syntax TYPE}, _) :: ts) =
39 (Syntax.const @{syntax_const "_TYPEREP"} $ Syntax_Phases.term_of_typ ctxt T, ts)
40 | typerep_tr' _ T ts = raise Match;
41 in [(@{const_syntax typerep}, typerep_tr')] end
47 fun add_typerep tyco thy =
49 val sorts = replicate (Sign.arity_number thy tyco) @{sort typerep};
50 val vs = Name.invent_names Name.context "'a" sorts;
51 val ty = Type (tyco, map TFree vs);
52 val lhs = Const (@{const_name typerep}, Term.itselfT ty --> @{typ typerep})
53 $ Free ("T", Term.itselfT ty);
54 val rhs = @{term Typerep} $ HOLogic.mk_literal tyco
55 $ HOLogic.mk_list @{typ typerep} (map (HOLogic.mk_typerep o TFree) vs);
56 val eq = HOLogic.mk_Trueprop (HOLogic.mk_eq (lhs, rhs));
59 |> Class.instantiation ([tyco], vs, @{sort typerep})
60 |> `(fn lthy => Syntax.check_term lthy eq)
61 |-> (fn eq => Specification.definition (NONE, (Attrib.empty_binding, eq)))
63 |> Class.prove_instantiation_exit (K (Class.intro_classes_tac []))
66 fun ensure_typerep tyco thy =
67 if not (Sorts.has_instance (Sign.classes_of thy) tyco @{sort typerep})
68 andalso Sorts.has_instance (Sign.classes_of thy) tyco @{sort type}
69 then add_typerep tyco thy else thy;
73 add_typerep @{type_name fun}
74 #> Typedef.interpretation ensure_typerep
75 #> Code.datatype_interpretation (ensure_typerep o fst)
76 #> Code.abstype_interpretation (ensure_typerep o fst)
82 "HOL.equal (Typerep tyco1 tys1) (Typerep tyco2 tys2) \<longleftrightarrow> HOL.equal tyco1 tyco2
83 \<and> list_all2 HOL.equal tys1 tys2"
84 by (auto simp add: eq_equal [symmetric] list_all2_eq [symmetric])
87 "HOL.equal (x :: typerep) x \<longleftrightarrow> True"
94 (Eval "Term.Type/ (_, _)")
96 code_reserved Eval Term
98 hide_const (open) typerep Typerep