src/ZF/indrule.ML
changeset 4804 02b7c759159b
parent 4352 7ac9f3e8a97d
child 4971 09b8945cac07
equal deleted inserted replaced
4803:8428d4699d58 4804:02b7c759159b
    60       val (Some pred) = gen_assoc (op aconv) (ind_alist, X)
    60       val (Some pred) = gen_assoc (op aconv) (ind_alist, X)
    61       val concl = FOLogic.mk_Trueprop (pred $ t)
    61       val concl = FOLogic.mk_Trueprop (pred $ t)
    62   in list_all_free (quantfrees, Logic.list_implies (iprems,concl)) end
    62   in list_all_free (quantfrees, Logic.list_implies (iprems,concl)) end
    63   handle Bind => error"Recursion term not found in conclusion";
    63   handle Bind => error"Recursion term not found in conclusion";
    64 
    64 
    65 (*Reduces backtracking by delivering the correct premise to each goal.
    65 (*Minimizes backtracking by delivering the correct premise to each goal.
    66   Intro rules with extra Vars in premises still cause some backtracking *)
    66   Intro rules with extra Vars in premises still cause some backtracking *)
    67 fun ind_tac [] 0 = all_tac
    67 fun ind_tac [] 0 = all_tac
    68   | ind_tac(prem::prems) i = 
    68   | ind_tac(prem::prems) i = 
    69         DEPTH_SOLVE_1 (ares_tac [prem, refl] i) THEN
    69         DEPTH_SOLVE_1 (ares_tac [prem, refl] i) THEN
    70         ind_tac prems (i-1);
    70         ind_tac prems (i-1);
    72 val pred = Free(pred_name, Ind_Syntax.iT --> FOLogic.oT);
    72 val pred = Free(pred_name, Ind_Syntax.iT --> FOLogic.oT);
    73 
    73 
    74 val ind_prems = map (induct_prem (map (rpair pred) Inductive.rec_tms)) 
    74 val ind_prems = map (induct_prem (map (rpair pred) Inductive.rec_tms)) 
    75                     Inductive.intr_tms;
    75                     Inductive.intr_tms;
    76 
    76 
    77 (*Debugging code...
    77 val _ = if !Ind_Syntax.trace then 
    78 val _ = writeln "ind_prems = ";
    78             (writeln "ind_prems = ";
    79 val _ = seq (writeln o Sign.string_of_term sign) ind_prems;
    79 	     seq (writeln o Sign.string_of_term sign) ind_prems;
    80 *)
    80 	     writeln "raw_induct = "; print_thm Intr_elim.raw_induct)
       
    81         else ();
       
    82 
    81 
    83 
    82 (*We use a MINIMAL simpset because others (such as FOL_ss) contain too many
    84 (*We use a MINIMAL simpset because others (such as FOL_ss) contain too many
    83   simplifications.  If the premises get simplified, then the proofs will 
    85   simplifications.  If the premises get simplified, then the proofs could 
    84   fail.  *)
    86   fail.  *)
    85 val min_ss = empty_ss
    87 val min_ss = empty_ss
    86       setmksimps (map mk_meta_eq o ZF_atomize o gen_all)
    88       setmksimps (map mk_meta_eq o ZF_atomize o gen_all)
    87       setSolver  (fn prems => resolve_tac (triv_rls@prems) 
    89       setSolver  (fn prems => resolve_tac (triv_rls@prems) 
    88                               ORELSE' assume_tac
    90                               ORELSE' assume_tac
    96       (fn prems =>
    98       (fn prems =>
    97        [rtac (impI RS allI) 1,
    99        [rtac (impI RS allI) 1,
    98         DETERM (etac Intr_elim.raw_induct 1),
   100         DETERM (etac Intr_elim.raw_induct 1),
    99         (*Push Part inside Collect*)
   101         (*Push Part inside Collect*)
   100         full_simp_tac (min_ss addsimps [Part_Collect]) 1,
   102         full_simp_tac (min_ss addsimps [Part_Collect]) 1,
   101         REPEAT (FIRSTGOAL (eresolve_tac [CollectE, exE, conjE, disjE] ORELSE'
   103         (*This CollectE and disjE separates out the introduction rules*)
   102                            hyp_subst_tac)),
   104 	REPEAT (FIRSTGOAL (eresolve_tac [CollectE, disjE])),
       
   105 	(*Now break down the individual cases.  No disjE here in case
       
   106           some premise involves disjunction.*)
       
   107         REPEAT (FIRSTGOAL (eresolve_tac [CollectE, exE, conjE] 
       
   108                            ORELSE' hyp_subst_tac)),
   103         ind_tac (rev prems) (length prems) ]);
   109         ind_tac (rev prems) (length prems) ]);
   104 
   110 
   105 (*** Prove the simultaneous induction rule ***)
   111 (*** Prove the simultaneous induction rule ***)
   106 
   112 
   107 (*Make distinct predicates for each inductive set*)
   113 (*Make distinct predicates for each inductive set*)
   163 					      mutual_induct_concl)))
   169 					      mutual_induct_concl)))
   164 	    (fn prems =>
   170 	    (fn prems =>
   165 	     [cut_facts_tac prems 1, 
   171 	     [cut_facts_tac prems 1, 
   166 	      REPEAT (rewrite_goals_tac [Pr.split_eq] THEN
   172 	      REPEAT (rewrite_goals_tac [Pr.split_eq] THEN
   167 		      lemma_tac 1)]))
   173 		      lemma_tac 1)]))
   168   else TrueI;
   174   else (writeln "  [ No mutual induction rule needed ]";
       
   175         TrueI);
   169 
   176 
   170 (*Mutual induction follows by freeness of Inl/Inr.*)
   177 (*Mutual induction follows by freeness of Inl/Inr.*)
   171 
   178 
   172 (*Simplification largely reduces the mutual induction rule to the 
   179 (*Simplification largely reduces the mutual induction rule to the 
   173   standard rule*)
   180   standard rule*)
   182   where t==Part(tf,Inl) and f==Part(tf,Inr) to  list({v: tf. P_t(v)}).
   189   where t==Part(tf,Inl) and f==Part(tf,Inr) to  list({v: tf. P_t(v)}).
   183   Instead the following rules extract the relevant conjunct.
   190   Instead the following rules extract the relevant conjunct.
   184 *)
   191 *)
   185 val cmonos = [subset_refl RS Collect_mono] RL Inductive.monos RLN (2,[rev_subsetD]);
   192 val cmonos = [subset_refl RS Collect_mono] RL Inductive.monos RLN (2,[rev_subsetD]);
   186 
   193 
   187 (*Avoids backtracking by delivering the correct premise to each goal*)
   194 (*Minimizes backtracking by delivering the correct premise to each goal*)
   188 fun mutual_ind_tac [] 0 = all_tac
   195 fun mutual_ind_tac [] 0 = all_tac
   189   | mutual_ind_tac(prem::prems) i = 
   196   | mutual_ind_tac(prem::prems) i = 
   190       DETERM
   197       DETERM
   191        (SELECT_GOAL 
   198        (SELECT_GOAL 
   192           (
   199           (