123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259(************************************************************************)(* * 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) *)(************************************************************************)openUtilopenCErrorsopenNamesopenFormulaopenUnifyletnewcnt()=letcnt=ref(-1)infunb->ifbthenincrcnt;!cntletpriority:typea.apattern->int=(* pure heuristics, <=0 for non reversible *)functionRightPatternrf->beginmatchrfwithRarrow->100|Rand->40|Ror->-15|Rfalse->-50|Rforall->100|Rexists(_,_,_)->-29end|LeftPatternlf->matchlfwithLfalse->999|Land_->90|Lor_->40|Lforall(_,_,_)->-30|Lexists_->60|LA(_,lap)->matchlapwithLLatom->0|LLfalse(_,_)->100|LLand(_,_)->80|LLor(_,_)->70|LLforall_->-20|LLexists(_,_)->50|LLarrow(_,_,_)->-10moduleOrderedFormula=structtypet=Formula.any_formulaletcompare(AnyFormulae1)(AnyFormulae2)=(prioritye1.pat)-(prioritye2.pat)endtypeh_item=GlobRef.t*Unify.Item.toptionleth_canonizeenv(hr,item)=(Environ.QGlobRef.canonizeenvhr,item)moduleHitem=structtypet=h_itemletcompare(id1,co1)(id2,co2)=letc=GlobRef.UserOrd.compareid1id2inifc=0thenOption.compareUnify.Item.compareco1co2elsecendmoduleHistory=Set.Make(Hitem)moduleContext:sigtypetvalempty:tvalfind:Evd.evar_map->atom->t->GlobRef.tvaladd:Evd.evar_map->atom->GlobRef.t->t->tvalremove:Environ.env->Evd.evar_map->atom->GlobRef.t->t->tend=structmoduleAtom=structtypet=atomletcompare=compare_atomendmoduleCM=Map.Make(Atom)typet=GlobRef.tlistCM.tletempty=CM.emptyletfindsigmatcm=List.hd(CM.findtcm)letaddsigmatypnamcm=tryletl=CM.findtypcminCM.addtyp(nam::l)cmwithNot_found->CM.addtyp[nam]cmletremoveenvsigmatypnamcm=tryletl=CM.findtypcminletl0=List.filter(funid->not(Environ.QGlobRef.equalenvidnam))linmatchl0with[]->CM.removetypcm|_->CM.addtypl0cmwithNot_found->cmendmoduleHP=Heap.Functional(OrderedFormula)typeseqgoal=GoalTermofatom|GoalAtomofatomtypet={redexes:HP.t;context:Context.t;state:Env.t;latoms:atomlist;gl:seqgoal;cnt:counter;history:History.t;depth:int}lethas_fuelseq=seq.depth>0letiter_redexesfseq=HP.iterfseq.redexesletdeepenseq={seqwithdepth=seq.depth-1}letrecordenvitemseq={seqwithhistory=History.add(h_canonizeenvitem)seq.history}letlookupenvsigmaitemseq=History.mem(h_canonizeenvitem)seq.history||matchitemwith(_,None)->false|(id,Somei1)->letp(id2,o)=matchowithNone->false|Somei2->Environ.QGlobRef.equalenvidid2&&more_generalenvsigmai2i1inHistory.existspseq.historyletadd_concl~flagsenvsigmatseq=matchbuild_formula~flagsseq.stateenvsigmaConclgoal_idtseq.cntwith|state,Leftf->{seqwithredexes=HP.add(AnyFormulaf)seq.redexes;gl=GoalTermf.constr;state}|state,Rightt->{seqwithgl=GoalAtomt;state}letadd_formula~flags~hintenvsigmaidtseq=letside=Hyphintinmatchbuild_formula~flagsseq.stateenvsigmaside(formula_idenvid)tseq.cntwith|state,Leftf->{seqwithredexes=HP.add(AnyFormulaf)seq.redexes;context=Context.addsigmaf.constridseq.context;state}|state,Rightt->{seqwithcontext=Context.addsigmatidseq.context;latoms=t::seq.latoms;state}letre_add_formula_listsigmalfseq=letdo_one(AnyFormulaf)cm=matchf.idwith|GoalId->cm|FormulaIdid->Context.addsigmaf.constridcmin{seqwithredexes=List.fold_rightHP.addlfseq.redexes;context=List.fold_rightdo_onelfseq.context}letfind_leftsigmatseq=Context.findsigmatseq.contextletfind_goalsigmaseq=lett=matchseq.glwithGoalAtoma->a|GoalTermt->tinfind_leftsigmatseqletrectake_formulaenvsigmaseq=lethd=HP.maximumseq.redexesinlethp=HP.removeseq.redexesinletAnyFormulahd0=hdinmatchhd0.idwith|GoalId->letnseq={seqwithredexes=hp}inbeginmatchseq.glwith|GoalTermtwhent==hd0.constr->hd,nseq|GoalAtom_|GoalTerm_->take_formulaenvsigmanseq(* discarding deprecated goal *)end|FormulaIdid->hd,{seqwithredexes=hp;context=Context.removeenvsigmahd0.constridseq.context}letempty_seqdepth={redexes=HP.empty;context=Context.empty;latoms=[];gl=GoalTermhole_atom;cnt=newcnt();history=History.empty;depth=depth;state=Env.empty}letmake_simple_atomsseq=letratoms=matchseq.glwith|GoalAtomt->[t]|GoalTerm_->[]in{negative=seq.latoms;positive=ratoms}letexpand_constructor_hints=List.map_append(function|GlobRef.IndRefind->List.init(Inductiveops.nconstructors(Global.env())ind)(funi->GlobRef.ConstructRef(ind,i+1))|gr->[gr])letextend_with_ref_list~flagsenvsigmalseq=letl=expand_constructor_hintslinletfgr(seq,sigma)=letsigma,c=Evd.fresh_globalenvsigmagrinletsigma,typ=Typing.type_ofenvsigmacin(add_formula~flags~hint:falseenvsigmagrtypseq,sigma)inList.fold_rightfl(seq,sigma)openHintsletextend_with_auto_hints~flagsenvsigmalseq=letf(seq,sigma)p_a_t=matchFullHint.reprp_a_twith|Res_pfc|Give_exactc|Res_pf_THEN_trivial_failc->letc=snd@@hint_as_termcin(matchEConstr.destRefsigmacwith|exceptionConstr.DestKO->seq,sigma|gr,_->letsigma,typ=Typing.type_ofenvsigmacinadd_formula~flags~hint:trueenvsigmagrtypseq,sigma)|_->seq,sigmainlethaccdbname=lethdb=trysearchtable_mapdbnamewithNot_found->user_errPp.(str("Firstorder: "^dbname^" : No such Hint database"))inHint_db.fold(fun__lacc->List.fold_leftfaccl)hdbaccinList.fold_lefth(seq,sigma)lletstateseq=seq.state