src/HOL/Tools/Lifting/lifting_setup.ML
author kuncar
Tue, 03 Apr 2012 16:26:48 +0200
changeset 47308 9caab698dbe4
child 47334 4708384e759d
permissions -rw-r--r--
new package Lifting - initial commit
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
47308
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
     1
(*  Title:      HOL/Tools/Lifting/lifting_setup.ML
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
     2
    Author:     Ondrej Kuncar
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
     3
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
     4
Setting the lifting infranstructure up.
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
     5
*)
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
     6
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
     7
signature LIFTING_SETUP =
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
     8
sig
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
     9
  exception SETUP_LIFTING_INFR of string
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    10
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    11
  val setup_lifting_infr: thm -> thm -> local_theory -> local_theory
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    12
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    13
  val setup_by_typedef_thm: thm -> local_theory -> local_theory
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    14
end;
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    15
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    16
structure Lifting_Seup: LIFTING_SETUP =
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    17
struct
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    18
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    19
infix 0 MRSL
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    20
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    21
fun ants MRSL thm = fold (fn rl => fn thm => rl RS thm) ants thm
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    22
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    23
exception SETUP_LIFTING_INFR of string
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    24
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    25
fun define_cr_rel equiv_thm abs_fun lthy =
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    26
  let
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    27
    fun force_type_of_rel rel forced_ty =
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    28
      let
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    29
        val thy = Proof_Context.theory_of lthy
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    30
        val rel_ty = (domain_type o fastype_of) rel
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    31
        val ty_inst = Sign.typ_match thy (rel_ty, forced_ty) Vartab.empty
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    32
      in
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    33
        Envir.subst_term_types ty_inst rel
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    34
      end
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    35
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    36
    val (rty, qty) = (dest_funT o fastype_of) abs_fun
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    37
    val abs_fun_graph = HOLogic.mk_eq(abs_fun $ Bound 1, Bound 0)
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    38
    val Abs_body = (case (HOLogic.dest_Trueprop o prop_of) equiv_thm of
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    39
      Const (@{const_name equivp}, _) $ _ => abs_fun_graph
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    40
      | Const (@{const_name part_equivp}, _) $ rel => 
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    41
        HOLogic.mk_conj (force_type_of_rel rel rty $ Bound 1 $ Bound 1, abs_fun_graph)
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    42
      | _ => raise SETUP_LIFTING_INFR "unsopported equivalence theorem"
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    43
      )
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    44
    val def_term = Abs ("x", rty, Abs ("y", qty, Abs_body));
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    45
    val qty_name = (fst o dest_Type) qty
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    46
    val cr_rel_name = Binding.prefix_name "cr_" (Binding.qualified_name qty_name)  
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    47
    val (fixed_def_term, lthy') = yield_singleton (Variable.importT_terms) def_term lthy
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    48
    val ((_, (_ , def_thm)), lthy'') =
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    49
      Local_Theory.define ((cr_rel_name, NoSyn), ((Thm.def_binding cr_rel_name, []), fixed_def_term)) lthy'
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    50
  in
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    51
    (def_thm, lthy'')
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    52
  end
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    53
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    54
fun define_abs_type quot_thm lthy =
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    55
  if Lifting_Def.can_generate_code_cert quot_thm then
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    56
    let
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    57
      val abs_type_thm = quot_thm RS @{thm Quotient_abs_rep}
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    58
      val add_abstype_attribute = 
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    59
          Thm.declaration_attribute (fn thm => Context.mapping (Code.add_abstype thm) I)
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    60
        val add_abstype_attrib = Attrib.internal (K add_abstype_attribute);
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    61
    in
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    62
      lthy
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    63
        |> (snd oo Local_Theory.note) ((Binding.empty, [add_abstype_attrib]), [abs_type_thm])
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    64
    end
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    65
  else
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    66
    lthy
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    67
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    68
fun setup_lifting_infr quot_thm equiv_thm lthy =
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    69
  let
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    70
    val (_, qtyp) = Lifting_Term.quot_thm_rty_qty quot_thm
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    71
    val qty_full_name = (fst o dest_Type) qtyp
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    72
    val quotients = { quot_thm = quot_thm }
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    73
    fun quot_info phi = Lifting_Info.transform_quotients phi quotients
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    74
  in
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    75
    lthy
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    76
      |> Local_Theory.declaration {syntax = false, pervasive = true}
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    77
        (fn phi => Lifting_Info.update_quotients qty_full_name (quot_info phi))
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    78
      |> define_abs_type quot_thm
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    79
  end
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    80
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    81
fun setup_by_typedef_thm typedef_thm lthy =
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    82
  let
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    83
    fun derive_quot_and_equiv_thm to_quot_thm to_equiv_thm typedef_thm lthy =
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    84
      let
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    85
        val (_ $ _ $ abs_fun $ _) = (HOLogic.dest_Trueprop o prop_of) typedef_thm
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    86
        val equiv_thm = typedef_thm RS to_equiv_thm
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    87
        val (T_def, lthy') = define_cr_rel equiv_thm abs_fun lthy
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    88
        val quot_thm =  [typedef_thm, T_def] MRSL to_quot_thm
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    89
      in
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    90
        (quot_thm, equiv_thm, lthy')
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    91
      end
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    92
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    93
    val typedef_set = (snd o dest_comb o HOLogic.dest_Trueprop o prop_of) typedef_thm
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    94
    val (quot_thm, equiv_thm, lthy') = (case typedef_set of
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    95
      Const ("Orderings.top_class.top", _) => 
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    96
        derive_quot_and_equiv_thm @{thm copy_type_to_Quotient} @{thm copy_type_to_equivp} 
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    97
          typedef_thm lthy
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    98
      | Const (@{const_name "Collect"}, _) $ Abs (_, _, _) => 
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
    99
        derive_quot_and_equiv_thm @{thm invariant_type_to_Quotient} @{thm invariant_type_to_part_equivp} 
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
   100
          typedef_thm lthy
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
   101
      | _ => raise SETUP_LIFTING_INFR "unsupported typedef theorem")
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
   102
  in
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
   103
    setup_lifting_infr quot_thm equiv_thm lthy'
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
   104
  end
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
   105
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
   106
fun setup_by_typedef_thm_aux xthm lthy = setup_by_typedef_thm (singleton (Attrib.eval_thms lthy) xthm) lthy
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
   107
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
   108
val _ = 
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
   109
  Outer_Syntax.local_theory @{command_spec "setup_lifting"}
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
   110
    "Setup lifting infrastracture" 
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
   111
      (Parse_Spec.xthm >> (fn xthm => setup_by_typedef_thm_aux xthm))
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
   112
9caab698dbe4 new package Lifting - initial commit
kuncar
parents:
diff changeset
   113
end;