123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134(************************************************************************)(* * 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) *)(************************************************************************)openUtilopenProofview.NotationsopenContext.Named.DeclarationmoduleNamedDecl=Context.Named.Declarationletextract_prefixenvinfo=letctx1=List.rev(EConstr.named_contextenv)inletctx2=List.rev(Evd.evar_contextinfo)inletrecsharel1l2accu=matchl1,l2with|d1::l1,d2::l2->ifd1==d2thensharel1l2(d1::accu)else(accu,d2::l2)|_->(accu,l2)insharectx1ctx2[]lettypecheck_evarevenvsigma=letinfo=Evd.find_undefinedsigmaevin(* Typecheck the hypotheses. *)lettype_hyp(sigma,env)decl=lett=NamedDecl.get_typedeclinletsigma,_=Typing.sort_ofenvsigmatinletsigma=matchdeclwith|LocalAssum_->sigma|LocalDef(_,body,_)->Typing.checkenvsigmabodytin(sigma,EConstr.push_nameddeclenv)inlet(common,changed)=extract_prefixenvinfoinletenv=Environ.reset_with_named_context(EConstr.val_of_named_contextcommon)envinlet(sigma,env)=List.fold_lefttype_hyp(sigma,env)changedin(* Typecheck the conclusion *)letsigma,_=Typing.sort_ofenvsigma(Evd.evar_conclinfo)insigmaletgeneric_refine~typecheckfgl=letsigma=Proofview.Goal.sigmaglinletenv=Proofview.Goal.envglinletconcl=Proofview.Goal.conclglinletstate=Proofview.Goal.stateglin(* Save the [future_goals] state to restore them after the
refinement. *)letsigma=Evd.push_future_goalssigmain(* Create the refinement term *)Proofview.Unsafe.tclEVARSsigma>>=fun()->f>>=fun(v,c)->Proofview.tclEVARMAP>>=funsigma'->Proofview.wrap_exceptionsbeginfun()->(* Redo the effects in sigma in the monad's env *)letprivates_csts=Evd.eval_side_effectssigma'inletenv=Safe_typing.push_private_constantsenvprivates_csts.Evd.seff_privatein(* Check that the introduced evars are well-typed *)letfoldaccuev=typecheck_evarevenvaccuinletsigma=iftypecheckthenEvd.fold_future_goalsfoldsigma'elsesigma'in(* Check that the refined term is typesafe *)letsigma=iftypecheckthenTyping.checkenvsigmacconclelsesigmain(* Check that the goal itself does not appear in the refined term *)letself=Proofview.Goal.goalglinlet_=ifnot(Evarutil.occur_evar_uptosigmaselfc)then()elsePretype_errors.error_occur_checkenvsigmaselfcin(* Restore the [future goals] state. *)letfuture_goals,sigma=Evd.pop_future_goalssigmain(* Select the goals *)letfuture_goals=Evd.FutureGoals.map_filter(Proofview.Unsafe.advancesigma)future_goalsinletshelf=Evd.shelfsigmainletfuture_goals=Evd.FutureGoals.filter(funev->not@@List.memevshelf)future_goalsin(* Proceed to the refinement *)letsigma=matchProofview.Unsafe.advancesigmaselfwith|None->(* Nothing to do, the goal has been solved by side-effect *)sigma|Someself->match(Evd.FutureGoals.principalfuture_goals)with|None->Evd.defineselfcsigma|Someevk->letid=Evd.evar_identselfsigmainletsigma=Evd.defineselfcsigmainmatchidwith|None->sigma|Someid->Evd.renameevkidsigmain(* Mark goals *)letsigma=Proofview.Unsafe.mark_as_goalssigma(Evd.FutureGoals.combfuture_goals)inletcomb=CList.rev_map(funx->Proofview.goal_with_statexstate)(Evd.FutureGoals.combfuture_goals)inlettrace()=Pp.(hov2(str"simple refine"++spc()++Termops.Internal.print_constr_envenvsigmac))inProofview.Trace.name_tactictrace(Proofview.tclUNITv)>>=funv->Proofview.Unsafe.tclSETENV(Environ.reset_contextenv)<*>Proofview.Unsafe.tclEVARSsigma<*>Proofview.Unsafe.tclSETGOALScomb<*>Proofview.tclUNITvendletliftc=Proofview.tclEVARMAP>>=funsigma->Proofview.wrap_exceptionsbeginfun()->let(sigma,c)=csigmainProofview.Unsafe.tclEVARSsigma>>=fun()->Proofview.tclUNITcendletmake_refine_enter~typecheckfgl=generic_refine~typecheck(liftf)glletrefine~typecheckf=letfevd=let(evd,c)=fevdin(evd,((),c))inProofview.Goal.enter(make_refine_enter~typecheckf)(** {7 solve_constraints}
Ensure no remaining unification problems are left. Run at every "." by default. *)letsolve_constraints=letopenProofviewintclENV>>=funenv->tclEVARMAP>>=funsigma->tryletsigma=Evarconv.solve_unif_constraints_with_heuristicsenvsigmainUnsafe.tclEVARSADVANCEsigmawithewhenCErrors.noncriticale->lete,info=Exninfo.captureeintclZERO~infoe