src/HOL/Tools/Lifting/lifting_bnf.ML
author kuncar
Thu, 10 Apr 2014 17:48:18 +0200
changeset 57866 f4ba736040fa
child 58019 660ffb526069
permissions -rw-r--r--
setup for Transfer and Lifting from BNF; tuned thm names
kuncar@57866
     1
(*  Title:      HOL/Tools/Transfer/transfer_bnf.ML
kuncar@57866
     2
    Author:     Ondrej Kuncar, TU Muenchen
kuncar@57866
     3
kuncar@57866
     4
Setup for Lifting for types that are BNF.
kuncar@57866
     5
*)
kuncar@57866
     6
kuncar@57866
     7
signature LIFTING_BNF =
kuncar@57866
     8
sig
kuncar@57866
     9
end
kuncar@57866
    10
kuncar@57866
    11
structure Lifting_BNF : LIFTING_BNF =
kuncar@57866
    12
struct
kuncar@57866
    13
kuncar@57866
    14
open BNF_Util
kuncar@57866
    15
open BNF_Def
kuncar@57866
    16
open Transfer_BNF
kuncar@57866
    17
kuncar@57866
    18
(* Quotient map theorem *)
kuncar@57866
    19
kuncar@57866
    20
fun Quotient_tac bnf ctxt i =
kuncar@57866
    21
  let
kuncar@57866
    22
    val rel_Grp = rel_Grp_of_bnf bnf
kuncar@57866
    23
    fun get_lhs thm = thm |> concl_of |> HOLogic.dest_Trueprop |> HOLogic.dest_eq |> fst
