src/HOL/Tools/Lifting/lifting_setup.ML
author kuncar
Thu, 05 Apr 2012 23:22:54 +0200
changeset 48237 075d22b3a32f
parent 48219 87c0eaf04bad
child 48392 69f95ac85c3d
permissions -rw-r--r--
detect incorrect situations; better error messages; sanity check for quot_thm in setup_lifting_infr
     1 (*  Title:      HOL/Tools/Lifting/lifting_setup.ML
     2     Author:     Ondrej Kuncar
     3 
     4 Setting up the lifting infrastructure.
     5 *)
     6 
     7 signature LIFTING_SETUP =
     8 sig
     9   exception SETUP_LIFTING_INFR of string
    10 
    11   val setup_lifting_infr: thm -> thm -> local_theory -> local_theory
    12 
    13   val setup_by_typedef_thm: thm -> local_theory -> local_theory
    14 end;
    15 
    16 structure Lifting_Setup: LIFTING_SETUP =
    17 struct
    18 
    19 infix 0 MRSL
    20 
    21 fun ants MRSL thm = fold (fn rl => fn thm => rl RS thm) ants thm
    22 
    23 exception SETUP_LIFTING_INFR of string
    24 
    25 fun define_cr_rel rep_fun lthy =
    26   let
    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'
    35   in
    36     (def_thm, lthy'')
    37   end
    38 
    39 fun define_abs_type quot_thm lthy =
    40   if Lifting_Def.can_generate_code_cert quot_thm then
    41     let
    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);
    46     in
    47       lthy
    48         |> (snd oo Local_Theory.note) ((Binding.empty, [add_abstype_attrib]), [abs_type_thm])
    49     end
    50   else
    51     lthy
    52 
    53 fun quot_thm_sanity_check ctxt quot_thm =
    54   let
    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
    61         [] => []
    62       | extras => [Pretty.block ([Pretty.str "Extra variables in the raw type:",
    63                                  Pretty.brk 1] @ 
    64                                  ((Pretty.commas o map (Pretty.str o quote)) extras) @
    65                                  [Pretty.str "."])])
    66     val not_type_constr = 
    67       (case qty of
    68          Type _ => []
    69          | _ => [Pretty.block [Pretty.str "The quotient type ",
    70                                 Pretty.quote (Syntax.pretty_typ ctxt' qty),
    71                                 Pretty.brk 1,
    72                                 Pretty.str "is not a type constructor."]])
    73     val errs = extra_rty_tfrees @ not_type_constr
    74   in
    75     if null errs then () else error (cat_lines (["Sanity check of the quotient theorem failed:",""] 
    76                                                 @ (map Pretty.string_of errs)))
    77   end
    78 
    79 fun setup_lifting_infr quot_thm equiv_thm lthy =
    80   let
    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
    86   in
    87     lthy
    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
    91   end
    92 
    93 fun setup_by_typedef_thm typedef_thm lthy =
    94   let
    95     fun derive_quot_and_equiv_thm to_quot_thm to_equiv_thm typedef_thm lthy =
    96       let
    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
   101       in
   102         (quot_thm, equiv_thm, lthy')
   103       end
   104 
   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} 
   109           typedef_thm lthy
   110       | Const (@{const_name "Collect"}, _) $ Abs (_, _, _) => 
   111         derive_quot_and_equiv_thm @{thm open_typedef_to_Quotient} @{thm open_typedef_to_part_equivp} 
   112           typedef_thm lthy
   113       | _ => derive_quot_and_equiv_thm @{thm typedef_to_Quotient} @{thm typedef_to_part_equivp} 
   114           typedef_thm lthy)
   115   in
   116     setup_lifting_infr quot_thm equiv_thm lthy'
   117   end
   118 
   119 fun setup_by_typedef_thm_aux xthm lthy = setup_by_typedef_thm (singleton (Attrib.eval_thms lthy) xthm) lthy
   120 
   121 val _ = 
   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))
   125 end;