17 val localize: thm list |
17 val localize: thm list |
18 end; |
18 end; |
19 |
19 |
20 signature INDUCT_METHOD = |
20 signature INDUCT_METHOD = |
21 sig |
21 sig |
|
22 val fix_tac: Proof.context -> int -> (string * typ) list -> int -> tactic |
|
23 val atomize_term: theory -> term -> term |
|
24 val atomize_tac: int -> tactic |
|
25 val rulified_term: thm -> theory * term |
|
26 val rulify_tac: int -> tactic |
22 val cases_tac: Proof.context -> bool -> term option list list -> thm option -> |
27 val cases_tac: Proof.context -> bool -> term option list list -> thm option -> |
23 thm list -> int -> cases_tactic |
28 thm list -> int -> cases_tactic |
24 val fix_tac: Proof.context -> (string * typ) list -> int -> tactic |
|
25 val induct_tac: Proof.context -> bool -> (string option * term) option list list -> |
29 val induct_tac: Proof.context -> bool -> (string option * term) option list list -> |
26 (string * typ) list list -> term option list -> thm option -> thm list -> int -> cases_tactic |
30 (string * typ) list list -> term option list -> thm option -> thm list -> int -> cases_tactic |
27 val coinduct_tac: Proof.context -> bool -> term option list -> term option list -> |
31 val coinduct_tac: Proof.context -> bool -> term option list -> term option list -> |
28 thm option -> thm list -> int -> cases_tactic |
32 thm option -> thm list -> int -> cases_tactic |
29 val setup: (theory -> theory) list |
33 val setup: (theory -> theory) list |
143 |
147 |
144 (** induct method **) |
148 (** induct method **) |
145 |
149 |
146 (* fix_tac *) |
150 (* fix_tac *) |
147 |
151 |
148 fun revert_skolem ctxt x = |
152 local |
149 (case ProofContext.revert_skolem ctxt x of |
153 |
150 SOME x' => x' |
154 fun goal_prefix k ((c as Const ("all", _)) $ Abs (a, T, B)) = c $ Abs (a, T, goal_prefix k B) |
151 | NONE => Syntax.deskolem x); |
155 | goal_prefix 0 _ = Term.dummy_pattern propT |
152 |
156 | goal_prefix k ((c as Const ("==>", _)) $ A $ B) = c $ A $ goal_prefix (k - 1) B |
153 local |
157 | goal_prefix _ _ = Term.dummy_pattern propT; |
|
158 |
|
159 fun goal_params k (Const ("all", _) $ Abs (_, _, B)) = goal_params k B + 1 |
|
160 | goal_params 0 _ = 0 |
|
161 | goal_params k (Const ("==>", _) $ _ $ B) = goal_params (k - 1) B |
|
162 | goal_params _ _ = 0; |
154 |
163 |
155 val meta_spec = PureThy.get_thm Pure.thy (Name "meta_spec"); |
164 val meta_spec = PureThy.get_thm Pure.thy (Name "meta_spec"); |
156 |
165 |
157 fun meta_spec_tac ctxt (x, T) = SUBGOAL (fn (goal, i) => fn st => |
166 fun meta_spec_tac ctxt n (x, T) = SUBGOAL (fn (goal, i) => |
158 let |
167 let |
159 val thy = Thm.theory_of_thm st; |
168 val thy = ProofContext.theory_of ctxt; |
160 val cert = Thm.cterm_of thy; |
169 val cert = Thm.cterm_of thy; |
161 val certT = Thm.ctyp_of thy; |
170 val certT = Thm.ctyp_of thy; |
162 |
171 |
163 val v = Free (x, T); |
172 val v = Free (x, T); |
|
173 fun spec_rule prfx (xs, body) = |
|
174 meta_spec |
|
175 |> Thm.rename_params_rule ([ProofContext.revert_skolem ctxt x], 1) |
|
176 |> Thm.lift_rule (cert prfx) |
|
177 |> `(Thm.prop_of #> Logic.strip_assums_concl) |
|
178 |-> (fn pred $ arg => |
|
179 Drule.cterm_instantiate |
|
180 [(cert (Term.head_of pred), cert (Unify.rlist_abs (xs, body))), |
|
181 (cert (Term.head_of arg), cert (Unify.rlist_abs (xs, v)))]); |
|
182 |
|
183 fun goal_concl k xs (Const ("all", _) $ Abs (a, T, B)) = goal_concl k ((a, T) :: xs) B |
|
184 | goal_concl 0 xs B = |
|
185 if not (Term.exists_subterm (fn t => t aconv v) B) then NONE |
|
186 else SOME (xs, Term.absfree (x, T, Term.incr_boundvars 1 B)) |
|
187 | goal_concl k xs (Const ("==>", _) $ _ $ B) = goal_concl (k - 1) xs B |
|
188 | goal_concl _ _ _ = NONE; |
164 in |
189 in |
165 if Term.exists_subterm (fn t => t aconv v) goal then |
190 (case goal_concl n [] goal of |
166 let |
191 SOME concl => |
167 val P = Term.absfree (x, T, goal); |
192 (compose_tac (false, spec_rule (goal_prefix n goal) concl, 1) THEN' rtac asm_rl) i |
168 val rule = meta_spec |
193 | NONE => (warning ("induct: no variable " ^ ProofContext.string_of_term ctxt v ^ |
169 |> Drule.instantiate' [SOME (certT T)] [SOME (cert P), SOME (cert v)] |
194 " to be fixed -- ignored"); all_tac)) |
170 |> Thm.rename_params_rule ([revert_skolem ctxt x], 1); |
195 end); |
171 in compose_tac (false, rule, 1) i end |
196 |
172 else all_tac |
197 fun miniscope_tac n i = PRIMITIVE (Drule.fconv_rule |
173 end st); |
198 (Drule.goals_conv (Library.equal i) |
174 |
199 (Drule.forall_conv n (Tactic.rewrite true [Thm.symmetric Drule.norm_hhf_eq])))); |
175 in |
200 |
176 |
201 in |
177 fun fix_tac ctxt xs = EVERY' (map (meta_spec_tac ctxt) (rev (gen_distinct (op =) xs))); |
202 |
|
203 fun fix_tac _ _ [] = K all_tac |
|
204 | fix_tac ctxt n xs = SUBGOAL (fn (goal, i) => |
|
205 (EVERY' (map (meta_spec_tac ctxt n) xs) THEN' |
|
206 (miniscope_tac (goal_params n goal))) i); |
178 |
207 |
179 end; |
208 end; |
180 |
209 |
181 |
210 |
182 (* add_defs *) |
211 (* add_defs *) |
192 |
221 |
193 |
222 |
194 (* atomize and rulify *) |
223 (* atomize and rulify *) |
195 |
224 |
196 fun atomize_term thy = |
225 fun atomize_term thy = |
197 ObjectLogic.drop_judgment thy o MetaSimplifier.rewrite_term thy Data.atomize []; |
226 MetaSimplifier.rewrite_term thy Data.atomize [] |
|
227 #> ObjectLogic.drop_judgment thy; |
|
228 |
|
229 val atomize_tac = |
|
230 Tactic.rewrite_goal_tac Data.atomize; |
198 |
231 |
199 fun rulified_term thm = |
232 fun rulified_term thm = |
200 let val thy = Thm.theory_of_thm thm in |
233 let val thy = Thm.theory_of_thm thm in |
201 Thm.prop_of thm |
234 Thm.prop_of thm |
202 |> MetaSimplifier.rewrite_term thy Data.rulify1 [] |
235 |> MetaSimplifier.rewrite_term thy Data.rulify1 [] |
203 |> MetaSimplifier.rewrite_term thy Data.rulify2 [] |
236 |> MetaSimplifier.rewrite_term thy Data.rulify2 [] |
204 |> pair thy |
237 |> pair thy |
205 end; |
238 end; |
206 |
239 |
207 val atomize_tac = Tactic.rewrite_goal_tac Data.atomize; |
|
208 |
|
209 val rulify_tac = |
240 val rulify_tac = |
210 Tactic.rewrite_goal_tac Data.rulify1 THEN' |
241 Tactic.rewrite_goal_tac Data.rulify1 THEN' |
211 Tactic.rewrite_goal_tac Data.rulify2 THEN' |
242 Tactic.rewrite_goal_tac Data.rulify2 THEN' |
212 Tactic.norm_hhf_tac; |
243 Tactic.norm_hhf_tac; |
213 |
244 |
216 |
247 |
217 local |
248 local |
218 |
249 |
219 fun imp_intr i raw_th = |
250 fun imp_intr i raw_th = |
220 let |
251 let |
|
252 val cert = Thm.cterm_of (Thm.theory_of_thm raw_th); |
221 val th = Thm.permute_prems (i - 1) 1 raw_th; |
253 val th = Thm.permute_prems (i - 1) 1 raw_th; |
222 val {thy, maxidx, ...} = Thm.rep_thm th; |
254 val prems = Thm.prems_of th; |
223 val cprems = Drule.cprems_of th; |
255 val As = Library.take (length prems - 1, prems); |
224 val As = Library.take (length cprems - 1, cprems); |
256 val C = Term.dummy_pattern propT; |
225 val C = Thm.cterm_of thy (Var (("C", maxidx + 1), propT)); |
257 in th COMP Thm.lift_rule (cert (Logic.list_implies (As, C))) Data.local_impI end; |
226 in th COMP Thm.lift_rule (Drule.list_implies (As, C)) Data.local_impI end; |
|
227 |
258 |
228 in |
259 in |
229 |
260 |
230 fun internalize k th = if k > 0 then internalize (k - 1) (imp_intr k th) else th; |
261 fun internalize k th = if k > 0 then internalize (k - 1) (imp_intr k th) else th; |
231 |
262 |
297 |
328 |
298 (* special renaming of rule parameters *) |
329 (* special renaming of rule parameters *) |
299 |
330 |
300 fun special_rename_params ctxt [[SOME (Free (z, Type (T, _)))]] thm = |
331 fun special_rename_params ctxt [[SOME (Free (z, Type (T, _)))]] thm = |
301 let |
332 let |
302 val x = revert_skolem ctxt z; |
333 val x = ProofContext.revert_skolem ctxt z; |
303 fun index i [] = [] |
334 fun index i [] = [] |
304 | index i (y :: ys) = |
335 | index i (y :: ys) = |
305 if x = y then x ^ string_of_int i :: index (i + 1) ys |
336 if x = y then x ^ string_of_int i :: index (i + 1) ys |
306 else y :: index i ys; |
337 else y :: index i ys; |
307 fun rename_params [] = [] |
338 fun rename_params [] = [] |
387 ruleq |
418 ruleq |
388 |> Seq.maps (RuleCases.consume (List.concat defs) facts) |
419 |> Seq.maps (RuleCases.consume (List.concat defs) facts) |
389 |> Seq.maps (fn ((cases, (k, more_facts)), rule) => |
420 |> Seq.maps (fn ((cases, (k, more_facts)), rule) => |
390 (CONJUNCTS (ALLGOALS (fn j => |
421 (CONJUNCTS (ALLGOALS (fn j => |
391 Method.insert_tac (more_facts @ nth_list defs (j - 1)) j |
422 Method.insert_tac (more_facts @ nth_list defs (j - 1)) j |
392 THEN fix_tac defs_ctxt (nth_list fixing (j - 1)) j)) |
423 THEN fix_tac defs_ctxt k (nth_list fixing (j - 1)) j)) |
393 THEN' atomize_tac) i st |> Seq.maps (fn st' => |
424 THEN' atomize_tac) i st |> Seq.maps (fn st' => |
394 divinate_inst (internalize k rule) i st' |
425 divinate_inst (internalize k rule) i st' |
395 |> Seq.map (rule_instance thy taking) |
426 |> Seq.map (rule_instance thy taking) |
396 |> Seq.maps (fn rule' => |
427 |> Seq.maps (fn rule' => |
397 CASES (rule_cases rule' cases) |
428 CASES (rule_cases rule' cases) |