kuncar@57866
    24
    val vars = get_lhs rel_Grp |> strip_comb |> snd |> map_filter (try (strip_comb #> snd #> hd))
kuncar@57866
    25
    val UNIVs = map (fn var => HOLogic.mk_UNIV (var |> dest_Var |> snd |> dest_Type |> snd |> hd)) vars
kuncar@57866
    26
    val inst = map2 (curry(pairself (certify ctxt))) vars UNIVs
kuncar@57866
    27
    val rel_Grp_UNIV_sym = rel_Grp |> Drule.instantiate_normalize ([], inst) 
kuncar@57866
    28
      |> Local_Defs.unfold ctxt @{thms subset_UNIV[THEN eqTrueI] UNIV_def[symmetric] simp_thms(21)}
kuncar@57866
    29
      |> (fn thm => thm RS sym)
kuncar@57866
    30
    val rel_mono = rel_mono_of_bnf bnf
kuncar@57866
    31
    val rel_conversep_sym = rel_conversep_of_bnf bnf RS sym
kuncar@57866
    32
  in
kuncar@57866
    33
    EVERY' [SELECT_GOAL (Local_Defs.unfold_tac ctxt [@{thm Quotient_alt_def5}]), 
kuncar@57866
    34
      REPEAT_DETERM o (etac conjE), rtac conjI, SELECT_GOAL (Local_Defs.unfold_tac ctxt [rel_Grp_UNIV_sym]),
kuncar@57866
    35
      rtac rel_mono THEN_ALL_NEW atac, rtac conjI, SELECT_GOAL (Local_Defs.unfold_tac ctxt
kuncar@57866
    36
        [rel_conversep_sym, rel_Grp_UNIV_sym]), rtac rel_mono THEN_ALL_NEW atac,
kuncar@57866
    37
      SELECT_GOAL (Local_Defs.unfold_tac ctxt [rel_conversep_sym, rel_OO_of_bnf bnf RS sym]),
kuncar@57866
    38
      hyp_subst_tac ctxt, rtac refl] i
kuncar@57866
    39
  end
kuncar@57866
    40
kuncar@57866
    41
fun mk_Quotient args =
kuncar@57866
    42
  let
kuncar@57866
    43
    val argTs = map fastype_of args
kuncar@57866
    44
  in
kuncar@57866
    45
    list_comb (Const (@{const_name Quotient}, argTs ---> HOLogic.boolT), args)
kuncar@57866
    46
  end
kuncar@57866
    47
kuncar@57866
    48
fun prove_Quotient_map bnf ctxt =
kuncar@57866
    49
  let
kuncar@57866
    50
    val live = live_of_bnf bnf
kuncar@57866
    51
    val old_ctxt = ctxt
kuncar@57866
    52
    val (((As, Bs), Ds), ctxt) = ctxt
kuncar@57866
    53
      |> mk_TFrees live
kuncar@57866
    54
      ||>> mk_TFrees live
kuncar@57866
    55
      ||>> mk_TFrees (dead_of_bnf bnf)
kuncar@57866
    56
    val argTss = map2 (fn a => fn b => [mk_pred2T a a, a --> b, b --> a,mk_pred2T a b]) As Bs
kuncar@57866
    57
    val ((argss, argss'), ctxt) = fold_map2 mk_Frees ["R", "Abs", "Rep", "T"] (transpose argTss) ctxt
kuncar@57866
    58
      |>> `transpose
kuncar@57866
    59
   
kuncar@57866
    60
    val assms = map (mk_Quotient #> HOLogic.mk_Trueprop) argss
kuncar@57866
    61
    val R_rel = list_comb (mk_rel_of_bnf Ds As As bnf, nth argss' 0)
kuncar@57866
    62
    val Abs_map = list_comb (mk_map_of_bnf Ds As Bs bnf, nth argss' 1)
kuncar@57866
    63
    val Rep_map = list_comb (mk_map_of_bnf Ds Bs As bnf, nth argss' 2)
kuncar@57866
    64
    val T_rel = list_comb (mk_rel_of_bnf Ds As Bs bnf, nth argss' 3)
kuncar@57866
    65
    val concl = mk_Quotient [R_rel, Abs_map, Rep_map, T_rel] |> HOLogic.mk_Trueprop
kuncar@57866
    66
    val goal = Logic.list_implies (assms, concl)
kuncar@57866
    67
    val thm = Goal.prove ctxt [] [] goal 
kuncar@57866
    68
      (fn {context = ctxt, prems = _} => Quotient_tac bnf ctxt 1)
kuncar@57866
    69
  in
kuncar@57866
    70
    Drule.zero_var_indexes (singleton (Variable.export ctxt old_ctxt) thm)
kuncar@57866
    71
  end
kuncar@57866
    72
kuncar@57866
    73
kuncar@57866
    74
fun Quotient_map bnf ctxt =
kuncar@57866
    75
  let
kuncar@57866
    76
    val Quotient = prove_Quotient_map bnf ctxt
kuncar@57866
    77
    fun qualify defname suffix = Binding.qualified true suffix defname
kuncar@57866
    78
    val Quotient_thm_name = qualify (base_name_of_bnf bnf) "Quotient"
kuncar@57866
    79
    val notes = [((Quotient_thm_name, []), [([Quotient], @{attributes [quot_map]})])]
kuncar@57866
    80
  in
kuncar@57866
    81
    notes
kuncar@57866
    82
  end
kuncar@57866
    83
kuncar@57866
    84
(* relator_eq_onp  *)
kuncar@57866
    85
kuncar@57866
    86
fun relator_eq_onp bnf ctxt =
kuncar@57866
    87
  let
kuncar@57866
    88
    val pred_data = lookup_defined_pred_data ctxt (type_name_of_bnf bnf)
kuncar@57866
    89
  in
kuncar@57866
    90
    [((Binding.empty, []), [([Transfer.rel_eq_onp pred_data], @{attributes [relator_eq_onp]})])]    
kuncar@57866
    91
  end
kuncar@57866
    92
kuncar@57866
    93
(* relator_mono  *)
kuncar@57866
    94
kuncar@57866
    95
fun relator_mono bnf =
kuncar@57866
    96
  [((Binding.empty, []), [([rel_mono_of_bnf bnf], @{attributes [relator_mono]})])]    
kuncar@57866
    97
  
kuncar@57866
    98
(* relator_distr  *)
kuncar@57866
    99
kuncar@57866
   100
fun relator_distr bnf =
kuncar@57866
   101
  [((Binding.empty, []), [([rel_OO_of_bnf bnf RS sym], @{attributes [relator_distr]})])]
kuncar@57866
   102
kuncar@57866
   103
(* interpretation *)
kuncar@57866
   104
kuncar@57866
   105
fun lifting_bnf_interpretation bnf lthy =
kuncar@57866
   106
  if dead_of_bnf bnf > 0 then lthy
kuncar@57866
   107
  else
kuncar@57866
   108
    let
kuncar@57866
   109
      val notes = relator_eq_onp bnf lthy @ Quotient_map bnf lthy @ relator_mono bnf
kuncar@57866
   110
        @ relator_distr bnf
kuncar@57866
   111
    in
kuncar@57866
   112
      snd (Local_Theory.notes notes lthy)
kuncar@57866
   113
    end
kuncar@57866
   114
kuncar@57866
   115
val _ = Context.>> (Context.map_theory (bnf_interpretation
kuncar@57866
   116
  (bnf_only_type_ctr (fn bnf => map_local_theory (lifting_bnf_interpretation bnf)))))
kuncar@57866
   117
kuncar@57866
   118
end