detect incorrect situations; better error messages; sanity check for quot_thm in setup_lifting_infr
1 (* Title: HOL/Tools/Lifting/lifting_setup.ML
4 Setting up the lifting infrastructure.
7 signature LIFTING_SETUP =
9 exception SETUP_LIFTING_INFR of string
11 val setup_lifting_infr: thm -> thm -> local_theory -> local_theory
13 val setup_by_typedef_thm: thm -> local_theory -> local_theory
16 structure Lifting_Setup: LIFTING_SETUP =
21 fun ants MRSL thm = fold (fn rl => fn thm => rl RS thm) ants thm
23 exception SETUP_LIFTING_INFR of string
25 fun define_cr_rel rep_fun lthy =
27 val (qty, rty) = (dest_funT o fastype_of) rep_fun
28 val rep_fun_graph = (HOLogic.eq_const rty) $ Bound 1 $ (rep_fun $ Bound 0)
29 val def_term = Abs ("x", rty, Abs ("y", qty, rep_fun_graph));
30 val qty_name = (fst o dest_Type) qty
31 val cr_rel_name = Binding.prefix_name "cr_" (Binding.qualified_name qty_name)
32 val (fixed_def_term, lthy') = yield_singleton (Variable.importT_terms) def_term lthy
33 val ((_, (_ , def_thm)), lthy'') =
34 Local_Theory.define ((cr_rel_name, NoSyn), ((Thm.def_binding cr_rel_name, []), fixed_def_term)) lthy'
39 fun define_abs_type quot_thm lthy =
40 if Lifting_Def.can_generate_code_cert quot_thm then
42 val abs_type_thm = quot_thm RS @{thm Quotient_abs_rep}
43 val add_abstype_attribute =
44 Thm.declaration_attribute (fn thm => Context.mapping (Code.add_abstype thm) I)
45 val add_abstype_attrib = Attrib.internal (K add_abstype_attribute);
48 |> (snd oo Local_Theory.note) ((Binding.empty, [add_abstype_attrib]), [abs_type_thm])
53 fun quot_thm_sanity_check ctxt quot_thm =
55 val ((_, [quot_thm_fixed]), ctxt') = Variable.importT [quot_thm] ctxt
56 val (rty, qty) = Lifting_Term.quot_thm_rty_qty quot_thm_fixed
57 val rty_tfreesT = Term.add_tfree_namesT rty []
58 val qty_tfreesT = Term.add_tfree_namesT qty []
59 val extra_rty_tfrees =
60 (case subtract (op =) qty_tfreesT rty_tfreesT of
62 | extras => [Pretty.block ([Pretty.str "Extra variables in the raw type:",
64 ((Pretty.commas o map (Pretty.str o quote)) extras) @
69 | _ => [Pretty.block [Pretty.str "The quotient type ",
70 Pretty.quote (Syntax.pretty_typ ctxt' qty),
72 Pretty.str "is not a type constructor."]])
73 val errs = extra_rty_tfrees @ not_type_constr
75 if null errs then () else error (cat_lines (["Sanity check of the quotient theorem failed:",""]
76 @ (map Pretty.string_of errs)))
79 fun setup_lifting_infr quot_thm equiv_thm lthy =
81 val _ = quot_thm_sanity_check lthy quot_thm
82 val (_, qtyp) = Lifting_Term.quot_thm_rty_qty quot_thm
83 val qty_full_name = (fst o dest_Type) qtyp
84 val quotients = { quot_thm = quot_thm }
85 fun quot_info phi = Lifting_Info.transform_quotients phi quotients
88 |> Local_Theory.declaration {syntax = false, pervasive = true}
89 (fn phi => Lifting_Info.update_quotients qty_full_name (quot_info phi))
90 |> define_abs_type quot_thm
93 fun setup_by_typedef_thm typedef_thm lthy =
95 fun derive_quot_and_equiv_thm to_quot_thm to_equiv_thm typedef_thm lthy =
97 val (_ $ rep_fun $ _ $ _) = (HOLogic.dest_Trueprop o prop_of) typedef_thm
98 val equiv_thm = typedef_thm RS to_equiv_thm
99 val (T_def, lthy') = define_cr_rel rep_fun lthy
100 val quot_thm = [typedef_thm, T_def] MRSL to_quot_thm
102 (quot_thm, equiv_thm, lthy')
105 val typedef_set = (snd o dest_comb o HOLogic.dest_Trueprop o prop_of) typedef_thm
106 val (quot_thm, equiv_thm, lthy') = (case typedef_set of
107 Const ("Orderings.top_class.top", _) =>
108 derive_quot_and_equiv_thm @{thm UNIV_typedef_to_Quotient} @{thm UNIV_typedef_to_equivp}
110 | Const (@{const_name "Collect"}, _) $ Abs (_, _, _) =>
111 derive_quot_and_equiv_thm @{thm open_typedef_to_Quotient} @{thm open_typedef_to_part_equivp}
113 | _ => derive_quot_and_equiv_thm @{thm typedef_to_Quotient} @{thm typedef_to_part_equivp}
116 setup_lifting_infr quot_thm equiv_thm lthy'
119 fun setup_by_typedef_thm_aux xthm lthy = setup_by_typedef_thm (singleton (Attrib.eval_thms lthy) xthm) lthy
122 Outer_Syntax.local_theory @{command_spec "setup_lifting"}
123 "Setup lifting infrastructure"
124 (Parse_Spec.xthm >> (fn xthm => setup_by_typedef_thm_aux xthm))