author | huffman |
Sat, 21 Apr 2012 10:59:52 +0200 | |
changeset 47647 | ec29cc09599d |
parent 47635 | ebb79474262c |
child 47658 | 7631f6f7873d |
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 |
|
47635
ebb79474262c
rename 'correspondence' method to 'transfer_prover'
huffman
parents:
47618
diff
changeset
|
15 |
val transfer_prover_tac: Proof.context -> int -> tactic |
47325 | 16 |
val setup: theory -> theory |
47580
d99c883cdf2c
use simpler method for preserving bound variable names in transfer tactic
huffman
parents:
47568
diff
changeset
|
17 |
val abs_tac: int -> tactic |
47325 | 18 |
end |
19 |
||
20 |
structure Transfer : TRANSFER = |
|
21 |
struct |
|
22 |
||
23 |
structure Data = Named_Thms |
|
24 |
( |
|
25 |
val name = @{binding transfer_raw} |
|
47635
ebb79474262c
rename 'correspondence' method to 'transfer_prover'
huffman
parents:
47618
diff
changeset
|
26 |
val description = "raw transfer rule for transfer method" |
47325 | 27 |
) |
28 |
||
47503 | 29 |
structure Relator_Eq = Named_Thms |
30 |
( |
|
31 |
val name = @{binding relator_eq} |
|
32 |
val description = "relator equality rule (used by transfer method)" |
|
33 |
) |
|
34 |
||
35 |
fun get_relator_eq ctxt = |
|
36 |
map (Thm.symmetric o mk_meta_eq) (Relator_Eq.get ctxt) |
|
37 |
||
47325 | 38 |
(** Conversions **) |
39 |
||
40 |
val App_rule = Thm.symmetric @{thm App_def} |
|
41 |
val Abs_rule = Thm.symmetric @{thm Abs_def} |
|
42 |
val Rel_rule = Thm.symmetric @{thm Rel_def} |
|
43 |
||
44 |
fun dest_funcT cT = |
|
45 |
(case Thm.dest_ctyp cT of [T, U] => (T, U) |
|
46 |
| _ => raise TYPE ("dest_funcT", [Thm.typ_of cT], [])) |
|
47 |
||
48 |
fun App_conv ct = |
|
49 |
let val (cT, cU) = dest_funcT (Thm.ctyp_of_term ct) |
|
50 |
in Drule.instantiate' [SOME cT, SOME cU] [SOME ct] App_rule end |
|
51 |
||
52 |
fun Abs_conv ct = |
|
53 |
let val (cT, cU) = dest_funcT (Thm.ctyp_of_term ct) |
|
54 |
in Drule.instantiate' [SOME cT, SOME cU] [SOME ct] Abs_rule end |
|
55 |
||
56 |
fun Rel_conv ct = |
|
57 |
let val (cT, cT') = dest_funcT (Thm.ctyp_of_term ct) |
|
58 |
val (cU, _) = dest_funcT cT' |
|
59 |
in Drule.instantiate' [SOME cT, SOME cU] [SOME ct] Rel_rule end |
|
60 |
||
61 |
fun Trueprop_conv cv ct = |
|
62 |
(case Thm.term_of ct of |
|
63 |
Const (@{const_name Trueprop}, _) $ _ => Conv.arg_conv cv ct |
|
64 |
| _ => raise CTERM ("Trueprop_conv", [ct])) |
|
65 |
||
66 |
(* Conversion to insert tags on every application and abstraction. *) |
|
67 |
fun fo_conv ctxt ct = ( |
|
68 |
Conv.combination_conv (fo_conv ctxt then_conv App_conv) (fo_conv ctxt) |
|
69 |
else_conv |
|
70 |
Conv.abs_conv (fo_conv o snd) ctxt then_conv Abs_conv |
|
71 |
else_conv |
|
72 |
Conv.all_conv) ct |
|
73 |
||
47635
ebb79474262c
rename 'correspondence' method to 'transfer_prover'
huffman
parents:
47618
diff
changeset
|
74 |
(* Conversion to preprocess a transfer rule *) |
47325 | 75 |
fun prep_conv ct = ( |
76 |
Conv.implies_conv Conv.all_conv prep_conv |
|
77 |
else_conv |
|
78 |
Trueprop_conv (Conv.fun_conv (Conv.fun_conv Rel_conv)) |
|
79 |
else_conv |
|
80 |
Conv.all_conv) ct |
|
81 |
||
47635
ebb79474262c
rename 'correspondence' method to 'transfer_prover'
huffman
parents:
47618
diff
changeset
|
82 |
(* Conversion to prep a proof goal containing a transfer rule *) |
ebb79474262c
rename 'correspondence' method to 'transfer_prover'
huffman
parents:
47618
diff
changeset
|
83 |
fun transfer_goal_conv ctxt ct = ( |
ebb79474262c
rename 'correspondence' method to 'transfer_prover'
huffman
parents:
47618
diff
changeset
|
84 |
Conv.forall_conv (transfer_goal_conv o snd) ctxt |
47325 | 85 |
else_conv |
47635
ebb79474262c
rename 'correspondence' method to 'transfer_prover'
huffman
parents:
47618
diff
changeset
|
86 |
Conv.implies_conv Conv.all_conv (transfer_goal_conv ctxt) |
47325 | 87 |
else_conv |
88 |
Trueprop_conv |
|
47618
1568dadd598a
make correspondence tactic more robust by replacing lhs with schematic variable before applying intro rules
huffman
parents:
47580
diff
changeset
|
89 |
(Conv.combination_conv (Conv.fun_conv Rel_conv) (fo_conv ctxt)) |
47325 | 90 |
else_conv |
91 |
Conv.all_conv) ct |
|
92 |
||
93 |
||
94 |
(** Transfer proof method **) |
|
95 |
||
47580
d99c883cdf2c
use simpler method for preserving bound variable names in transfer tactic
huffman
parents:
47568
diff
changeset
|
96 |
fun dest_Rel (Const (@{const_name Rel}, _) $ r $ x $ y) = (r, x, y) |
d99c883cdf2c
use simpler method for preserving bound variable names in transfer tactic
huffman
parents:
47568
diff
changeset
|
97 |
| dest_Rel t = raise TERM ("dest_Rel", [t]) |
47325 | 98 |
|
99 |
fun RelT (Const (@{const_name Rel}, _) $ _ $ _ $ y) = fastype_of y |
|
100 |
||
101 |
(* Tactic to correspond a value to itself *) |
|
102 |
fun eq_tac ctxt = SUBGOAL (fn (t, i) => |
|
103 |
let |
|
104 |
val T = RelT (HOLogic.dest_Trueprop (Logic.strip_assums_concl t)) |
|
105 |
val cT = ctyp_of (Proof_Context.theory_of ctxt) T |
|
47503 | 106 |
val rews = get_relator_eq ctxt |
47325 | 107 |
val thm1 = Drule.instantiate' [SOME cT] [] @{thm Rel_eq_refl} |
108 |
val thm2 = Raw_Simplifier.rewrite_rule rews thm1 |
|
109 |
in |
|
110 |
rtac thm2 i |
|
111 |
end handle Match => no_tac | TERM _ => no_tac) |
|
112 |
||
47355
3d9d98e0f1a4
add bounded quantifier constant transfer_bforall, whose definition is unfolded after transfer
huffman
parents:
47327
diff
changeset
|
113 |
val post_simps = |
3d9d98e0f1a4
add bounded quantifier constant transfer_bforall, whose definition is unfolded after transfer
huffman
parents:
47327
diff
changeset
|
114 |
@{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
|
115 |
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
|
116 |
|
47356
19fb95255ec9
transfer method generalizes over free variables in goal
huffman
parents:
47355
diff
changeset
|
117 |
fun gen_frees_tac keepers ctxt = SUBGOAL (fn (t, i) => |
19fb95255ec9
transfer method generalizes over free variables in goal
huffman
parents:
47355
diff
changeset
|
118 |
let |
19fb95255ec9
transfer method generalizes over free variables in goal
huffman
parents:
47355
diff
changeset
|
119 |
val vs = rev (Term.add_frees t []) |
47568
98c8b7542b72
add option to transfer method for specifying variables not to generalize over
huffman
parents:
47523
diff
changeset
|
120 |
val vs' = filter_out (member (op =) keepers) vs |
47356
19fb95255ec9
transfer method generalizes over free variables in goal
huffman
parents:
47355
diff
changeset
|
121 |
in |
19fb95255ec9
transfer method generalizes over free variables in goal
huffman
parents:
47355
diff
changeset
|
122 |
Induct.arbitrary_tac ctxt 0 vs' i |
19fb95255ec9
transfer method generalizes over free variables in goal
huffman
parents:
47355
diff
changeset
|
123 |
end) |
19fb95255ec9
transfer method generalizes over free variables in goal
huffman
parents:
47355
diff
changeset
|
124 |
|
47580
d99c883cdf2c
use simpler method for preserving bound variable names in transfer tactic
huffman
parents:
47568
diff
changeset
|
125 |
(* Apply rule Rel_Abs with appropriate bound variable name *) |
d99c883cdf2c
use simpler method for preserving bound variable names in transfer tactic
huffman
parents:
47568
diff
changeset
|
126 |
val abs_tac = SUBGOAL (fn (t, i) => |
d99c883cdf2c
use simpler method for preserving bound variable names in transfer tactic
huffman
parents:
47568
diff
changeset
|
127 |
let |
d99c883cdf2c
use simpler method for preserving bound variable names in transfer tactic
huffman
parents:
47568
diff
changeset
|
128 |
val pat = (#2 o dest_Rel o HOLogic.dest_Trueprop o Thm.concl_of) @{thm Rel_Abs} |
d99c883cdf2c
use simpler method for preserving bound variable names in transfer tactic
huffman
parents:
47568
diff
changeset
|
129 |
val obj = (#3 o dest_Rel o HOLogic.dest_Trueprop o Logic.strip_assums_concl) t |
d99c883cdf2c
use simpler method for preserving bound variable names in transfer tactic
huffman
parents:
47568
diff
changeset
|
130 |
val rule = Thm.rename_boundvars pat obj @{thm Rel_Abs} |
d99c883cdf2c
use simpler method for preserving bound variable names in transfer tactic
huffman
parents:
47568
diff
changeset
|
131 |
in |
d99c883cdf2c
use simpler method for preserving bound variable names in transfer tactic
huffman
parents:
47568
diff
changeset
|
132 |
rtac rule i |
d99c883cdf2c
use simpler method for preserving bound variable names in transfer tactic
huffman
parents:
47568
diff
changeset
|
133 |
end handle TERM _ => no_tac) |
d99c883cdf2c
use simpler method for preserving bound variable names in transfer tactic
huffman
parents:
47568
diff
changeset
|
134 |
|
47325 | 135 |
fun transfer_tac ctxt = SUBGOAL (fn (t, i) => |
136 |
let |
|
137 |
val rules = Data.get ctxt |
|
47580
d99c883cdf2c
use simpler method for preserving bound variable names in transfer tactic
huffman
parents:
47568
diff
changeset
|
138 |
val app_tac = rtac @{thm Rel_App} |
47325 | 139 |
in |
140 |
EVERY |
|
141 |
[rewrite_goal_tac @{thms transfer_forall_eq transfer_implies_eq} i, |
|
142 |
CONVERSION (Trueprop_conv (fo_conv ctxt)) i, |
|
143 |
rtac @{thm transfer_start [rotated]} i, |
|
47580
d99c883cdf2c
use simpler method for preserving bound variable names in transfer tactic
huffman
parents:
47568
diff
changeset
|
144 |
REPEAT_ALL_NEW (app_tac ORELSE' abs_tac ORELSE' atac |
47523
1bf0e92c1ca0
make transfer method more deterministic by using SOLVED' on some subgoals
huffman
parents:
47503
diff
changeset
|
145 |
ORELSE' SOLVED' (REPEAT_ALL_NEW (resolve_tac rules)) |
1bf0e92c1ca0
make transfer method more deterministic by using SOLVED' on some subgoals
huffman
parents:
47503
diff
changeset
|
146 |
ORELSE' eq_tac ctxt) (i + 1), |
47325 | 147 |
(* 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
|
148 |
rewrite_goal_tac post_simps i, |
47325 | 149 |
rtac @{thm _} i] |
150 |
end) |
|
151 |
||
47635
ebb79474262c
rename 'correspondence' method to 'transfer_prover'
huffman
parents:
47618
diff
changeset
|
152 |
fun transfer_prover_tac ctxt i = |
47325 | 153 |
let |
47523
1bf0e92c1ca0
make transfer method more deterministic by using SOLVED' on some subgoals
huffman
parents:
47503
diff
changeset
|
154 |
val rules = @{thms Rel_App Rel_Abs} @ Data.get ctxt |
47325 | 155 |
in |
156 |
EVERY |
|
47635
ebb79474262c
rename 'correspondence' method to 'transfer_prover'
huffman
parents:
47618
diff
changeset
|
157 |
[CONVERSION (transfer_goal_conv ctxt) i, |
ebb79474262c
rename 'correspondence' method to 'transfer_prover'
huffman
parents:
47618
diff
changeset
|
158 |
rtac @{thm transfer_prover_start} i, |
47325 | 159 |
REPEAT_ALL_NEW |
47618
1568dadd598a
make correspondence tactic more robust by replacing lhs with schematic variable before applying intro rules
huffman
parents:
47580
diff
changeset
|
160 |
(resolve_tac rules ORELSE' atac ORELSE' eq_tac ctxt) (i+1), |
1568dadd598a
make correspondence tactic more robust by replacing lhs with schematic variable before applying intro rules
huffman
parents:
47580
diff
changeset
|
161 |
rewrite_goal_tac @{thms App_def Abs_def} i, |
1568dadd598a
make correspondence tactic more robust by replacing lhs with schematic variable before applying intro rules
huffman
parents:
47580
diff
changeset
|
162 |
rtac @{thm refl} i] |
47325 | 163 |
end |
164 |
||
47568
98c8b7542b72
add option to transfer method for specifying variables not to generalize over
huffman
parents:
47523
diff
changeset
|
165 |
val free = Args.context -- Args.term >> (fn (_, Free v) => v | (ctxt, t) => |
98c8b7542b72
add option to transfer method for specifying variables not to generalize over
huffman
parents:
47523
diff
changeset
|
166 |
error ("Bad free variable: " ^ Syntax.string_of_term ctxt t)) |
98c8b7542b72
add option to transfer method for specifying variables not to generalize over
huffman
parents:
47523
diff
changeset
|
167 |
|
98c8b7542b72
add option to transfer method for specifying variables not to generalize over
huffman
parents:
47523
diff
changeset
|
168 |
val fixing = Scan.optional (Scan.lift (Args.$$$ "fixing" -- Args.colon) |
98c8b7542b72
add option to transfer method for specifying variables not to generalize over
huffman
parents:
47523
diff
changeset
|
169 |
|-- Scan.repeat free) [] |
98c8b7542b72
add option to transfer method for specifying variables not to generalize over
huffman
parents:
47523
diff
changeset
|
170 |
|
47327
600e6b07a693
add type annotations to make SML happy (cf. ec6187036495)
huffman
parents:
47325
diff
changeset
|
171 |
val transfer_method : (Proof.context -> Method.method) context_parser = |
47568
98c8b7542b72
add option to transfer method for specifying variables not to generalize over
huffman
parents:
47523
diff
changeset
|
172 |
fixing >> (fn vs => fn ctxt => |
98c8b7542b72
add option to transfer method for specifying variables not to generalize over
huffman
parents:
47523
diff
changeset
|
173 |
SIMPLE_METHOD' (gen_frees_tac vs ctxt THEN' transfer_tac ctxt)) |
47325 | 174 |
|
47635
ebb79474262c
rename 'correspondence' method to 'transfer_prover'
huffman
parents:
47618
diff
changeset
|
175 |
val transfer_prover_method : (Proof.context -> Method.method) context_parser = |
ebb79474262c
rename 'correspondence' method to 'transfer_prover'
huffman
parents:
47618
diff
changeset
|
176 |
Scan.succeed (fn ctxt => SIMPLE_METHOD' (transfer_prover_tac ctxt)) |
47325 | 177 |
|
47635
ebb79474262c
rename 'correspondence' method to 'transfer_prover'
huffman
parents:
47618
diff
changeset
|
178 |
(* Attribute for transfer rules *) |
47325 | 179 |
|
180 |
val prep_rule = Conv.fconv_rule prep_conv |
|
181 |
||
182 |
val transfer_add = |
|
183 |
Thm.declaration_attribute (Data.add_thm o prep_rule) |
|
184 |
||
185 |
val transfer_del = |
|
186 |
Thm.declaration_attribute (Data.del_thm o prep_rule) |
|
187 |
||
188 |
val transfer_attribute = |
|
189 |
Attrib.add_del transfer_add transfer_del |
|
190 |
||
191 |
(* Theory setup *) |
|
192 |
||
193 |
val setup = |
|
194 |
Data.setup |
|
47503 | 195 |
#> Relator_Eq.setup |
47325 | 196 |
#> Attrib.setup @{binding transfer_rule} transfer_attribute |
47635
ebb79474262c
rename 'correspondence' method to 'transfer_prover'
huffman
parents:
47618
diff
changeset
|
197 |
"transfer rule for transfer method" |
47325 | 198 |
#> Method.setup @{binding transfer} transfer_method |
199 |
"generic theorem transfer method" |
|
47635
ebb79474262c
rename 'correspondence' method to 'transfer_prover'
huffman
parents:
47618
diff
changeset
|
200 |
#> Method.setup @{binding transfer_prover} transfer_prover_method |
ebb79474262c
rename 'correspondence' method to 'transfer_prover'
huffman
parents:
47618
diff
changeset
|
201 |
"for proving transfer rules" |
47325 | 202 |
|
203 |
end |