src/HOL/Tools/inductive_package.ML
changeset 7293 959e060f4a2f
parent 7257 745cfc8871e2
child 7349 228b711ad68c
equal deleted inserted replaced
7292:dff3470c5c62 7293:959e060f4a2f
   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