1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980(************************************************************************)(* * The Coq Proof Assistant / The Coq Development Team *)(* v * Copyright INRIA, CNRS and contributors *)(* <O___,, * (see version control and CREDITS file for authors & dates) *)(* \VV/ **************************************************************)(* // * This file is distributed under the terms of the *)(* * GNU Lesser General Public License Version 2.1 *)(* * (see LICENSE file for the text of the license) *)(************************************************************************)openUtilopenConstropenDeclarationsmoduleRelDecl=Context.Rel.Declarationletfind_mutually_recursive_statementssigmathms=letinds=List.map(funx->lettyp=Declare.CInfo.get_typxinlet(hyps,ccl)=EConstr.decompose_prod_declssigmatypinletwhnf_hyp_hds=EConstr.map_rel_context_in_env(funenvc->fst(Reductionops.whd_all_stackenvsigmac))(Global.env())hypsinletind_hyps=List.flatten(List.map_i(funidecl->lett=RelDecl.get_typedeclinmatchEConstr.kindsigmatwith|Ind((kn,_asind),u)whenletmind=Global.lookup_mindkninmind.mind_finite<>Declarations.CoFinite->[ind,x,i]|_->[])0(List.rev(List.filterContext.Rel.Declaration.is_local_assumwhnf_hyp_hds)))inletind_ccl=letcclenv=EConstr.push_rel_contexthyps(Global.env())inletwhnf_ccl,_=Reductionops.whd_all_stackcclenvsigmacclinmatchEConstr.kindsigmawhnf_cclwith|Ind((kn,_asind),u)when(Global.lookup_mindkn).mind_finite==Declarations.CoFinite->[ind,x,0]|_->[]inind_hyps,ind_ccl)thmsinletinds_hyps,ind_ccls=List.splitindsinletof_same_mutind((kn,_),_,_)=function((kn',_),_,_)->Environ.QMutInd.equal(Global.env())knkn'in(* Check if all conclusions are coinductive in the same type *)(* (degenerated cartesian product since there is at most one coind ccl) *)letsame_indccl=List.cartesians_filter(funhypoks->ifList.for_all(of_same_mutindhyp)oksthenSome(hyp::oks)elseNone)[]ind_cclsinletcommon_same_indhyp=List.cartesians_filter(funhypoks->ifList.for_all(of_same_mutindhyp)oksthenSome(hyp::oks)elseNone)[]inds_hypsinletpossibly_cofix=not(List.is_emptysame_indccl)in(* all conclusions are coinductive *)letpossible_fix_indices=matchcommon_same_indhypwith|[]->[]|_::_->(* assume the largest indices as possible *)List.map(List.mappi3)inds_hypsinifnotpossibly_cofix&&List.is_emptypossible_fix_indicesthenCErrors.user_errPp.(str("Cannot find common (mutual) inductive premises or coinductive"^" conclusions in the statements."));Pretyping.{possibly_cofix;possible_fix_indices}typemutual_info=|NonMutualofEConstr.tDeclare.CInfo.t|MutualofPretyping.possible_guardletlook_for_possibly_mutual_statementssigmathms:mutual_info=matchthmswith|[thm]->(* One non recursively proved theorem *)NonMutualthm|_::_asthms->(* More than one statement and/or an explicit decreasing mark: *)Mutual(find_mutually_recursive_statementssigmathms)|[]->CErrors.anomaly(Pp.str"Empty list of theorems.")