/*
 * @(#)$Id: induction_mutual,v 1.1.2.2 1999/02/05 18:47:00 rjb Exp $
 *
 * $Log: induction_mutual,v $
 * Revision 1.1.2.2  1999/02/05 18:47:00  rjb
 * Annotations removed from `Instances' argument.
 *
 * Revision 1.1.2.1  1999/02/01 10:22:39  rjb
 * Support for proof planning with multi-predicate induction schemes.
 *
 */

method(induction_mutual(induction(Lemma-Instances-IndTerms) then SubPlans),
       H==>G,
       [% Force to fail quickly if less than two induction predicates
        InstancesAnn = [_|[_|_]],
        apply_scheme_init(H==>G,Lemma,InstancesAnn,IndTerms,SubPlans,
                          _Suggestion,NonIndVarTypes,InitialSeqs), !],
       [iterate(
           % IndTerms included to prevent fresh meta-variables being used.
           InitialSeqs-[]-IndTerms,
           CurrentSeqs-PrevSubSeqs-IndTerms :=> RemainingSeqs-SubSeqs-IndTerms,
           (apply_scheme_aux(H,NonIndVarTypes,IndTerms,CurrentSeqs,
                             Cases,RemainingSeqs),
            base_and_step_cases(H,Cases,BSeqPs,CSeqPs,SSeqPs,SCSeqPs),
            map_list(BSeqPs,BSeq-Plan:=>BSeq1,
                            ((applicable_submethod(BSeq,base_case(Ms),_,BSeq1),
                              Plan = base_case(Ms)) orelse
                             (BSeq1-Plan = BSeq-idtac)),
                     BSeq1s),
            flatten(BSeq1s,FBSeq1s),
            map_list(CSeqPs,CSeq-Plan:=>CSeq1,
                     (applicable_submethod(CSeq,base_case(Ms),_,CSeqIs),
                      (CSeqIs = [] -> (CSeq1 = [], Plan = base_case(Ms));
                       (map_list(CSeqIs,CSeqI:=>CSeqJs-use_hypotheses(Hyp),
                                 applicable_submethod(
                                    CSeqI,use_hypotheses(Hyp),_,CSeqJs),
                                 CSeqJsCTs),
                        zip(CSeqJsCTs,CSeqJss,CTJs),
                        flatten(CSeqJss,CSeq1),
                        Plan = (base_case(Ms) then CTJs)))),
                     CSeq1s),
            flatten(CSeq1s,FCSeq1s),
            map_list(SSeqPs,SSeq-Plan:=>SSeq1,
                            (applicable_submethod(SSeq,step_case(Ms),_,SSeq1),
                             Plan = step_case(Ms)),
                     SSeq1s),
            flatten(SSeq1s,FSSeq1s),
            map_list(SCSeqPs,SCSeq-Plan:=>SCSeq1,
                     (applicable_submethod(SCSeq,step_case(Ms),_,SCSeqIs),
                      (SCSeqIs = [] -> (SCSeq1 = [], Plan = step_case(Ms));
                       (map_list(SCSeqIs,SCSeqI:=>SCSeqJs-SubPlan,
                                 (applicable_submethod(
                                     SCSeqI,
                                     (try post_ripple_normalize(NormPlan) then
                                      use_hypotheses(Hyp)),
                                     _,SCSeqJs),
                                  (metavar(NormPlan) ->
                                   SubPlan = use_hypotheses(Hyp);
                                   SubPlan = (sym_eval(NormPlan) then
                                              use_hypotheses(Hyp)))),
                                 SCSeqJsSCTs),
                        zip(SCSeqJsSCTs,SCSeqJss,SCTJs),
                        flatten(SCSeqJss,SCSeq1),
                        Plan = (step_case(Ms) then SCTJs)))),
                     SCSeq1s),
            flatten(SCSeq1s,FSCSeq1s),
            append(PrevSubSeqs,FBSeq1s,Seqs1),
            append(Seqs1,FCSeq1s,Seqs2),
            append(Seqs2,FSSeq1s,Seqs3),
            append(Seqs3,FSCSeq1s,SubSeqs)
           ),
           RemainingSeqs \= [],      % Continue iterating if sequents remain.
           []-AllSubSeqs-IndTerms),  % Fail if not all sequents processed.
        map_list(InstancesAnn,IA:=>I,unannotated(IA,I),Instances)
       ],
       AllSubSeqs,
       induction_mutual(induction(Lemma-Instances-IndTerms) then SubPlans)
      ).
