12 val of_rule: Proof.context -> string option list * string option list -> |
12 val of_rule: Proof.context -> string option list * string option list -> |
13 (binding * string option * mixfix) list -> thm -> thm |
13 (binding * string option * mixfix) list -> thm -> thm |
14 val read_instantiate: Proof.context -> |
14 val read_instantiate: Proof.context -> |
15 ((indexname * Position.T) * string) list -> string list -> thm -> thm |
15 ((indexname * Position.T) * string) list -> string list -> thm -> thm |
16 val res_inst_tac: Proof.context -> |
16 val res_inst_tac: Proof.context -> |
17 ((indexname * Position.T) * string) list -> thm -> int -> tactic |
17 ((indexname * Position.T) * string) list -> (binding * string option * mixfix) list -> thm -> |
|
18 int -> tactic |
18 val eres_inst_tac: Proof.context -> |
19 val eres_inst_tac: Proof.context -> |
19 ((indexname * Position.T) * string) list -> thm -> int -> tactic |
20 ((indexname * Position.T) * string) list -> (binding * string option * mixfix) list -> thm -> |
|
21 int -> tactic |
20 val cut_inst_tac: Proof.context -> |
22 val cut_inst_tac: Proof.context -> |
21 ((indexname * Position.T) * string) list -> thm -> int -> tactic |
23 ((indexname * Position.T) * string) list -> (binding * string option * mixfix) list -> thm -> |
|
24 int -> tactic |
22 val forw_inst_tac: Proof.context -> |
25 val forw_inst_tac: Proof.context -> |
23 ((indexname * Position.T) * string) list -> thm -> int -> tactic |
26 ((indexname * Position.T) * string) list -> (binding * string option * mixfix) list -> thm -> |
|
27 int -> tactic |
24 val dres_inst_tac: Proof.context -> |
28 val dres_inst_tac: Proof.context -> |
25 ((indexname * Position.T) * string) list -> thm -> int -> tactic |
29 ((indexname * Position.T) * string) list -> (binding * string option * mixfix) list -> thm -> |
26 val thin_tac: Proof.context -> string -> int -> tactic |
30 int -> tactic |
27 val subgoal_tac: Proof.context -> string -> int -> tactic |
31 val thin_tac: Proof.context -> string -> (binding * string option * mixfix) list -> |
|
32 int -> tactic |
|
33 val subgoal_tac: Proof.context -> string -> (binding * string option * mixfix) list -> |
|
34 int -> tactic |
28 val make_elim_preserve: Proof.context -> thm -> thm |
35 val make_elim_preserve: Proof.context -> thm -> thm |
29 val method: |
36 val method: |
30 (Proof.context -> ((indexname * Position.T) * string) list -> thm -> int -> tactic) -> |
37 (Proof.context -> ((indexname * Position.T) * string) list -> |
|
38 (binding * string option * mixfix) list -> thm -> int -> tactic) -> |
31 (Proof.context -> thm list -> int -> tactic) -> (Proof.context -> Proof.method) context_parser |
39 (Proof.context -> thm list -> int -> tactic) -> (Proof.context -> Proof.method) context_parser |
32 end; |
40 end; |
33 |
41 |
34 structure Rule_Insts: RULE_INSTS = |
42 structure Rule_Insts: RULE_INSTS = |
35 struct |
43 struct |
122 (** forward rules **) |
130 (** forward rules **) |
123 |
131 |
124 fun where_rule ctxt mixed_insts fixes thm = |
132 fun where_rule ctxt mixed_insts fixes thm = |
125 let |
133 let |
126 val ctxt' = ctxt |
134 val ctxt' = ctxt |
127 |> Proof_Context.read_vars fixes |-> Proof_Context.add_fixes |> #2 |
135 |> Variable.declare_thm thm |
128 |> Variable.declare_thm thm; |
136 |> Proof_Context.read_vars fixes |-> Proof_Context.add_fixes |> #2; |
129 val (inst_tvars, inst_vars) = read_insts ctxt' mixed_insts thm; |
137 val (inst_tvars, inst_vars) = read_insts ctxt' mixed_insts thm; |
130 in |
138 in |
131 thm |
139 thm |
132 |> Drule.instantiate_normalize |
140 |> Drule.instantiate_normalize |
133 (map (apply2 (Thm.ctyp_of ctxt) o apfst TVar) inst_tvars, |
141 (map (apply2 (Thm.ctyp_of ctxt) o apfst TVar) inst_tvars, |
134 map (apply2 (Thm.cterm_of ctxt) o apfst Var) inst_vars) |
142 map (apply2 (Thm.cterm_of ctxt) o apfst Var) inst_vars) |
135 |> singleton (Proof_Context.export ctxt' ctxt) |
143 |> singleton (Variable.export ctxt' ctxt) |
136 |> Rule_Cases.save thm |
144 |> Rule_Cases.save thm |
137 end; |
145 end; |
138 |
146 |
139 fun of_rule ctxt (args, concl_args) fixes thm = |
147 fun of_rule ctxt (args, concl_args) fixes thm = |
140 let |
148 let |
208 |> Proof_Context.add_fixes (map (fn (x, T) => (Binding.name x, SOME T, NoSyn)) params) |
216 |> Proof_Context.add_fixes (map (fn (x, T) => (Binding.name x, SOME T, NoSyn)) params) |
209 ||> Proof_Context.set_mode Proof_Context.mode_schematic; |
217 ||> Proof_Context.set_mode Proof_Context.mode_schematic; |
210 val paramTs = map #2 params; |
218 val paramTs = map #2 params; |
211 |
219 |
212 |
220 |
|
221 (* local fixes *) |
|
222 |
|
223 val fixes_ctxt = param_ctxt |
|
224 |> Proof_Context.read_vars fixes |-> Proof_Context.add_fixes |> #2; |
|
225 |
|
226 val (inst_tvars, inst_vars) = read_insts fixes_ctxt mixed_insts thm; |
|
227 |
|
228 |
213 (* lift and instantiate rule *) |
229 (* lift and instantiate rule *) |
214 |
|
215 val (inst_tvars, inst_vars) = read_insts param_ctxt mixed_insts thm; |
|
216 |
230 |
217 val inc = Thm.maxidx_of st + 1; |
231 val inc = Thm.maxidx_of st + 1; |
218 fun lift_var ((a, j), T) = |
232 fun lift_var ((a, j), T) = |
219 Var ((a, j + inc), paramTs ---> Logic.incr_tvar inc T); |
233 Var ((a, j + inc), paramTs ---> Logic.incr_tvar inc T); |
220 fun lift_term t = |
234 fun lift_term t = |
221 fold_rev Term.absfree (param_names ~~ paramTs) |
235 fold_rev Term.absfree (param_names ~~ paramTs) |
222 (Logic.incr_indexes (paramTs, inc) t); |
236 (Logic.incr_indexes (paramTs, inc) t); |
223 |
237 |
224 val inst_tvars' = inst_tvars |
238 val inst_tvars' = inst_tvars |
225 |> map (apply2 (Thm.ctyp_of param_ctxt o Logic.incr_tvar inc) o apfst TVar); |
239 |> map (apply2 (Thm.ctyp_of fixes_ctxt o Logic.incr_tvar inc) o apfst TVar); |
226 val inst_vars' = inst_vars |
240 val inst_vars' = inst_vars |
227 |> map (fn (v, t) => apply2 (Thm.cterm_of param_ctxt) (lift_var v, lift_term t)); |
241 |> map (fn (v, t) => apply2 (Thm.cterm_of fixes_ctxt) (lift_var v, lift_term t)); |
228 |
242 |
229 val thm' = |
243 val thm' = |
230 Drule.instantiate_normalize (inst_tvars', inst_vars') |
244 Drule.instantiate_normalize (inst_tvars', inst_vars') |
231 (Thm.lift_rule cgoal thm); |
245 (Thm.lift_rule cgoal thm) |
|
246 |> singleton (Variable.export fixes_ctxt param_ctxt); |
232 in |
247 in |
233 compose_tac param_ctxt (bires_flag, thm', Thm.nprems_of thm) i |
248 compose_tac param_ctxt (bires_flag, thm', Thm.nprems_of thm) i |
234 end) i st; |
249 end) i st; |
235 |
250 |
236 val res_inst_tac = bires_inst_tac false; |
251 val res_inst_tac = bires_inst_tac false; |
254 [th] => th |
269 [th] => th |
255 | _ => raise THM ("make_elim_preserve", 1, [rl])) |
270 | _ => raise THM ("make_elim_preserve", 1, [rl])) |
256 end; |
271 end; |
257 |
272 |
258 (*instantiate and cut -- for atomic fact*) |
273 (*instantiate and cut -- for atomic fact*) |
259 fun cut_inst_tac ctxt insts rule = res_inst_tac ctxt insts (make_elim_preserve ctxt rule); |
274 fun cut_inst_tac ctxt insts fixes rule = |
|
275 res_inst_tac ctxt insts fixes (make_elim_preserve ctxt rule); |
260 |
276 |
261 (*forward tactic applies a rule to an assumption without deleting it*) |
277 (*forward tactic applies a rule to an assumption without deleting it*) |
262 fun forw_inst_tac ctxt insts rule = cut_inst_tac ctxt insts rule THEN' assume_tac ctxt; |
278 fun forw_inst_tac ctxt insts fixes rule = |
|
279 cut_inst_tac ctxt insts fixes rule THEN' assume_tac ctxt; |
263 |
280 |
264 (*dresolve tactic applies a rule to replace an assumption*) |
281 (*dresolve tactic applies a rule to replace an assumption*) |
265 fun dres_inst_tac ctxt insts rule = eres_inst_tac ctxt insts (make_elim_preserve ctxt rule); |
282 fun dres_inst_tac ctxt insts fixes rule = |
|
283 eres_inst_tac ctxt insts fixes (make_elim_preserve ctxt rule); |
266 |
284 |
267 |
285 |
268 (* derived tactics *) |
286 (* derived tactics *) |
269 |
287 |
270 (*deletion of an assumption*) |
288 (*deletion of an assumption*) |
271 fun thin_tac ctxt s = |
289 fun thin_tac ctxt s fixes = |
272 eres_inst_tac ctxt [((("V", 0), Position.none), s)] Drule.thin_rl; |
290 eres_inst_tac ctxt [((("V", 0), Position.none), s)] fixes Drule.thin_rl; |
273 |
291 |
274 (*Introduce the given proposition as lemma and subgoal*) |
292 (*Introduce the given proposition as lemma and subgoal*) |
275 fun subgoal_tac ctxt A = |
293 fun subgoal_tac ctxt A fixes = |
276 DETERM o res_inst_tac ctxt [((("psi", 0), Position.none), A)] cut_rl; |
294 DETERM o res_inst_tac ctxt [((("psi", 0), Position.none), A)] fixes cut_rl; |
277 |
|
278 |
295 |
279 |
296 |
280 (* method wrapper *) |
297 (* method wrapper *) |
281 |
298 |
282 fun method inst_tac tac = |
299 fun method inst_tac tac = |
283 Args.goal_spec -- |
300 Args.goal_spec -- |
284 Scan.optional (Scan.lift |
301 Scan.optional (Scan.lift |
285 (Parse.and_list1 (Parse.position Args.var -- (Args.$$$ "=" |-- Parse.!!! Args.name_inner_syntax)) |
302 (Parse.and_list1 |
286 --| Args.$$$ "in")) [] -- |
303 (Parse.position Args.var -- (Args.$$$ "=" |-- Parse.!!! Args.name_inner_syntax)) -- |
|
304 Parse.for_fixes --| Args.$$$ "in")) ([], []) -- |
287 Attrib.thms >> |
305 Attrib.thms >> |
288 (fn ((quant, insts), thms) => fn ctxt => METHOD (fn facts => |
306 (fn ((quant, (insts, fixes)), thms) => fn ctxt => METHOD (fn facts => |
289 if null insts then quant (Method.insert_tac facts THEN' tac ctxt thms) |
307 if null insts andalso null fixes |
|
308 then quant (Method.insert_tac facts THEN' tac ctxt thms) |
290 else |
309 else |
291 (case thms of |
310 (case thms of |
292 [thm] => quant (Method.insert_tac facts THEN' inst_tac ctxt insts thm) |
311 [thm] => quant (Method.insert_tac facts THEN' inst_tac ctxt insts fixes thm) |
293 | _ => error "Cannot have instantiations with multiple rules"))); |
312 | _ => error "Cannot have instantiations with multiple rules"))); |
294 |
313 |
295 |
314 |
296 (* setup *) |
315 (* setup *) |
297 |
316 |
307 Method.setup @{binding frule_tac} (method forw_inst_tac forward_tac) |
326 Method.setup @{binding frule_tac} (method forw_inst_tac forward_tac) |
308 "apply rule in forward manner (dynamic instantiation)" #> |
327 "apply rule in forward manner (dynamic instantiation)" #> |
309 Method.setup @{binding cut_tac} (method cut_inst_tac (K cut_rules_tac)) |
328 Method.setup @{binding cut_tac} (method cut_inst_tac (K cut_rules_tac)) |
310 "cut rule (dynamic instantiation)" #> |
329 "cut rule (dynamic instantiation)" #> |
311 Method.setup @{binding subgoal_tac} |
330 Method.setup @{binding subgoal_tac} |
312 (Args.goal_spec -- Scan.lift (Scan.repeat1 Args.name_inner_syntax) >> |
331 (Args.goal_spec -- Scan.lift (Scan.repeat1 Args.name_inner_syntax -- Parse.for_fixes) >> |
313 (fn (quant, props) => fn ctxt => |
332 (fn (quant, (props, fixes)) => fn ctxt => |
314 SIMPLE_METHOD'' quant (EVERY' (map (subgoal_tac ctxt) props)))) |
333 SIMPLE_METHOD'' quant (EVERY' (map (fn prop => subgoal_tac ctxt prop fixes) props)))) |
315 "insert subgoal (dynamic instantiation)" #> |
334 "insert subgoal (dynamic instantiation)" #> |
316 Method.setup @{binding thin_tac} |
335 Method.setup @{binding thin_tac} |
317 (Args.goal_spec -- Scan.lift Args.name_inner_syntax >> |
336 (Args.goal_spec -- Scan.lift (Args.name_inner_syntax -- Parse.for_fixes) >> |
318 (fn (quant, prop) => fn ctxt => SIMPLE_METHOD'' quant (thin_tac ctxt prop))) |
337 (fn (quant, (prop, fixes)) => fn ctxt => SIMPLE_METHOD'' quant (thin_tac ctxt prop fixes))) |
319 "remove premise (dynamic instantiation)"); |
338 "remove premise (dynamic instantiation)"); |
320 |
339 |
321 end; |
340 end; |