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
|