123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566(************************************************************************)(* * The Rocq Prover / The Rocq 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_statementssigmactxsccls=letinds=List.map2(functxccl->let(hyps,ccl)=EConstr.decompose_prod_declssigmacclinlethyps=hyps@ctxinletwhnf_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,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,0]|_->[]inind_hyps,ind_ccl)ctxscclsinletinds_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.mapsnd)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}