453 let |
453 let |
454 val _ = message " Proving the induction rule ..."; |
454 val _ = message " Proving the induction rule ..."; |
455 |
455 |
456 val sign = Theory.sign_of thy; |
456 val sign = Theory.sign_of thy; |
457 |
457 |
|
458 val sum_case_rewrites = (case ThyInfo.lookup_theory "Datatype" of |
|
459 None => [] |
|
460 | Some thy' => map mk_meta_eq (PureThy.get_thms thy' "sum.cases")); |
|
461 |
458 val (preds, ind_prems, mutual_ind_concl) = mk_indrule cs cTs params intr_ts; |
462 val (preds, ind_prems, mutual_ind_concl) = mk_indrule cs cTs params intr_ts; |
459 |
463 |
460 (* make predicate for instantiation of abstract induction rule *) |
464 (* make predicate for instantiation of abstract induction rule *) |
461 |
465 |
462 fun mk_ind_pred _ [P] = P |
466 fun mk_ind_pred _ [P] = P |
463 | mk_ind_pred T Ps = |
467 | mk_ind_pred T Ps = |
464 let val n = (length Ps) div 2; |
468 let val n = (length Ps) div 2; |
465 val Type (_, [T1, T2]) = T |
469 val Type (_, [T1, T2]) = T |
466 in Const ("basic_sum_case", |
470 in Const ("Datatype.sum.sum_case", |
467 [T1 --> HOLogic.boolT, T2 --> HOLogic.boolT, T] ---> HOLogic.boolT) $ |
471 [T1 --> HOLogic.boolT, T2 --> HOLogic.boolT, T] ---> HOLogic.boolT) $ |
468 mk_ind_pred T1 (take (n, Ps)) $ mk_ind_pred T2 (drop (n, Ps)) |
472 mk_ind_pred T1 (take (n, Ps)) $ mk_ind_pred T2 (drop (n, Ps)) |
469 end; |
473 end; |
470 |
474 |
471 val ind_pred = mk_ind_pred sumT preds; |
475 val ind_pred = mk_ind_pred sumT preds; |
480 map (fn c => prove_goalw_cterm [] (cterm_of sign |
484 map (fn c => prove_goalw_cterm [] (cterm_of sign |
481 (HOLogic.mk_Trueprop (HOLogic.mk_eq |
485 (HOLogic.mk_Trueprop (HOLogic.mk_eq |
482 (mk_vimage cs sumT (HOLogic.Collect_const sumT $ ind_pred) c, |
486 (mk_vimage cs sumT (HOLogic.Collect_const sumT $ ind_pred) c, |
483 HOLogic.Collect_const (HOLogic.dest_setT (fastype_of c)) $ |
487 HOLogic.Collect_const (HOLogic.dest_setT (fastype_of c)) $ |
484 nth_elem (find_index_eq c cs, preds))))) |
488 nth_elem (find_index_eq c cs, preds))))) |
485 (fn _ => [rtac vimage_Collect 1, rewrite_goals_tac |
489 (fn _ => [rtac vimage_Collect 1, rewrite_goals_tac sum_case_rewrites, |
486 (map mk_meta_eq [sum_case_Inl, sum_case_Inr]), |
|
487 rtac refl 1])) cs; |
490 rtac refl 1])) cs; |
488 |
491 |
489 val induct = prove_goalw_cterm [] (cterm_of sign |
492 val induct = prove_goalw_cterm [] (cterm_of sign |
490 (Logic.list_implies (ind_prems, ind_concl))) (fn prems => |
493 (Logic.list_implies (ind_prems, ind_concl))) (fn prems => |
491 [rtac (impI RS allI) 1, |
494 [rtac (impI RS allI) 1, |
496 REPEAT (FIRSTGOAL (eresolve_tac [CollectE, disjE])), |
499 REPEAT (FIRSTGOAL (eresolve_tac [CollectE, disjE])), |
497 (*Now break down the individual cases. No disjE here in case |
500 (*Now break down the individual cases. No disjE here in case |
498 some premise involves disjunction.*) |
501 some premise involves disjunction.*) |
499 REPEAT (FIRSTGOAL (eresolve_tac [IntE, CollectE, exE, conjE] |
502 REPEAT (FIRSTGOAL (eresolve_tac [IntE, CollectE, exE, conjE] |
500 ORELSE' hyp_subst_tac)), |
503 ORELSE' hyp_subst_tac)), |
501 rewrite_goals_tac (map mk_meta_eq [sum_case_Inl, sum_case_Inr]), |
504 rewrite_goals_tac sum_case_rewrites, |
502 EVERY (map (fn prem => |
505 EVERY (map (fn prem => |
503 DEPTH_SOLVE_1 (ares_tac [prem, conjI, refl] 1)) prems)]); |
506 DEPTH_SOLVE_1 (ares_tac [prem, conjI, refl] 1)) prems)]); |
504 |
507 |
505 val lemma = prove_goalw_cterm rec_sets_defs (cterm_of sign |
508 val lemma = prove_goalw_cterm rec_sets_defs (cterm_of sign |
506 (Logic.mk_implies (ind_concl, mutual_ind_concl))) (fn prems => |
509 (Logic.mk_implies (ind_concl, mutual_ind_concl))) (fn prems => |
507 [cut_facts_tac prems 1, |
510 [cut_facts_tac prems 1, |
508 REPEAT (EVERY |
511 REPEAT (EVERY |
509 [REPEAT (resolve_tac [conjI, impI] 1), |
512 [REPEAT (resolve_tac [conjI, impI] 1), |
510 TRY (dtac vimageD 1), etac allE 1, dtac mp 1, atac 1, |
513 TRY (dtac vimageD 1), etac allE 1, dtac mp 1, atac 1, |
511 rewrite_goals_tac (map mk_meta_eq [sum_case_Inl, sum_case_Inr]), |
514 rewrite_goals_tac sum_case_rewrites, |
512 atac 1])]) |
515 atac 1])]) |
513 |
516 |
514 in standard (split_rule (induct RS lemma)) |
517 in standard (split_rule (induct RS lemma)) |
515 end; |
518 end; |
516 |
519 |