10 val rule_by_tactic: Proof.context -> tactic -> thm -> thm |
10 val rule_by_tactic: Proof.context -> tactic -> thm -> thm |
11 val assume_tac: Proof.context -> int -> tactic |
11 val assume_tac: Proof.context -> int -> tactic |
12 val eq_assume_tac: int -> tactic |
12 val eq_assume_tac: int -> tactic |
13 val compose_tac: Proof.context -> (bool * thm * int) -> int -> tactic |
13 val compose_tac: Proof.context -> (bool * thm * int) -> int -> tactic |
14 val make_elim: thm -> thm |
14 val make_elim: thm -> thm |
15 val biresolve_tac: (bool * thm) list -> int -> tactic |
15 val biresolve0_tac: (bool * thm) list -> int -> tactic |
16 val resolve_tac: thm list -> int -> tactic |
16 val biresolve_tac: Proof.context -> (bool * thm) list -> int -> tactic |
17 val eresolve_tac: thm list -> int -> tactic |
17 val resolve0_tac: thm list -> int -> tactic |
18 val forward_tac: thm list -> int -> tactic |
18 val resolve_tac: Proof.context -> thm list -> int -> tactic |
19 val dresolve_tac: thm list -> int -> tactic |
19 val eresolve0_tac: thm list -> int -> tactic |
|
20 val eresolve_tac: Proof.context -> thm list -> int -> tactic |
|
21 val forward0_tac: thm list -> int -> tactic |
|
22 val forward_tac: Proof.context -> thm list -> int -> tactic |
|
23 val dresolve0_tac: thm list -> int -> tactic |
|
24 val dresolve_tac: Proof.context -> thm list -> int -> tactic |
20 val atac: int -> tactic |
25 val atac: int -> tactic |
21 val rtac: thm -> int -> tactic |
26 val rtac: thm -> int -> tactic |
22 val dtac: thm -> int -> tactic |
27 val dtac: thm -> int -> tactic |
23 val etac: thm -> int -> tactic |
28 val etac: thm -> int -> tactic |
24 val ftac: thm -> int -> tactic |
29 val ftac: thm -> int -> tactic |
25 val ares_tac: thm list -> int -> tactic |
30 val ares_tac: thm list -> int -> tactic |
26 val solve_tac: thm list -> int -> tactic |
31 val solve_tac: Proof.context -> thm list -> int -> tactic |
27 val bimatch_tac: Proof.context -> (bool * thm) list -> int -> tactic |
32 val bimatch_tac: Proof.context -> (bool * thm) list -> int -> tactic |
28 val match_tac: Proof.context -> thm list -> int -> tactic |
33 val match_tac: Proof.context -> thm list -> int -> tactic |
29 val ematch_tac: Proof.context -> thm list -> int -> tactic |
34 val ematch_tac: Proof.context -> thm list -> int -> tactic |
30 val dmatch_tac: Proof.context -> thm list -> int -> tactic |
35 val dmatch_tac: Proof.context -> thm list -> int -> tactic |
31 val flexflex_tac: Proof.context -> tactic |
36 val flexflex_tac: Proof.context -> tactic |
112 (*Converts a "destruct" rule like P&Q==>P to an "elimination" rule |
117 (*Converts a "destruct" rule like P&Q==>P to an "elimination" rule |
113 like [| P&Q; P==>R |] ==> R *) |
118 like [| P&Q; P==>R |] ==> R *) |
114 fun make_elim rl = zero_var_indexes (rl RS revcut_rl); |
119 fun make_elim rl = zero_var_indexes (rl RS revcut_rl); |
115 |
120 |
116 (*Attack subgoal i by resolution, using flags to indicate elimination rules*) |
121 (*Attack subgoal i by resolution, using flags to indicate elimination rules*) |
117 fun biresolve_tac brules i = PRIMSEQ (Thm.biresolution NONE false brules i); |
122 fun biresolve0_tac brules i = PRIMSEQ (Thm.biresolution NONE false brules i); |
|
123 fun biresolve_tac ctxt brules i = PRIMSEQ (Thm.biresolution (SOME ctxt) false brules i); |
118 |
124 |
119 (*Resolution: the simple case, works for introduction rules*) |
125 (*Resolution: the simple case, works for introduction rules*) |
120 fun resolve_tac rules = biresolve_tac (map (pair false) rules); |
126 fun resolve0_tac rules = biresolve0_tac (map (pair false) rules); |
|
127 fun resolve_tac ctxt rules = biresolve_tac ctxt (map (pair false) rules); |
121 |
128 |
122 (*Resolution with elimination rules only*) |
129 (*Resolution with elimination rules only*) |
123 fun eresolve_tac rules = biresolve_tac (map (pair true) rules); |
130 fun eresolve0_tac rules = biresolve0_tac (map (pair true) rules); |
|
131 fun eresolve_tac ctxt rules = biresolve_tac ctxt (map (pair true) rules); |
124 |
132 |
125 (*Forward reasoning using destruction rules.*) |
133 (*Forward reasoning using destruction rules.*) |
126 fun forward_tac rls = resolve_tac (map make_elim rls) THEN' atac; |
134 fun forward0_tac rls = resolve0_tac (map make_elim rls) THEN' atac; |
|
135 fun forward_tac ctxt rls = resolve_tac ctxt (map make_elim rls) THEN' atac; |
127 |
136 |
128 (*Like forward_tac, but deletes the assumption after use.*) |
137 (*Like forward_tac, but deletes the assumption after use.*) |
129 fun dresolve_tac rls = eresolve_tac (map make_elim rls); |
138 fun dresolve0_tac rls = eresolve0_tac (map make_elim rls); |
|
139 fun dresolve_tac ctxt rls = eresolve_tac ctxt (map make_elim rls); |
130 |
140 |
131 (*Shorthand versions: for resolution with a single theorem*) |
141 (*Shorthand versions: for resolution with a single theorem*) |
132 fun rtac rl = resolve_tac [rl]; |
142 fun rtac rl = resolve0_tac [rl]; |
133 fun dtac rl = dresolve_tac [rl]; |
143 fun dtac rl = dresolve0_tac [rl]; |
134 fun etac rl = eresolve_tac [rl]; |
144 fun etac rl = eresolve0_tac [rl]; |
135 fun ftac rl = forward_tac [rl]; |
145 fun ftac rl = forward0_tac [rl]; |
136 |
146 |
137 (*Use an assumption or some rules ... A popular combination!*) |
147 (*Use an assumption or some rules ... A popular combination!*) |
138 fun ares_tac rules = atac ORELSE' resolve_tac rules; |
148 fun ares_tac rules = atac ORELSE' resolve0_tac rules; |
139 |
149 |
140 fun solve_tac rules = resolve_tac rules THEN_ALL_NEW atac; |
150 fun solve_tac ctxt rules = resolve_tac ctxt rules THEN_ALL_NEW assume_tac ctxt; |
141 |
151 |
142 (*Matching tactics -- as above, but forbid updating of state*) |
152 (*Matching tactics -- as above, but forbid updating of state*) |
143 fun bimatch_tac ctxt brules i = PRIMSEQ (Thm.biresolution (SOME ctxt) true brules i); |
153 fun bimatch_tac ctxt brules i = PRIMSEQ (Thm.biresolution (SOME ctxt) true brules i); |
144 fun match_tac ctxt rules = bimatch_tac ctxt (map (pair false) rules); |
154 fun match_tac ctxt rules = bimatch_tac ctxt (map (pair false) rules); |
145 fun ematch_tac ctxt rules = bimatch_tac ctxt (map (pair true) rules); |
155 fun ematch_tac ctxt rules = bimatch_tac ctxt (map (pair true) rules); |
173 |
183 |
174 (*** Applications of cut_rl ***) |
184 (*** Applications of cut_rl ***) |
175 |
185 |
176 (*The conclusion of the rule gets assumed in subgoal i, |
186 (*The conclusion of the rule gets assumed in subgoal i, |
177 while subgoal i+1,... are the premises of the rule.*) |
187 while subgoal i+1,... are the premises of the rule.*) |
178 fun cut_tac rule i = resolve_tac [cut_rl] i THEN resolve_tac [rule] (i + 1); |
188 fun cut_tac rule i = resolve0_tac [cut_rl] i THEN resolve0_tac [rule] (i + 1); |
179 |
189 |
180 (*"Cut" a list of rules into the goal. Their premises will become new |
190 (*"Cut" a list of rules into the goal. Their premises will become new |
181 subgoals.*) |
191 subgoals.*) |
182 fun cut_rules_tac ths i = EVERY (map (fn th => cut_tac th i) ths); |
192 fun cut_rules_tac ths i = EVERY (map (fn th => cut_tac th i) ths); |
183 |
193 |
298 |
308 |
299 (*Rotates the given subgoal to be the first.*) |
309 (*Rotates the given subgoal to be the first.*) |
300 fun prefer_tac i = PRIMITIVE (Thm.permute_prems (i - 1) 1 #> Thm.permute_prems 0 ~1); |
310 fun prefer_tac i = PRIMITIVE (Thm.permute_prems (i - 1) 1 #> Thm.permute_prems 0 ~1); |
301 |
311 |
302 (* remove premises that do not satisfy p; fails if all prems satisfy p *) |
312 (* remove premises that do not satisfy p; fails if all prems satisfy p *) |
303 fun filter_prems_tac p = |
313 fun filter_prems_tac ctxt p = |
304 let fun Then NONE tac = SOME tac |
314 let fun Then NONE tac = SOME tac |
305 | Then (SOME tac) tac' = SOME(tac THEN' tac'); |
315 | Then (SOME tac) tac' = SOME(tac THEN' tac'); |
306 fun thins H (tac,n) = |
316 fun thins H (tac,n) = |
307 if p H then (tac,n+1) |
317 if p H then (tac,n+1) |
308 else (Then tac (rotate_tac n THEN' eresolve_tac [thin_rl]),0); |
318 else (Then tac (rotate_tac n THEN' eresolve_tac ctxt [thin_rl]),0); |
309 in SUBGOAL(fn (subg,n) => |
319 in SUBGOAL(fn (subg,n) => |
310 let val Hs = Logic.strip_assums_hyp subg |
320 let val Hs = Logic.strip_assums_hyp subg |
311 in case fst(fold thins Hs (NONE,0)) of |
321 in case fst(fold thins Hs (NONE,0)) of |
312 NONE => no_tac | SOME tac => tac n |
322 NONE => no_tac | SOME tac => tac n |
313 end) |
323 end) |