123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246(************************************************************************)(* * 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) *)(************************************************************************)openUtilopenPpopenCErrorsopenNamesopenEConstropenFormulaopenUnifyletnewcnt()=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.toptionmoduleHitem=structtypet=h_itemletcompare(id1,co1)(id2,co2)=letc=GlobRef.CanOrd.compareid1id2inifc=0thenOption.compareUnify.Item.compareco1co2elsecendmoduleCM=Map.Make(Constr)moduleHistory=Set.Make(Hitem)letcm_addsigmatypnamcm=lettyp=EConstr.to_constr~abort_on_undefined_evars:falsesigmatypintryletl=CM.findtypcminCM.addtyp(nam::l)cmwithNot_found->CM.addtyp[nam]cmletcm_removesigmatypnamcm=lettyp=EConstr.to_constr~abort_on_undefined_evars:falsesigmatypintryletl=CM.findtypcminletl0=List.filter(funid->not(GlobRef.CanOrd.equalidnam))linmatchl0with[]->CM.removetypcm|_->CM.addtypl0cmwithNot_found->cmmoduleHP=Heap.Functional(OrderedFormula)typeseqgoal=GoalTermofEConstr.t|GoalAtomofatomtypet={redexes:HP.t;context:(GlobRef.tlist)CM.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}letrecorditemseq={seqwithhistory=History.additemseq.history}letlookupenvsigmaitemseq=History.memitemseq.history||matchitemwith(_,None)->false|(id,Somei1)->letp(id2,o)=matchowithNone->false|Somei2->Environ.QGlobRef.equalenvidid2&&more_generalenvsigmai2i1inHistory.existspseq.historyletadd_concl~flagsenvsigmatseq=matchbuild_formula~flagsenvsigmaConclGoalIdtseq.cntwith|Leftf->{seqwithredexes=HP.add(AnyFormulaf)seq.redexes;gl=GoalTermf.constr}|Rightt->{seqwithgl=GoalAtomt}letadd_formula~flags~hintenvsigmaidtseq=letside=Hyphintinmatchbuild_formula~flagsenvsigmaside(FormulaIdid)tseq.cntwith|Leftf->{seqwithredexes=HP.add(AnyFormulaf)seq.redexes;context=cm_addsigmaf.constridseq.context}|Rightt->{seqwithcontext=cm_addsigma(repr_atomt)idseq.context;latoms=t::seq.latoms}letre_add_formula_listsigmalfseq=letdo_one(AnyFormulaf)cm=matchf.idwith|GoalId->cm|FormulaIdid->cm_addsigmaf.constridcmin{seqwithredexes=List.fold_rightHP.addlfseq.redexes;context=List.fold_rightdo_onelfseq.context}letfind_leftsigmatseq=List.hd(CM.find(EConstr.to_constr~abort_on_undefined_evars:falsesigmat)seq.context)letfind_goalsigmaseq=lett=matchseq.glwithGoalAtoma->repr_atoma|GoalTermt->tinfind_leftsigmatseqletrectake_formulasigmaseq=lethd=HP.maximumseq.redexesinlethp=HP.removeseq.redexesinletAnyFormulahd0=hdinmatchhd0.idwith|GoalId->letnseq={seqwithredexes=hp}inbeginmatchseq.glwith|GoalTermtwhent==hd0.constr->hd,nseq|GoalAtom_|GoalTerm_->take_formulasigmanseq(* discarding deprecated goal *)end|FormulaIdid->hd,{seqwithredexes=hp;context=cm_removesigmahd0.constridseq.context}letempty_seqdepth={redexes=HP.empty;context=CM.empty;latoms=[];gl=GoalTerm(mkMeta1);cnt=newcnt();history=History.empty;depth=depth}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)l(* For debug *)let_print_cmapmap=letprint_entrycls=letenv=Global.env()inletsigma=Evd.from_envenvinstr"| "++prlistPrinter.pr_globall++str" : "++Printer.pr_constr_envenvsigmac++cut()++sin(v0(str"-----"++cut()++CM.foldprint_entrymap(mt())++str"-----"))