src/ZF/indrule.ML
changeset 3090 eeb4d0c7f748
parent 2637 e9b203f854ae
child 3398 dfd9cbad5530
equal deleted inserted replaced
3089:32dad29d4666 3090:eeb4d0c7f748
   149 
   149 
   150 val lemma_tac = FIRST' [eresolve_tac [asm_rl, conjE, PartE, mp],
   150 val lemma_tac = FIRST' [eresolve_tac [asm_rl, conjE, PartE, mp],
   151                         resolve_tac [allI, impI, conjI, Part_eqI],
   151                         resolve_tac [allI, impI, conjI, Part_eqI],
   152                         dresolve_tac [spec, mp, Pr.fsplitD]];
   152                         dresolve_tac [spec, mp, Pr.fsplitD]];
   153 
   153 
       
   154 val need_mutual = length Intr_elim.rec_names > 1;
       
   155 
   154 val lemma = (*makes the link between the two induction rules*)
   156 val lemma = (*makes the link between the two induction rules*)
   155     prove_goalw_cterm part_rec_defs 
   157   if need_mutual then
   156           (cterm_of sign (Logic.mk_implies (induct_concl,mutual_induct_concl)))
   158      (writeln "  Proving the mutual induction rule...";
   157           (fn prems =>
   159       prove_goalw_cterm part_rec_defs 
   158            [cut_facts_tac prems 1, 
   160 	    (cterm_of sign (Logic.mk_implies (induct_concl,
   159             REPEAT (rewrite_goals_tac [Pr.split_eq] THEN
   161 					      mutual_induct_concl)))
   160                     lemma_tac 1)]);
   162 	    (fn prems =>
       
   163 	     [cut_facts_tac prems 1, 
       
   164 	      REPEAT (rewrite_goals_tac [Pr.split_eq] THEN
       
   165 		      lemma_tac 1)]))
       
   166   else TrueI;
   161 
   167 
   162 (*Mutual induction follows by freeness of Inl/Inr.*)
   168 (*Mutual induction follows by freeness of Inl/Inr.*)
   163 
   169 
   164 (*Simplification largely reduces the mutual induction rule to the 
   170 (*Simplification largely reduces the mutual induction rule to the 
   165   standard rule*)
   171   standard rule*)
   201               DEPTH_SOLVE (FIRSTGOAL (ares_tac [impI] ORELSE' 
   207               DEPTH_SOLVE (FIRSTGOAL (ares_tac [impI] ORELSE' 
   202                                       eresolve_tac (conjE::mp::cmonos))))
   208                                       eresolve_tac (conjE::mp::cmonos))))
   203           ) i)
   209           ) i)
   204        THEN mutual_ind_tac prems (i-1);
   210        THEN mutual_ind_tac prems (i-1);
   205 
   211 
   206 val _ = writeln "  Proving the mutual induction rule...";
       
   207 
       
   208 val mutual_induct_fsplit = 
   212 val mutual_induct_fsplit = 
       
   213   if need_mutual then
   209     prove_goalw_cterm []
   214     prove_goalw_cterm []
   210           (cterm_of sign
   215           (cterm_of sign
   211            (Logic.list_implies 
   216            (Logic.list_implies 
   212               (map (induct_prem (Inductive.rec_tms~~preds)) Inductive.intr_tms,
   217               (map (induct_prem (Inductive.rec_tms~~preds)) Inductive.intr_tms,
   213                mutual_induct_concl)))
   218                mutual_induct_concl)))
   214           (fn prems =>
   219           (fn prems =>
   215            [rtac (quant_induct RS lemma) 1,
   220            [rtac (quant_induct RS lemma) 1,
   216             mutual_ind_tac (rev prems) (length prems)]);
   221             mutual_ind_tac (rev prems) (length prems)])
   217 
   222   else TrueI;
   218 
       
   219 
   223 
   220 (** Uncurrying the predicate in the ordinary induction rule **)
   224 (** Uncurrying the predicate in the ordinary induction rule **)
   221 
   225 
   222 (*instantiate the variable to a tuple, if it is non-trivial, in order to
   226 (*instantiate the variable to a tuple, if it is non-trivial, in order to
   223   allow the predicate to be "opened up".
   227   allow the predicate to be "opened up".
   238                   (CP.split_rule_var
   242                   (CP.split_rule_var
   239                     (Var((pred_name,2), elem_type --> Ind_Syntax.oT),
   243                     (Var((pred_name,2), elem_type --> Ind_Syntax.oT),
   240                      induct0));
   244                      induct0));
   241 
   245 
   242   (*Just "True" unless there's true mutual recursion.  This saves storage.*)
   246   (*Just "True" unless there's true mutual recursion.  This saves storage.*)
   243   val mutual_induct = 
   247   val mutual_induct = CP.remove_split mutual_induct_fsplit
   244       if length Intr_elim.rec_names > 1 
       
   245       then CP.remove_split mutual_induct_fsplit
       
   246       else TrueI;
       
   247   end
   248   end
   248 end;
   249 end;