author | huffman |
Tue, 17 Apr 2012 11:03:08 +0200 | |
changeset 47503 | cb44d09d9d22 |
parent 47356 | 19fb95255ec9 |
child 47523 | 1bf0e92c1ca0 |
permissions | -rw-r--r-- |
47325 | 1 |
(* Title: HOL/Tools/transfer.ML |
2 |
Author: Brian Huffman, TU Muenchen |
|
3 |
||
4 |
Generic theorem transfer method. |
|
5 |
*) |
|
6 |
||
7 |
signature TRANSFER = |
|
8 |
sig |
|
9 |
val fo_conv: Proof.context -> conv |
|
10 |
val prep_conv: conv |
|
47503 | 11 |
val get_relator_eq: Proof.context -> thm list |
47325 | 12 |
val transfer_add: attribute |
13 |
val transfer_del: attribute |
|
14 |
val transfer_tac: Proof.context -> int -> tactic |
|
15 |
val correspondence_tac: Proof.context -> int -> tactic |
|
16 |
val setup: theory -> theory |
|
17 |
end |
|
18 |
||
19 |
structure Transfer : TRANSFER = |
|
20 |
struct |
|
21 |
||
22 |
structure Data = Named_Thms |
|
23 |
( |
|
24 |
val name = @{binding transfer_raw} |
|
25 |
val description = "raw correspondence rule for transfer method" |
|
26 |
) |
|
27 |
||
47503 | 28 |
structure Relator_Eq = Named_Thms |
29 |
( |
|
30 |
val name = @{binding relator_eq} |
|
31 |
val description = "relator equality rule (used by transfer method)" |
|
32 |
) |
|
33 |
||
34 |
fun get_relator_eq ctxt = |
|
35 |
map (Thm.symmetric o mk_meta_eq) (Relator_Eq.get ctxt) |
|
36 |
||
47325 | 37 |
(** Conversions **) |
38 |
||
39 |
val App_rule = Thm.symmetric @{thm App_def} |
|
40 |
val Abs_rule = Thm.symmetric @{thm Abs_def} |
|
41 |
val Rel_rule = Thm.symmetric @{thm Rel_def} |
|
42 |
||
43 |
fun dest_funcT cT = |
|
44 |
(case Thm.dest_ctyp cT of [T, U] => (T, U) |
|
45 |
| _ => raise TYPE ("dest_funcT", [Thm.typ_of cT], [])) |
|
46 |
||
47 |
fun App_conv ct = |
|
48 |
let val (cT, cU) = dest_funcT (Thm.ctyp_of_term ct) |
|
49 |
in Drule.instantiate' [SOME cT, SOME cU] [SOME ct] App_rule end |
|
50 |
||
51 |
fun Abs_conv ct = |
|
52 |
let val (cT, cU) = dest_funcT (Thm.ctyp_of_term ct) |
|
53 |
in Drule.instantiate' [SOME cT, SOME cU] [SOME ct] Abs_rule end |
|
54 |
||
55 |
fun Rel_conv ct = |
|
56 |
let val (cT, cT') = dest_funcT (Thm.ctyp_of_term ct) |
|
57 |
val (cU, _) = dest_funcT cT' |
|
58 |
in Drule.instantiate' [SOME cT, SOME cU] [SOME ct] Rel_rule end |
|
59 |
||
60 |
fun Trueprop_conv cv ct = |
|
61 |
(case Thm.term_of ct of |
|
62 |
Const (@{const_name Trueprop}, _) $ _ => Conv.arg_conv cv ct |
|
63 |
| _ => raise CTERM ("Trueprop_conv", [ct])) |
|
64 |
||
65 |
(* Conversion to insert tags on every application and abstraction. *) |
|
66 |
fun fo_conv ctxt ct = ( |
|
67 |
Conv.combination_conv (fo_conv ctxt then_conv App_conv) (fo_conv ctxt) |
|
68 |
else_conv |
|
69 |
Conv.abs_conv (fo_conv o snd) ctxt then_conv Abs_conv |
|
70 |
else_conv |
|
71 |
Conv.all_conv) ct |
|
72 |
||
73 |
(* Conversion to preprocess a correspondence rule *) |
|
74 |
fun prep_conv ct = ( |
|
75 |
Conv.implies_conv Conv.all_conv prep_conv |
|
76 |
else_conv |
|
77 |
Trueprop_conv (Conv.fun_conv (Conv.fun_conv Rel_conv)) |
|
78 |
else_conv |
|
79 |
Conv.all_conv) ct |
|
80 |
||
81 |
(* Conversion to prep a proof goal containing a correspondence rule *) |
|
82 |
fun correspond_conv ctxt ct = ( |
|
83 |
Conv.forall_conv (correspond_conv o snd) ctxt |
|
84 |
else_conv |
|
85 |
Conv.implies_conv Conv.all_conv (correspond_conv ctxt) |
|
86 |
else_conv |
|
87 |
Trueprop_conv |
|
88 |
(Conv.combination_conv |
|
89 |
(Conv.combination_conv Rel_conv (fo_conv ctxt)) (fo_conv ctxt)) |
|
90 |
else_conv |
|
91 |
Conv.all_conv) ct |
|
92 |
||
93 |
||
94 |
(** Transfer proof method **) |
|
95 |
||
96 |
fun bnames (t $ u) = bnames t @ bnames u |
|
97 |
| bnames (Abs (x,_,t)) = x :: bnames t |
|
98 |
| bnames _ = [] |
|
99 |
||
100 |
fun rename [] t = (t, []) |
|
101 |
| rename (x::xs) ((c as Const (@{const_name Abs}, _)) $ Abs (_, T, t)) = |
|
102 |
let val (t', xs') = rename xs t |
|
103 |
in (c $ Abs (x, T, t'), xs') end |
|
104 |
| rename xs0 (t $ u) = |
|
105 |
let val (t', xs1) = rename xs0 t |
|
106 |
val (u', xs2) = rename xs1 u |
|
107 |
in (t' $ u', xs2) end |
|
108 |
| rename xs t = (t, xs) |
|
109 |
||
110 |
fun cert ctxt t = cterm_of (Proof_Context.theory_of ctxt) t |
|
111 |
||
112 |
fun RelT (Const (@{const_name Rel}, _) $ _ $ _ $ y) = fastype_of y |
|
113 |
||
114 |
(* Tactic to correspond a value to itself *) |
|
115 |
fun eq_tac ctxt = SUBGOAL (fn (t, i) => |
|
116 |
let |
|
117 |
val T = RelT (HOLogic.dest_Trueprop (Logic.strip_assums_concl t)) |
|
118 |
val cT = ctyp_of (Proof_Context.theory_of ctxt) T |
|
47503 | 119 |
val rews = get_relator_eq ctxt |
47325 | 120 |
val thm1 = Drule.instantiate' [SOME cT] [] @{thm Rel_eq_refl} |
121 |
val thm2 = Raw_Simplifier.rewrite_rule rews thm1 |
|
122 |
in |
|
123 |
rtac thm2 i |
|
124 |
end handle Match => no_tac | TERM _ => no_tac) |
|
125 |
||
47355
3d9d98e0f1a4
add bounded quantifier constant transfer_bforall, whose definition is unfolded after transfer
huffman
parents:
47327
diff
changeset
|
126 |
val post_simps = |
3d9d98e0f1a4
add bounded quantifier constant transfer_bforall, whose definition is unfolded after transfer
huffman
parents:
47327
diff
changeset
|
127 |
@{thms App_def Abs_def transfer_forall_eq [symmetric] |
3d9d98e0f1a4
add bounded quantifier constant transfer_bforall, whose definition is unfolded after transfer
huffman
parents:
47327
diff
changeset
|
128 |
transfer_implies_eq [symmetric] transfer_bforall_unfold} |
3d9d98e0f1a4
add bounded quantifier constant transfer_bforall, whose definition is unfolded after transfer
huffman
parents:
47327
diff
changeset
|
129 |
|
47356
19fb95255ec9
transfer method generalizes over free variables in goal
huffman
parents:
47355
diff
changeset
|
130 |
fun gen_frees_tac keepers ctxt = SUBGOAL (fn (t, i) => |
19fb95255ec9
transfer method generalizes over free variables in goal
huffman
parents:
47355
diff
changeset
|
131 |
let |
19fb95255ec9
transfer method generalizes over free variables in goal
huffman
parents:
47355
diff
changeset
|
132 |
val vs = rev (Term.add_frees t []) |
19fb95255ec9
transfer method generalizes over free variables in goal
huffman
parents:
47355
diff
changeset
|
133 |
val vs' = filter_out (member (op =) keepers o fst) vs |
19fb95255ec9
transfer method generalizes over free variables in goal
huffman
parents:
47355
diff
changeset
|
134 |
in |
19fb95255ec9
transfer method generalizes over free variables in goal
huffman
parents:
47355
diff
changeset
|
135 |
Induct.arbitrary_tac ctxt 0 vs' i |
19fb95255ec9
transfer method generalizes over free variables in goal
huffman
parents:
47355
diff
changeset
|
136 |
end) |
19fb95255ec9
transfer method generalizes over free variables in goal
huffman
parents:
47355
diff
changeset
|
137 |
|
47325 | 138 |
fun transfer_tac ctxt = SUBGOAL (fn (t, i) => |
139 |
let |
|
140 |
val bs = bnames t |
|
141 |
val rules = Data.get ctxt |
|
142 |
in |
|
143 |
EVERY |
|
144 |
[rewrite_goal_tac @{thms transfer_forall_eq transfer_implies_eq} i, |
|
145 |
CONVERSION (Trueprop_conv (fo_conv ctxt)) i, |
|
146 |
rtac @{thm transfer_start [rotated]} i, |
|
147 |
REPEAT_ALL_NEW (resolve_tac rules ORELSE' atac ORELSE' eq_tac ctxt) (i + 1), |
|
148 |
(* Alpha-rename bound variables in goal *) |
|
149 |
SUBGOAL (fn (u, i) => |
|
150 |
rtac @{thm equal_elim_rule1} i THEN |
|
151 |
rtac (Thm.reflexive (cert ctxt (fst (rename bs u)))) i) i, |
|
152 |
(* FIXME: rewrite_goal_tac does unwanted eta-contraction *) |
|
47355
3d9d98e0f1a4
add bounded quantifier constant transfer_bforall, whose definition is unfolded after transfer
huffman
parents:
47327
diff
changeset
|
153 |
rewrite_goal_tac post_simps i, |
47325 | 154 |
rtac @{thm _} i] |
155 |
end) |
|
156 |
||
157 |
fun correspondence_tac ctxt i = |
|
158 |
let |
|
159 |
val rules = Data.get ctxt |
|
160 |
in |
|
161 |
EVERY |
|
162 |
[CONVERSION (correspond_conv ctxt) i, |
|
163 |
REPEAT_ALL_NEW |
|
164 |
(resolve_tac rules ORELSE' atac ORELSE' eq_tac ctxt) i] |
|
165 |
end |
|
166 |
||
47327
600e6b07a693
add type annotations to make SML happy (cf. ec6187036495)
huffman
parents:
47325
diff
changeset
|
167 |
val transfer_method : (Proof.context -> Method.method) context_parser = |
47356
19fb95255ec9
transfer method generalizes over free variables in goal
huffman
parents:
47355
diff
changeset
|
168 |
Scan.succeed (fn ctxt => SIMPLE_METHOD' (gen_frees_tac [] ctxt THEN' transfer_tac ctxt)) |
47325 | 169 |
|
47327
600e6b07a693
add type annotations to make SML happy (cf. ec6187036495)
huffman
parents:
47325
diff
changeset
|
170 |
val correspondence_method : (Proof.context -> Method.method) context_parser = |
47325 | 171 |
Scan.succeed (fn ctxt => SIMPLE_METHOD' (correspondence_tac ctxt)) |
172 |
||
173 |
(* Attribute for correspondence rules *) |
|
174 |
||
175 |
val prep_rule = Conv.fconv_rule prep_conv |
|
176 |
||
177 |
val transfer_add = |
|
178 |
Thm.declaration_attribute (Data.add_thm o prep_rule) |
|
179 |
||
180 |
val transfer_del = |
|
181 |
Thm.declaration_attribute (Data.del_thm o prep_rule) |
|
182 |
||
183 |
val transfer_attribute = |
|
184 |
Attrib.add_del transfer_add transfer_del |
|
185 |
||
186 |
(* Theory setup *) |
|
187 |
||
188 |
val setup = |
|
189 |
Data.setup |
|
47503 | 190 |
#> Relator_Eq.setup |
47325 | 191 |
#> Attrib.setup @{binding transfer_rule} transfer_attribute |
192 |
"correspondence rule for transfer method" |
|
193 |
#> Method.setup @{binding transfer} transfer_method |
|
194 |
"generic theorem transfer method" |
|
195 |
#> Method.setup @{binding correspondence} correspondence_method |
|
196 |
"for proving correspondence rules" |
|
197 |
||
198 |
end |