38 | real_head_of (Const ("HOL.induct_forall", _) $ Abs (_, _, t)) = real_head_of t |
38 | real_head_of (Const ("HOL.induct_forall", _) $ Abs (_, _, t)) = real_head_of t |
39 | real_head_of t = head_of t |
39 | real_head_of t = head_of t |
40 *} |
40 *} |
41 |
41 |
42 ML {* |
42 ML {* |
43 fun mk_vc_compat (avoid, avoid_trm) prems concl_args params = |
43 fun mk_vc_compat (avoid, avoid_trm) prems concl_args params = |
44 let |
44 let |
45 fun aux arg = arg |
45 val vc_goal = concl_args |
|
46 |> HOLogic.mk_tuple |
46 |> mk_fresh_star avoid_trm |
47 |> mk_fresh_star avoid_trm |
47 |> HOLogic.mk_Trueprop |
48 |> HOLogic.mk_Trueprop |
48 |> (curry Logic.list_implies) prems |
49 |> (curry Logic.list_implies) prems |
49 |> (curry list_all_free) params |
50 |> (curry list_all_free) params |
50 in |
51 in |
51 if null avoid then [] else map aux concl_args |
52 if null avoid then [] else [vc_goal] |
52 end |
53 end |
53 *} |
54 *} |
54 |
55 |
55 ML {* |
56 ML {* |
56 fun map_term prop f trm = |
57 fun map_term prop f trm = |
190 in |
191 in |
191 EVERY1 [rtac prem', RANGE (map (SUBGOAL o select) prems) ] |
192 EVERY1 [rtac prem', RANGE (map (SUBGOAL o select) prems) ] |
192 end) ctxt |
193 end) ctxt |
193 *} |
194 *} |
194 |
195 |
195 ML {* |
196 |
196 fun binder_tac prem intr_cvars Ps fresh_thms avoid avoid_trms ctxt = |
197 ML {* |
|
198 fun fresh_thm ctxt fresh_thms p c prms avoid_trm = |
|
199 let |
|
200 val conj1 = |
|
201 mk_fresh_star (mk_perm (Bound 0) (mk_perm p avoid_trm)) c |
|
202 val conj2 = |
|
203 mk_fresh_star_ty @{typ perm} (mk_supp (HOLogic.mk_tuple (map (mk_perm p) prms))) (Bound 0) |
|
204 val fresh_goal = mk_exists ("q", @{typ perm}) (HOLogic.mk_conj (conj1, conj2)) |
|
205 |> HOLogic.mk_Trueprop |
|
206 |
|
207 val _ = tracing ("fresh goal: " ^ Syntax.string_of_term ctxt fresh_goal) |
|
208 in |
|
209 Goal.prove ctxt [] [] fresh_goal |
|
210 (K (HEADGOAL (rtac @{thm at_set_avoiding2}))) |
|
211 end |
|
212 *} |
|
213 |
|
214 ML {* |
|
215 fun binder_tac prem intr_cvars param_trms Ps fresh_thms avoid avoid_trm ctxt = |
197 Subgoal.FOCUS (fn {context, params, ...} => |
216 Subgoal.FOCUS (fn {context, params, ...} => |
198 let |
217 let |
199 val thy = ProofContext.theory_of context |
218 val thy = ProofContext.theory_of context |
200 val (prms, p, _) = split_last2 (map snd params) |
219 val (prms, p, c) = split_last2 (map snd params) |
201 val prm_tys = map (fastype_of o term_of) prms |
220 val prm_trms = map term_of prms |
|
221 val prm_tys = map fastype_of prm_trms |
202 val cperms = map (cterm_of thy o perm_const) prm_tys |
222 val cperms = map (cterm_of thy o perm_const) prm_tys |
203 val p_prms = map2 (fn ct1 => fn ct2 => Thm.mk_binop ct1 p ct2) cperms prms |
223 val p_prms = map2 (fn ct1 => fn ct2 => Thm.mk_binop ct1 p ct2) cperms prms |
204 val prem' = cterm_instantiate (intr_cvars ~~ p_prms) prem |
224 val prem' = cterm_instantiate (intr_cvars ~~ p_prms) prem |
|
225 val avoid_trm' = subst_free (param_trms ~~ prm_trms) avoid_trm |
|
226 |
|
227 val fthm = fresh_thm context fresh_thms (term_of p) (term_of c) (map term_of prms) avoid_trm' |
205 in |
228 in |
206 Skip_Proof.cheat_tac thy |
229 Skip_Proof.cheat_tac thy |
207 (* EVERY1 [rtac prem'] *) |
230 (* EVERY1 [rtac prem'] *) |
208 end) ctxt |
231 end) ctxt |
209 *} |
232 *} |
210 |
233 |
211 ML {* |
234 ML {* |
212 fun case_tac ctxt fresh_thms Ps avoid avoid_trm intr_cvars prem = |
235 fun case_tac ctxt fresh_thms Ps (avoid, avoid_trm) intr_cvars param_trms prem = |
213 let |
236 let |
214 val tac1 = non_binder_tac prem intr_cvars Ps ctxt |
237 val tac1 = non_binder_tac prem intr_cvars Ps ctxt |
215 val tac2 = binder_tac prem intr_cvars Ps fresh_thms avoid avoid_trm ctxt |
238 val tac2 = binder_tac prem intr_cvars param_trms Ps fresh_thms avoid avoid_trm ctxt |
216 in |
239 in |
217 EVERY' [ rtac @{thm allI}, rtac @{thm allI}, eqvt_stac ctxt, |
240 EVERY' [ rtac @{thm allI}, rtac @{thm allI}, eqvt_stac ctxt, |
218 if null avoid then tac1 else tac2 ] |
241 if null avoid then tac1 else tac2 ] |
219 end |
242 end |
220 *} |
243 *} |
221 |
244 |
222 ML {* |
245 ML {* |
223 fun tac raw_induct fresh_thms Ps avoids avoid_trms intr_cvars {prems, context} = |
246 fun prove_sinduct_tac raw_induct fresh_thms Ps avoids avoid_trms intr_cvars param_trms {prems, context} = |
224 let |
247 let |
225 val cases_tac = map4 (case_tac context fresh_thms Ps) avoids avoid_trms intr_cvars prems |
248 val cases_tac = map4 (case_tac context fresh_thms Ps) (avoids ~~avoid_trms) intr_cvars param_trms prems |
226 in |
249 in |
227 EVERY1 [ DETERM o rtac raw_induct, RANGE cases_tac ] |
250 EVERY1 [ DETERM o rtac raw_induct, RANGE cases_tac ] |
228 end |
251 end |
229 *} |
252 *} |
230 |
253 |
231 ML {* |
254 ML {* |
232 val normalise = @{lemma "(Q --> (!p c. P p c)) ==> (\<And>c. Q ==> P (0::perm) c)" by simp} |
255 val normalise = @{lemma "(Q --> (!p c. P p c)) ==> (!!c. Q ==> P (0::perm) c)" by simp} |
233 *} |
256 *} |
234 |
257 |
235 ML {* |
258 ML {* |
236 fun prove_strong_inductive rule_names avoids raw_induct intrs ctxt = |
259 fun prove_strong_inductive rule_names avoids raw_induct intrs ctxt = |
237 let |
260 let |
246 val param_trms = (map o map) Free params |
269 val param_trms = (map o map) Free params |
247 |
270 |
248 val intr_vars_tys = map (fn t => rev (Term.add_vars (prop_of t) [])) intrs |
271 val intr_vars_tys = map (fn t => rev (Term.add_vars (prop_of t) [])) intrs |
249 val intr_vars = (map o map) fst intr_vars_tys |
272 val intr_vars = (map o map) fst intr_vars_tys |
250 val intr_vars_substs = map2 (curry (op ~~)) intr_vars param_trms |
273 val intr_vars_substs = map2 (curry (op ~~)) intr_vars param_trms |
251 val intr_cvars = (map o map) (cterm_of thy o Var) intr_vars_tys |
274 val intr_cvars = (map o map) (cterm_of thy o Var) intr_vars_tys |
252 |
275 |
253 val (intr_prems, intr_concls) = intrs |
276 val (intr_prems, intr_concls) = intrs |
254 |> map prop_of |
277 |> map prop_of |
255 |> map2 subst_Vars intr_vars_substs |
278 |> map2 subst_Vars intr_vars_substs |
256 |> map Logic.strip_horn |
279 |> map Logic.strip_horn |
289 |> map2 (prep_prem Ps c_name c_ty) (avoids ~~ avoid_trms) |
312 |> map2 (prep_prem Ps c_name c_ty) (avoids ~~ avoid_trms) |
290 |
313 |
291 fun after_qed ctxt_outside fresh_thms ctxt = |
314 fun after_qed ctxt_outside fresh_thms ctxt = |
292 let |
315 let |
293 val thms = Goal.prove ctxt [] ind_prems' ind_concl' |
316 val thms = Goal.prove ctxt [] ind_prems' ind_concl' |
294 (tac raw_induct fresh_thms Ps avoids avoid_trms intr_cvars) |
317 (prove_sinduct_tac raw_induct fresh_thms Ps avoids avoid_trms intr_cvars param_trms) |
295 |> singleton (ProofContext.export ctxt ctxt_outside) |
318 |> singleton (ProofContext.export ctxt ctxt_outside) |
296 |> Datatype_Aux.split_conj_thm |
319 |> Datatype_Aux.split_conj_thm |
297 |> map (fn thm => thm RS normalise) |
320 |> map (fn thm => thm RS normalise) |
298 |> map (asm_full_simplify (HOL_basic_ss addsimps @{thms permute_zero induct_rulify})) |
321 |> map (asm_full_simplify (HOL_basic_ss addsimps @{thms permute_zero induct_rulify})) |
299 |> map (Drule.rotate_prems (length ind_prems')) |
322 |> map (Drule.rotate_prems (length ind_prems')) |
504 apply(simp add: supp_Pair fresh_star_Un) |
528 apply(simp add: supp_Pair fresh_star_Un) |
505 apply(rule_tac t="p \<bullet> (T1 \<rightarrow> T2)" and s="(q + p) \<bullet> (T1 \<rightarrow> T2)" in subst) |
529 apply(rule_tac t="p \<bullet> (T1 \<rightarrow> T2)" and s="(q + p) \<bullet> (T1 \<rightarrow> T2)" in subst) |
506 apply(simp only: permute_plus) |
530 apply(simp only: permute_plus) |
507 apply(rule supp_perm_eq) |
531 apply(rule supp_perm_eq) |
508 apply(simp add: supp_Pair fresh_star_Un) |
532 apply(simp add: supp_Pair fresh_star_Un) |
|
533 (* apply(perm_simp) *) |
509 apply(simp (no_asm) only: eqvts) |
534 apply(simp (no_asm) only: eqvts) |
510 apply(rule a3) |
535 apply(rule a3) |
511 apply(simp only: eqvts permute_plus) |
536 apply(simp only: eqvts permute_plus) |
512 apply(rule_tac p="- (q + p)" in permute_boolE) |
537 apply(rule_tac p="- (q + p)" in permute_boolE) |
513 apply(perm_strict_simp add: permute_minus_cancel) |
538 apply(perm_strict_simp add: permute_minus_cancel) |
515 apply(rule_tac p="- (q + p)" in permute_boolE) |
540 apply(rule_tac p="- (q + p)" in permute_boolE) |
516 apply(perm_strict_simp add: permute_minus_cancel) |
541 apply(perm_strict_simp add: permute_minus_cancel) |
517 apply(assumption) |
542 apply(assumption) |
518 apply(perm_strict_simp) |
543 apply(perm_strict_simp) |
519 apply(simp only:) |
544 apply(simp only:) |
|
545 thm at_set_avoiding2 |
520 apply(rule at_set_avoiding2) |
546 apply(rule at_set_avoiding2) |
521 apply(simp add: finite_supp) |
547 apply(simp add: finite_supp) |
522 apply(simp add: finite_supp) |
548 apply(simp add: finite_supp) |
523 apply(simp add: finite_supp) |
549 apply(simp add: finite_supp) |
524 apply(rule_tac p="-p" in permute_boolE) |
550 apply(rule_tac p="-p" in permute_boolE) |