1 (* Title: HOL/Tools/typecopy_package.ML
3 Author: Florian Haftmann, TU Muenchen
5 Introducing copies of types using trivial typedefs; datatype-like abstraction.
8 signature TYPECOPY_PACKAGE =
11 vs: (string * sort) list,
18 val add_typecopy: bstring * string list -> typ -> (bstring * bstring) option
19 -> theory -> (string * info) * theory
20 val get_typecopies: theory -> string list
21 val get_info: theory -> string -> info option
22 val interpretation: (string -> theory -> theory) -> theory -> theory
23 val print_typecopies: theory -> unit
24 val setup: theory -> theory
27 structure TypecopyPackage: TYPECOPY_PACKAGE =
33 vs: (string * sort) list,
41 structure TypecopyData = TheoryDataFun
43 type T = info Symtab.table;
44 val empty = Symtab.empty;
47 fun merge _ = Symtab.merge (K true);
50 fun print_typecopies thy =
52 val tab = TypecopyData.get thy;
53 fun mk (tyco, { vs, constr, typ, proj = (proj, _), ... } : info) =
54 (Pretty.block o Pretty.breaks) [
55 Syntax.pretty_typ_global thy (Type (tyco, map TFree vs)),
57 (Pretty.str o Sign.extern_const thy) constr,
58 Syntax.pretty_typ_global thy typ,
59 Pretty.block [Pretty.str "(", (Pretty.str o Sign.extern_const thy) proj, Pretty.str ")"]];
61 (Pretty.writeln o Pretty.block o Pretty.fbreaks)
62 (Pretty.str "type copies:" :: map mk (Symtab.dest tab))
65 val get_typecopies = Symtab.keys o TypecopyData.get;
66 val get_info = Symtab.lookup o TypecopyData.get;
69 (* interpretation of type copies *)
71 structure TypecopyInterpretation = InterpretationFun(type T = string val eq = op =);
72 val interpretation = TypecopyInterpretation.interpretation;
79 fun gen_add_typecopy prep_typ (raw_tyco, raw_vs) raw_ty constr_proj thy =
81 val ty = prep_typ thy raw_ty;
82 val vs = AList.make (the_default HOLogic.typeS o AList.lookup (op =) (typ_tfrees ty)) raw_vs;
83 val tac = Tactic.rtac UNIV_witness 1;
84 fun add_info tyco ( { abs_type = ty_abs, rep_type = ty_rep, Abs_name = c_abs,
85 Rep_name = c_rep, Abs_inject = inject,
86 Abs_inverse = inverse, ... } : TypedefPackage.info ) thy =
90 |> Drule.instantiate' [SOME (ctyp_of thy (Logic.varifyT ty_rep))] [];
91 val inject' = inject OF [exists_thm, exists_thm];
92 val proj_def = inverse OF [exists_thm];
98 proj = (c_rep, ty_abs --> ty_rep),
103 |> (TypecopyData.map o Symtab.update_new) (tyco, info)
104 |> TypecopyInterpretation.data tyco
109 |> TypedefPackage.add_typedef_i false (SOME raw_tyco) (raw_tyco, map fst vs, NoSyn)
110 (HOLogic.mk_UNIV ty) (Option.map swap constr_proj) tac
111 |-> (fn (tyco, info) => add_info tyco info)
116 val add_typecopy = gen_add_typecopy Sign.certify_typ;
121 (* code generator setup *)
123 fun add_typecopy_spec tyco thy =
125 val SOME { constr, proj_def, inject, vs, ... } = get_info thy tyco;
126 val vs' = (map o apsnd) (curry (Sorts.inter_sort (Sign.classes_of thy)) [HOLogic.class_eq]) vs;
127 val ty = Logic.unvarifyT (Sign.the_const_type thy constr);
128 fun add_def tyco lthy =
130 val ty = Type (tyco, map TFree vs');
131 fun mk_side const_name = Const (const_name, ty --> ty --> HOLogic.boolT)
132 $ Free ("x", ty) $ Free ("y", ty);
133 val def = HOLogic.mk_Trueprop (HOLogic.mk_eq
134 (mk_side @{const_name eq_class.eq}, mk_side @{const_name "op ="}));
135 val def' = Syntax.check_term lthy def;
136 val ((_, (_, thm)), lthy') = Specification.definition
137 (NONE, ((Name.no_binding, []), def')) lthy;
138 val ctxt_thy = ProofContext.init (ProofContext.theory_of lthy);
139 val thm' = singleton (ProofContext.export lthy' ctxt_thy) thm;
140 in (thm', lthy') end;
141 fun tac thms = Class.intro_classes_tac []
142 THEN ALLGOALS (ProofContext.fact_tac thms);
146 |> Code_Unit.constrain_thm [HOLogic.class_eq]
148 |> MetaSimplifier.rewrite_rule [Thm.transfer thy @{thm equals_eq}];
149 in Code.add_func eq thy end;
152 |> Code.add_datatype [(constr, ty)]
153 |> Code.add_func proj_def
154 |> TheoryTarget.instantiation ([tyco], vs', [HOLogic.class_eq])
156 |-> (fn thm => Class.prove_instantiation_instance (K (tac [thm]))
158 #> ProofContext.theory_of
164 TypecopyInterpretation.init
165 #> interpretation add_typecopy_spec