12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591(************************************************************************)(* * 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) *)(************************************************************************)(* *)(* Micromega: A reflexive tactic using the Positivstellensatz *)(* *)(* ** Toplevel definition of tactics ** *)(* *)(* - Modules Mc, Env, Cache, CacheZ *)(* *)(* Frédéric Besson (Irisa/Inria) 2006-2019 *)(* *)(************************************************************************)openPpopenNamesopenGoptionsopenMutilsopenConstropenContextopenTactypesopenMcPrintermoduleERelevance=EConstr.ERelevance(**
* Debug flag
*)letdebug=false(* Limit the proof search *)letmax_depth=max_intletsince_8_14=Deprecation.make~since:"8.14"()(* Search limit for provers over Q R *)let{Goptions.get=lra_proof_depth}=declare_int_option_and_ref~depr:since_8_14~key:["Lra";"Depth"]~value:max_depth()(* Search limit for provers over Z *)let{Goptions.get=lia_enum}=declare_bool_option_and_ref~depr:since_8_14~key:["Lia";"Enum"]~value:true()let{Goptions.get=lia_proof_depth}=declare_int_option_and_ref~depr:since_8_14~key:["Lia";"Depth"]~value:max_depth()letget_lia_option()=(true,lia_enum(),lia_proof_depth())(* Enable/disable caches *)let{Goptions.get=use_lia_cache}=declare_bool_option_and_ref~key:["Lia";"Cache"]~value:true()let{Goptions.get=use_nia_cache}=declare_bool_option_and_ref~key:["Nia";"Cache"]~value:true()let{Goptions.get=use_nra_cache}=declare_bool_option_and_ref~key:["Nra";"Cache"]~value:true()let{Goptions.get=show_used_hyps}=declare_bool_option_and_ref~key:["Info";"Micromega"]~value:false()letuse_csdp_cache()=true(**
* Initialize a tag type to the Tag module declaration (see Mutils).
*)typetag=Tag.tmoduleMc=Micromega(**
* An atom is of the form:
* pExpr1 \{<,>,=,<>,<=,>=\} pExpr2
* where pExpr1, pExpr2 are polynomial expressions (see Micromega). pExprs are
* parametrized by 'cst, which is used as the type of constants.
*)type'cstatom='cstMc.formulatype'cstformula=('cstatom,EConstr.constr,tag*EConstr.constr,Names.Id.t)Mc.gFormulatype'cstclause=('cstMc.nFormula,tag*EConstr.constr)Mc.clausetype'cstcnf=('cstMc.nFormula,tag*EConstr.constr)Mc.cnfletpp_kindo=function|Mc.IsProp->output_stringo"Prop"|Mc.IsBool->output_stringo"bool"letkind_is_prop=functionMc.IsProp->true|Mc.IsBool->falseletrecpp_formulao(f:'cstformula)=Mc.(matchfwith|TTk->output_stringo(ifkind_is_propkthen"True"else"true")|FFk->output_stringo(ifkind_is_propkthen"False"else"false")|X(k,c)->Printf.fprintfo"X %a"pp_kindk|A(_,_,(t,_))->Printf.fprintfo"A(%a)"Tag.ppt|AND(_,f1,f2)->Printf.fprintfo"AND(%a,%a)"pp_formulaf1pp_formulaf2|OR(_,f1,f2)->Printf.fprintfo"OR(%a,%a)"pp_formulaf1pp_formulaf2|IMPL(_,f1,n,f2)->Printf.fprintfo"IMPL(%a,%s,%a)"pp_formulaf1(matchnwithSomeid->Names.Id.to_stringid|None->"")pp_formulaf2|NOT(_,f)->Printf.fprintfo"NOT(%a)"pp_formulaf|IFF(_,f1,f2)->Printf.fprintfo"IFF(%a,%a)"pp_formulaf1pp_formulaf2|EQ(f1,f2)->Printf.fprintfo"EQ(%a,%a)"pp_formulaf1pp_formulaf2)(**
* Given a set of integers s=\{i0,...,iN\} and a list m, return the list of
* elements of m that are at position i0,...,iN.
*)letselectism=letrecxselectiim=matchmwith|[]->[]|e::m->ifISet.memisthene::xselecti(i+1)melsexselecti(i+1)minxselecti0m(**
* MODULE: Mapping of the Rocq data-strustures into Caml and Caml extracted
* code. This includes initializing Caml variables based on Rocq terms, parsing
* various Rocq expressions into Caml, and dumping Caml expressions into Rocq.
*
* Opened here and in csdpcert.ml.
*)(**
* Initialization : a large amount of Caml symbols are derived from
* ZMicromega.v
*)letconstr_of_refstr=EConstr.of_constr(UnivGen.constr_of_monomorphic_global(Global.env())(Rocqlib.lib_refstr))letrocq_and=lazy(constr_of_ref"core.and.type")letrocq_or=lazy(constr_of_ref"core.or.type")letrocq_not=lazy(constr_of_ref"core.not.type")letrocq_iff=lazy(constr_of_ref"core.iff.type")letrocq_True=lazy(constr_of_ref"core.True.type")letrocq_False=lazy(constr_of_ref"core.False.type")letrocq_bool=lazy(constr_of_ref"core.bool.type")letrocq_true=lazy(constr_of_ref"core.bool.true")letrocq_false=lazy(constr_of_ref"core.bool.false")letrocq_andb=lazy(constr_of_ref"core.bool.andb")letrocq_orb=lazy(constr_of_ref"core.bool.orb")letrocq_implb=lazy(constr_of_ref"core.bool.implb")letrocq_eqb=lazy(constr_of_ref"core.bool.eqb")letrocq_negb=lazy(constr_of_ref"core.bool.negb")letrocq_cons=lazy(constr_of_ref"core.list.cons")letrocq_nil=lazy(constr_of_ref"core.list.nil")letrocq_list=lazy(constr_of_ref"core.list.type")letrocq_O=lazy(constr_of_ref"num.nat.O")letrocq_S=lazy(constr_of_ref"num.nat.S")letrocq_nat=lazy(constr_of_ref"num.nat.type")letrocq_unit=lazy(constr_of_ref"core.unit.type")(* let rocq_option = lazy (init_constant "option")*)letrocq_None=lazy(constr_of_ref"core.option.None")letrocq_tt=lazy(constr_of_ref"core.unit.tt")letrocq_Inl=lazy(constr_of_ref"core.sum.inl")letrocq_Inr=lazy(constr_of_ref"core.sum.inr")letrocq_N0=lazy(constr_of_ref"num.N.N0")letrocq_Npos=lazy(constr_of_ref"num.N.Npos")letrocq_xH=lazy(constr_of_ref"num.pos.xH")letrocq_xO=lazy(constr_of_ref"num.pos.xO")letrocq_xI=lazy(constr_of_ref"num.pos.xI")letrocq_Z=lazy(constr_of_ref"num.Z.type")letrocq_ZERO=lazy(constr_of_ref"num.Z.Z0")letrocq_POS=lazy(constr_of_ref"num.Z.Zpos")letrocq_NEG=lazy(constr_of_ref"num.Z.Zneg")letrocq_Q=lazy(constr_of_ref"rat.Q.type")letrocq_Qmake=lazy(constr_of_ref"rat.Q.Qmake")letrocq_R=lazy(constr_of_ref"reals.R.type")letrocq_Rcst=lazy(constr_of_ref"micromega.Rcst.type")letrocq_C0=lazy(constr_of_ref"micromega.Rcst.C0")letrocq_C1=lazy(constr_of_ref"micromega.Rcst.C1")letrocq_CQ=lazy(constr_of_ref"micromega.Rcst.CQ")letrocq_CZ=lazy(constr_of_ref"micromega.Rcst.CZ")letrocq_CPlus=lazy(constr_of_ref"micromega.Rcst.CPlus")letrocq_CMinus=lazy(constr_of_ref"micromega.Rcst.CMinus")letrocq_CMult=lazy(constr_of_ref"micromega.Rcst.CMult")letrocq_CPow=lazy(constr_of_ref"micromega.Rcst.CPow")letrocq_CInv=lazy(constr_of_ref"micromega.Rcst.CInv")letrocq_COpp=lazy(constr_of_ref"micromega.Rcst.COpp")letrocq_R0=lazy(constr_of_ref"reals.R.R0")letrocq_R1=lazy(constr_of_ref"reals.R.R1")letrocq_proofTerm=lazy(constr_of_ref"micromega.ZArithProof.type")letrocq_doneProof=lazy(constr_of_ref"micromega.ZArithProof.DoneProof")letrocq_ratProof=lazy(constr_of_ref"micromega.ZArithProof.RatProof")letrocq_cutProof=lazy(constr_of_ref"micromega.ZArithProof.CutProof")letrocq_splitProof=lazy(constr_of_ref"micromega.ZArithProof.SplitProof")letrocq_enumProof=lazy(constr_of_ref"micromega.ZArithProof.EnumProof")letrocq_ExProof=lazy(constr_of_ref"micromega.ZArithProof.ExProof")letrocq_IsProp=lazy(constr_of_ref"micromega.kind.isProp")letrocq_IsBool=lazy(constr_of_ref"micromega.kind.isBool")letrocq_Zgt=lazy(constr_of_ref"num.Z.gt")letrocq_Zge=lazy(constr_of_ref"num.Z.ge")letrocq_Zle=lazy(constr_of_ref"num.Z.le")letrocq_Zlt=lazy(constr_of_ref"num.Z.lt")letrocq_Zgtb=lazy(constr_of_ref"num.Z.gtb")letrocq_Zgeb=lazy(constr_of_ref"num.Z.geb")letrocq_Zleb=lazy(constr_of_ref"num.Z.leb")letrocq_Zltb=lazy(constr_of_ref"num.Z.ltb")letrocq_Zeqb=lazy(constr_of_ref"num.Z.eqb")letrocq_eq=lazy(constr_of_ref"core.eq.type")letrocq_Zplus=lazy(constr_of_ref"num.Z.add")letrocq_Zminus=lazy(constr_of_ref"num.Z.sub")letrocq_Zopp=lazy(constr_of_ref"num.Z.opp")letrocq_Zmult=lazy(constr_of_ref"num.Z.mul")letrocq_Zpower=lazy(constr_of_ref"num.Z.pow")letrocq_Qle=lazy(constr_of_ref"rat.Q.Qle")letrocq_Qlt=lazy(constr_of_ref"rat.Q.Qlt")letrocq_Qeq=lazy(constr_of_ref"rat.Q.Qeq")letrocq_Qplus=lazy(constr_of_ref"rat.Q.Qplus")letrocq_Qminus=lazy(constr_of_ref"rat.Q.Qminus")letrocq_Qopp=lazy(constr_of_ref"rat.Q.Qopp")letrocq_Qmult=lazy(constr_of_ref"rat.Q.Qmult")letrocq_Qpower=lazy(constr_of_ref"rat.Q.Qpower")letrocq_Rgt=lazy(constr_of_ref"reals.R.Rgt")letrocq_Rge=lazy(constr_of_ref"reals.R.Rge")letrocq_Rle=lazy(constr_of_ref"reals.R.Rle")letrocq_Rlt=lazy(constr_of_ref"reals.R.Rlt")letrocq_Rplus=lazy(constr_of_ref"reals.R.Rplus")letrocq_Rminus=lazy(constr_of_ref"reals.R.Rminus")letrocq_Ropp=lazy(constr_of_ref"reals.R.Ropp")letrocq_Rmult=lazy(constr_of_ref"reals.R.Rmult")letrocq_Rinv=lazy(constr_of_ref"reals.R.Rinv")letrocq_Rpower=lazy(constr_of_ref"reals.R.pow")letrocq_powerZR=lazy(constr_of_ref"reals.R.powerRZ")letrocq_IZR=lazy(constr_of_ref"reals.R.IZR")letrocq_IQR=lazy(constr_of_ref"reals.R.Q2R")letrocq_PEX=lazy(constr_of_ref"micromega.PExpr.PEX")letrocq_PEc=lazy(constr_of_ref"micromega.PExpr.PEc")letrocq_PEadd=lazy(constr_of_ref"micromega.PExpr.PEadd")letrocq_PEopp=lazy(constr_of_ref"micromega.PExpr.PEopp")letrocq_PEmul=lazy(constr_of_ref"micromega.PExpr.PEmul")letrocq_PEsub=lazy(constr_of_ref"micromega.PExpr.PEsub")letrocq_PEpow=lazy(constr_of_ref"micromega.PExpr.PEpow")letrocq_PX=lazy(constr_of_ref"micromega.Pol.PX")letrocq_Pc=lazy(constr_of_ref"micromega.Pol.Pc")letrocq_Pinj=lazy(constr_of_ref"micromega.Pol.Pinj")letrocq_OpEq=lazy(constr_of_ref"micromega.Op2.OpEq")letrocq_OpNEq=lazy(constr_of_ref"micromega.Op2.OpNEq")letrocq_OpLe=lazy(constr_of_ref"micromega.Op2.OpLe")letrocq_OpLt=lazy(constr_of_ref"micromega.Op2.OpLt")letrocq_OpGe=lazy(constr_of_ref"micromega.Op2.OpGe")letrocq_OpGt=lazy(constr_of_ref"micromega.Op2.OpGt")letrocq_PsatzLet=lazy(constr_of_ref"micromega.Psatz.PsatzLet")letrocq_PsatzIn=lazy(constr_of_ref"micromega.Psatz.PsatzIn")letrocq_PsatzSquare=lazy(constr_of_ref"micromega.Psatz.PsatzSquare")letrocq_PsatzMulE=lazy(constr_of_ref"micromega.Psatz.PsatzMulE")letrocq_PsatzMultC=lazy(constr_of_ref"micromega.Psatz.PsatzMulC")letrocq_PsatzAdd=lazy(constr_of_ref"micromega.Psatz.PsatzAdd")letrocq_PsatzC=lazy(constr_of_ref"micromega.Psatz.PsatzC")letrocq_PsatzZ=lazy(constr_of_ref"micromega.Psatz.PsatzZ")(* let rocq_GT = lazy (m_constant "GT")*)letrocq_DeclaredConstant=lazy(constr_of_ref"micromega.DeclaredConstant.type")letrocq_TT=lazy(constr_of_ref"micromega.GFormula.TT")letrocq_FF=lazy(constr_of_ref"micromega.GFormula.FF")letrocq_AND=lazy(constr_of_ref"micromega.GFormula.AND")letrocq_OR=lazy(constr_of_ref"micromega.GFormula.OR")letrocq_NOT=lazy(constr_of_ref"micromega.GFormula.NOT")letrocq_Atom=lazy(constr_of_ref"micromega.GFormula.A")letrocq_X=lazy(constr_of_ref"micromega.GFormula.X")letrocq_IMPL=lazy(constr_of_ref"micromega.GFormula.IMPL")letrocq_IFF=lazy(constr_of_ref"micromega.GFormula.IFF")letrocq_EQ=lazy(constr_of_ref"micromega.GFormula.EQ")letrocq_Formula=lazy(constr_of_ref"micromega.BFormula.type")letrocq_eKind=lazy(constr_of_ref"micromega.eKind")(**
* Initialization : a few Caml symbols are derived from other libraries;
* QMicromega, ZArithRing, RingMicromega.
*)letrocq_QWitness=lazy(constr_of_ref"micromega.QWitness.type")letrocq_Build=lazy(constr_of_ref"micromega.Formula.Build_Formula")letrocq_Cstr=lazy(constr_of_ref"micromega.Formula.type")(**
* Parsing and dumping : transformation functions between Caml and Rocq
* data-structures.
*
* dump_* functions go from Micromega to Rocq terms
* undump_* functions go from Rocq to Micromega terms (reverse of dump_)
* parse_* functions go from Rocq to Micromega terms
* pp_* functions pretty-print Rocq terms.
*)exceptionParseError(* A simple but useful getter function *)letget_left_constructsigmaterm=matchEConstr.kindsigmatermwith|Construct((_,i),_)->(i,[||])|App(l,rst)->(matchEConstr.kindsigmalwith|Construct((_,i),_)->(i,rst)|_->raiseParseError)|_->raiseParseError(* Access the Micromega module *)(* parse/dump/print from numbers up to expressions and formulas *)letrecparse_natsigmaterm=leti,c=get_left_constructsigmaterminmatchiwith|1->Mc.O|2->Mc.S(parse_natsigmac.(0))|i->raiseParseErrorletrecdump_natx=matchxwith|Mc.O->Lazy.forcerocq_O|Mc.Sp->EConstr.mkApp(Lazy.forcerocq_S,[|dump_natp|])letrecparse_positivesigmaterm=leti,c=get_left_constructsigmaterminmatchiwith|1->Mc.XI(parse_positivesigmac.(0))|2->Mc.XO(parse_positivesigmac.(0))|3->Mc.XH|i->raiseParseErrorletrecdump_positivex=matchxwith|Mc.XH->Lazy.forcerocq_xH|Mc.XOp->EConstr.mkApp(Lazy.forcerocq_xO,[|dump_positivep|])|Mc.XIp->EConstr.mkApp(Lazy.forcerocq_xI,[|dump_positivep|])letparse_nsigmaterm=leti,c=get_left_constructsigmaterminmatchiwith|1->Mc.N0|2->Mc.Npos(parse_positivesigmac.(0))|i->raiseParseErrorletdump_nx=matchxwith|Mc.N0->Lazy.forcerocq_N0|Mc.Nposp->EConstr.mkApp(Lazy.forcerocq_Npos,[|dump_positivep|])(** [is_ground_term env sigma term] holds if the term [term]
is an instance of the typeclass [DeclConstant.GT term]
i.e. built from user-defined constants and functions.
NB: This mechanism can be used to customise the reification process to decide
what to consider as a constant (see [parse_constant])
*)letis_declared_termenvevdt=matchEConstr.kindevdtwith|Const_|Construct_->((* Restrict typeclass resolution to trivial cases *)lettyp=Retyping.get_type_ofenvevdtintryignore(Class_tactics.resolve_one_typeclassenvevd(EConstr.mkApp(Lazy.forcerocq_DeclaredConstant,[|typ;t|])));truewithNot_found->false)|_->falseletrecis_ground_termenvevdterm=matchEConstr.kindevdtermwith|App(c,args)->is_declared_termenvevdc&&Array.for_all(is_ground_termenvevd)args|Const_|Construct_->is_declared_termenvevdterm|_->falseletparse_zsigmaterm=leti,c=get_left_constructsigmaterminmatchiwith|1->Mc.Z0|2->Mc.Zpos(parse_positivesigmac.(0))|3->Mc.Zneg(parse_positivesigmac.(0))|i->raiseParseErrorletdump_zx=matchxwith|Mc.Z0->Lazy.forcerocq_ZERO|Mc.Zposp->EConstr.mkApp(Lazy.forcerocq_POS,[|dump_positivep|])|Mc.Znegp->EConstr.mkApp(Lazy.forcerocq_NEG,[|dump_positivep|])letdump_qq=EConstr.mkApp(Lazy.forcerocq_Qmake,[|dump_zq.Micromega.qnum;dump_positiveq.Micromega.qden|])letparse_qsigmaterm=matchEConstr.kindsigmatermwith|App(c,args)->ifEConstr.eq_constrsigmac(Lazy.forcerocq_Qmake)then{Mc.qnum=parse_zsigmaargs.(0);Mc.qden=parse_positivesigmaargs.(1)}elseraiseParseError|_->raiseParseErrorletrecpp_Rcstocst=matchcstwith|Mc.C0->output_stringo"C0"|Mc.C1->output_stringo"C1"|Mc.CQq->output_stringo"CQ _"|Mc.CZz->pp_zoz|Mc.CPlus(x,y)->Printf.fprintfo"(%a + %a)"pp_Rcstxpp_Rcsty|Mc.CMinus(x,y)->Printf.fprintfo"(%a - %a)"pp_Rcstxpp_Rcsty|Mc.CMult(x,y)->Printf.fprintfo"(%a * %a)"pp_Rcstxpp_Rcsty|Mc.CPow(x,y)->Printf.fprintfo"(%a ^ _)"pp_Rcstx|Mc.CInvt->Printf.fprintfo"(/ %a)"pp_Rcstt|Mc.COppt->Printf.fprintfo"(- %a)"pp_Rcsttletrecdump_Rcstcst=matchcstwith|Mc.C0->Lazy.forcerocq_C0|Mc.C1->Lazy.forcerocq_C1|Mc.CQq->EConstr.mkApp(Lazy.forcerocq_CQ,[|dump_qq|])|Mc.CZz->EConstr.mkApp(Lazy.forcerocq_CZ,[|dump_zz|])|Mc.CPlus(x,y)->EConstr.mkApp(Lazy.forcerocq_CPlus,[|dump_Rcstx;dump_Rcsty|])|Mc.CMinus(x,y)->EConstr.mkApp(Lazy.forcerocq_CMinus,[|dump_Rcstx;dump_Rcsty|])|Mc.CMult(x,y)->EConstr.mkApp(Lazy.forcerocq_CMult,[|dump_Rcstx;dump_Rcsty|])|Mc.CPow(x,y)->EConstr.mkApp(Lazy.forcerocq_CPow,[|dump_Rcstx;(matchywith|Mc.Inlz->EConstr.mkApp(Lazy.forcerocq_Inl,[|Lazy.forcerocq_Z;Lazy.forcerocq_nat;dump_zz|])|Mc.Inrn->EConstr.mkApp(Lazy.forcerocq_Inr,[|Lazy.forcerocq_Z;Lazy.forcerocq_nat;dump_natn|]))|])|Mc.CInvt->EConstr.mkApp(Lazy.forcerocq_CInv,[|dump_Rcstt|])|Mc.COppt->EConstr.mkApp(Lazy.forcerocq_COpp,[|dump_Rcstt|])letrecdump_listtypdump_eltl=matchlwith|[]->EConstr.mkApp(Lazy.forcerocq_nil,[|typ|])|e::l->EConstr.mkApp(Lazy.forcerocq_cons,[|typ;dump_elte;dump_listtypdump_eltl|])letundump_var=parse_positiveletdump_var=dump_positiveletundump_exprundump_constantsigmae=letiscc'=EConstr.eq_constrsigmac(Lazy.forcec')inletrecxundumpe=matchEConstr.kindsigmaewith|App(c,[|_;n|])wheniscrocq_PEX->Mc.PEX(undump_varsigman)|App(c,[|_;z|])wheniscrocq_PEc->Mc.PEc(undump_constantsigmaz)|App(c,[|_;e1;e2|])wheniscrocq_PEadd->Mc.PEadd(xundumpe1,xundumpe2)|App(c,[|_;e1;e2|])wheniscrocq_PEsub->Mc.PEsub(xundumpe1,xundumpe2)|App(c,[|_;e|])wheniscrocq_PEopp->Mc.PEopp(xundumpe)|App(c,[|_;e1;e2|])wheniscrocq_PEmul->Mc.PEmul(xundumpe1,xundumpe2)|App(c,[|_;e;n|])wheniscrocq_PEpow->Mc.PEpow(xundumpe,parse_nsigman)|_->raiseParseErrorinxundumpeletdump_exprtypdump_ze=letrecdump_expre=matchewith|Mc.PEXn->EConstr.mkApp(Lazy.forcerocq_PEX,[|typ;dump_varn|])|Mc.PEcz->EConstr.mkApp(Lazy.forcerocq_PEc,[|typ;dump_zz|])|Mc.PEadd(e1,e2)->EConstr.mkApp(Lazy.forcerocq_PEadd,[|typ;dump_expre1;dump_expre2|])|Mc.PEsub(e1,e2)->EConstr.mkApp(Lazy.forcerocq_PEsub,[|typ;dump_expre1;dump_expre2|])|Mc.PEoppe->EConstr.mkApp(Lazy.forcerocq_PEopp,[|typ;dump_expre|])|Mc.PEmul(e1,e2)->EConstr.mkApp(Lazy.forcerocq_PEmul,[|typ;dump_expre1;dump_expre2|])|Mc.PEpow(e,n)->EConstr.mkApp(Lazy.forcerocq_PEpow,[|typ;dump_expre;dump_nn|])indump_expreletdump_poltypdump_ce=letrecdump_pole=matchewith|Mc.Pcn->EConstr.mkApp(Lazy.forcerocq_Pc,[|typ;dump_cn|])|Mc.Pinj(p,pol)->EConstr.mkApp(Lazy.forcerocq_Pinj,[|typ;dump_positivep;dump_polpol|])|Mc.PX(pol1,p,pol2)->EConstr.mkApp(Lazy.forcerocq_PX,[|typ;dump_polpol1;dump_positivep;dump_polpol2|])indump_pole(* let pp_clause pp_c o (f: 'cst clause) =
List.iter (fun ((p,_),(t,_)) -> Printf.fprintf o "(%a @%a)" (pp_pol pp_c) p Tag.pp t) f *)letpp_clause_tago(f:'cstclause)=List.iter(fun((p,_),(t,_))->Printf.fprintfo"(_ @%a)"Tag.ppt)f(* let pp_cnf pp_c o (f:'cst cnf) =
List.iter (fun l -> Printf.fprintf o "[%a]" (pp_clause pp_c) l) f *)letpp_cnf_tago(f:'cstcnf)=List.iter(funl->Printf.fprintfo"[%a]"pp_clause_tagl)fletdump_psatztypdump_ze=letz=Lazy.forcetypinletrecdump_conee=matchewith|Mc.PsatzLet(e1,e2)->EConstr.mkApp(Lazy.forcerocq_PsatzLet,[|z;dump_conee1;dump_conee2|])|Mc.PsatzInn->EConstr.mkApp(Lazy.forcerocq_PsatzIn,[|z;dump_natn|])|Mc.PsatzMulC(e,c)->EConstr.mkApp(Lazy.forcerocq_PsatzMultC,[|z;dump_polzdump_ze;dump_conec|])|Mc.PsatzSquaree->EConstr.mkApp(Lazy.forcerocq_PsatzSquare,[|z;dump_polzdump_ze|])|Mc.PsatzAdd(e1,e2)->EConstr.mkApp(Lazy.forcerocq_PsatzAdd,[|z;dump_conee1;dump_conee2|])|Mc.PsatzMulE(e1,e2)->EConstr.mkApp(Lazy.forcerocq_PsatzMulE,[|z;dump_conee1;dump_conee2|])|Mc.PsatzCp->EConstr.mkApp(Lazy.forcerocq_PsatzC,[|z;dump_zp|])|Mc.PsatzZ->EConstr.mkApp(Lazy.forcerocq_PsatzZ,[|z|])indump_coneeletundump_opsigmac=leti,c=get_left_constructsigmacinmatchiwith|1->Mc.OpEq|2->Mc.OpNEq|3->Mc.OpLe|4->Mc.OpGe|5->Mc.OpLt|6->Mc.OpGt|_->raiseParseErrorletdump_op=function|Mc.OpEq->Lazy.forcerocq_OpEq|Mc.OpNEq->Lazy.forcerocq_OpNEq|Mc.OpLe->Lazy.forcerocq_OpLe|Mc.OpGe->Lazy.forcerocq_OpGe|Mc.OpGt->Lazy.forcerocq_OpGt|Mc.OpLt->Lazy.forcerocq_OpLtletundump_cstrundump_constantsigmac=letiscc'=EConstr.eq_constrsigmac(Lazy.forcec')inmatchEConstr.kindsigmacwith|App(c,[|_;e1;o;e2|])wheniscrocq_Build->{Mc.flhs=undump_exprundump_constantsigmae1;Mc.fop=undump_opsigmao;Mc.frhs=undump_exprundump_constantsigmae2}|_->raiseParseErrorletdump_cstrtypdump_constant{Mc.flhs=e1;Mc.fop=o;Mc.frhs=e2}=EConstr.mkApp(Lazy.forcerocq_Build,[|typ;dump_exprtypdump_constante1;dump_opo;dump_exprtypdump_constante2|])letassoc_constsigmaxl=trysnd(List.find(fun(x',y)->EConstr.eq_constrsigmax(Lazy.forcex'))l)withNot_found->raiseParseErrorletzop_table_prop=[(rocq_Zgt,Mc.OpGt);(rocq_Zge,Mc.OpGe);(rocq_Zlt,Mc.OpLt);(rocq_Zle,Mc.OpLe)]letzop_table_bool=[(rocq_Zgtb,Mc.OpGt);(rocq_Zgeb,Mc.OpGe);(rocq_Zltb,Mc.OpLt);(rocq_Zleb,Mc.OpLe);(rocq_Zeqb,Mc.OpEq)]letrop_table_prop=[(rocq_Rgt,Mc.OpGt);(rocq_Rge,Mc.OpGe);(rocq_Rlt,Mc.OpLt);(rocq_Rle,Mc.OpLe)]letrop_table_bool=[]letqop_table_prop=[(rocq_Qlt,Mc.OpLt);(rocq_Qle,Mc.OpLe);(rocq_Qeq,Mc.OpEq)]letqop_table_bool=[]typegl=Environ.env*Evd.evar_mapletis_convertibleenvsigmat1t2=Reductionops.is_convenvsigmat1t2letparse_operatortable_proptable_boolhas_equalitytyp(env,sigma)k(op,args)=matchargswith|[|a1;a2|]->(assoc_constsigmaop(matchkwithMc.IsProp->table_prop|Mc.IsBool->table_bool),a1,a2)|[|ty;a1;a2|]->ifhas_equality&&EConstr.eq_constrsigmaop(Lazy.forcerocq_eq)&&is_convertibleenvsigmaty(Lazy.forcetyp)then(Mc.OpEq,args.(1),args.(2))elseraiseParseError|_->raiseParseErrorletparse_zop=parse_operatorzop_table_propzop_table_booltruerocq_Zletparse_rop=parse_operatorrop_table_prop[]truerocq_Rletparse_qop=parse_operatorqop_table_prop[]falserocq_Rtype'aop=|Binopof('aMc.pExpr->'aMc.pExpr->'aMc.pExpr)|Opp|Power|Uknofstringletassoc_opssigmaxl=trysnd(List.find(fun(x',y)->EConstr.eq_constrsigmax(Lazy.forcex'))l)withNot_found->Ukn"Oups"(**
* MODULE: Env is for environment.
*)moduleEnv=structtypet={vars:(EConstr.t*Mc.kind)list;(* The list represents a mapping from EConstr.t to indexes. *)gl:gl(* The evar_map may be updated due to unification of universes *)}letemptygl={vars=[];gl}(** [eq_constr gl x y] returns an updated [gl] if x and y can be unified *)leteq_constr(env,sigma)xy=matchEConstr.eq_constr_universes_projenvsigmaxywith|Somecsts->(letcsts=UnivProblem.Set.forcecstsinmatchEvd.add_universe_constraintssigmacstswith|sigma->Some(env,sigma)|exceptionUGraph.UniverseInconsistency_->None)|None->Noneletcompute_rank_addenvvis_prop=letrecaddglvarsnv=matchvarswith|[]->(gl,[(v,is_prop)],n)|(e,b)::l->(matcheq_constrglevwith|Somegl'->(gl',vars,n)|None->letgl,l',n=addgll(n+1)vin(gl,(e,b)::l',n))inletgl',vars',n=addenv.glenv.vars1vin({vars=vars';gl=gl'},CamlToCoq.positiven)letget_rankenvv=letgl=env.glinletrecget_rankenvn=matchenvwith|[]->raise(Invalid_argument"get_rank")|(e,_)::l->(matcheq_constrglevwithSome_->n|None->get_rankl(n+1))inget_rankenv.vars1letelementsenv=env.vars(* let string_of_env gl env =
let rec string_of_env i env acc =
match env with
| [] -> acc
| e::env -> string_of_env (i+1) env
(IMap.add i
(Pp.string_of_ppcmds
(Printer.pr_econstr_env gl.env gl.sigma e)) acc) in
string_of_env 1 env IMap.empty
*)letpp(genv,sigma)env=letppl=List.mapi(funi(e,_)->Pp.str"x"++Pp.int(i+1)++Pp.str":"++Printer.pr_econstr_envgenvsigmae)envinList.fold_right(funep->e++Pp.str" ; "++p)ppl(Pp.str"\n")end(* MODULE END: Env *)(**
* This is the big generic function for expression parsers.
*)letparse_expr(genv,sigma)parse_constantparse_expops_specenvterm=ifdebugthenFeedback.msg_debug(Pp.str"parse_expr: "++Printer.pr_leconstr_envgenvsigmaterm);letparse_variableenvterm=letenv,n=Env.compute_rank_addenvtermMc.IsBoolin(Mc.PEXn,env)inletrecparse_exprenvterm=letcombineenvop(t1,t2)=letexpr1,env=parse_exprenvt1inletexpr2,env=parse_exprenvt2in(opexpr1expr2,env)intry(Mc.PEc(parse_constant(genv,sigma)term),env)withParseError->(matchEConstr.kindsigmatermwith|App(t,args)->(matchEConstr.kindsigmatwith|Constc->(matchassoc_opssigmatops_specwith|Binopf->combineenvf(args.(0),args.(1))|Opp->letexpr,env=parse_exprenvargs.(0)in(Mc.PEoppexpr,env)|Power->(tryletexpr,env=parse_exprenvargs.(0)inletpower=parse_expexprargs.(1)in(power,env)withParseError->(* if the exponent is a variable *)letenv,n=Env.compute_rank_addenvtermMc.IsBoolin(Mc.PEXn,env))|Ukns->ifdebugthen(Printf.printf"unknown op: %s\n"s;flushstdout);letenv,n=Env.compute_rank_addenvtermMc.IsBoolin(Mc.PEXn,env))|_->parse_variableenvterm)|_->parse_variableenvterm)inparse_exprenvtermletzop_spec=[(rocq_Zplus,Binop(funxy->Mc.PEadd(x,y)));(rocq_Zminus,Binop(funxy->Mc.PEsub(x,y)));(rocq_Zmult,Binop(funxy->Mc.PEmul(x,y)));(rocq_Zopp,Opp);(rocq_Zpower,Power)]letqop_spec=[(rocq_Qplus,Binop(funxy->Mc.PEadd(x,y)));(rocq_Qminus,Binop(funxy->Mc.PEsub(x,y)));(rocq_Qmult,Binop(funxy->Mc.PEmul(x,y)));(rocq_Qopp,Opp);(rocq_Qpower,Power)]letrop_spec=[(rocq_Rplus,Binop(funxy->Mc.PEadd(x,y)));(rocq_Rminus,Binop(funxy->Mc.PEsub(x,y)));(rocq_Rmult,Binop(funxy->Mc.PEmul(x,y)));(rocq_Ropp,Opp);(rocq_Rpower,Power)]letparse_constantparse((genv:Environ.env),sigma)t=parsesigmat(** [parse_more_constant parse gl t] returns the reification of term [t].
If [t] is a ground term, then it is first reduced to normal form
before using a 'syntactic' parser *)letparse_more_constantparse(genv,sigma)t=tryparse(genv,sigma)twithParseError->ifdebugthenFeedback.msg_debugPp.(str"try harder");ifis_ground_termgenvsigmatthenparse(genv,sigma)(Redexpr.cbv_vmgenvsigmat)elseraiseParseErrorletzconstant=parse_constantparse_zletqconstant=parse_constantparse_qletnconstant=parse_constantparse_nat(** [parse_more_zexpr parse_constant gl] improves the parsing of exponent
which can be arithmetic expressions (without variables).
[parse_constant_expr] returns a constant if the argument is an expression without variables. *)letrecparse_zexprgl=parse_exprglzconstant(funexpr(x:EConstr.t)->letz=parse_zconstantglxinmatchzwith|Mc.Zneg_->Mc.PEcMc.Z0|_->Mc.PEpow(expr,Mc.Z.to_Nz))zop_specandparse_zconstantgle=lete,_=parse_zexprgl(Env.emptygl)einmatchMc.zeval_constewithNone->raiseParseError|Somez->z(* NB: R is a different story.
Because it is axiomatised, reducing would not be effective.
Therefore, there is a specific parser for constant over R
*)letrconst_assoc=[(rocq_Rplus,funxy->Mc.CPlus(x,y));(rocq_Rminus,funxy->Mc.CMinus(x,y));(rocq_Rmult,funxy->Mc.CMult(x,y))(* rocq_Rdiv , (fun x y -> Mc.CMult(x,Mc.CInv y)) ;*)]letrconstant(genv,sigma)term=letrecrconstantterm=matchEConstr.kindsigmatermwith|Constx->ifEConstr.eq_constrsigmaterm(Lazy.forcerocq_R0)thenMc.C0elseifEConstr.eq_constrsigmaterm(Lazy.forcerocq_R1)thenMc.C1elseraiseParseError|App(op,args)->(try(* the evaluation order is important in the following *)letf=assoc_constsigmaoprconst_associnleta=rconstantargs.(0)inletb=rconstantargs.(1)infabwithParseError->(matchopwith|opwhenEConstr.eq_constrsigmaop(Lazy.forcerocq_Rinv)->letarg=rconstantargs.(0)inifMc.qeq_bool(Mc.q_of_Rcstarg){Mc.qnum=Mc.Z0;Mc.qden=Mc.XH}thenraiseParseError(* This is a division by zero -- no semantics *)elseMc.CInvarg|opwhenEConstr.eq_constrsigmaop(Lazy.forcerocq_Rpower)->Mc.CPow(rconstantargs.(0),Mc.Inr(parse_more_constantnconstant(genv,sigma)args.(1)))|opwhenEConstr.eq_constrsigmaop(Lazy.forcerocq_IQR)->Mc.CQ(qconstant(genv,sigma)args.(0))|opwhenEConstr.eq_constrsigmaop(Lazy.forcerocq_IZR)->Mc.CZ(parse_more_constantzconstant(genv,sigma)args.(0))|_->raiseParseError))|_->raiseParseErrorinrconstanttermletrconstant(genv,sigma)term=ifdebugthenFeedback.msg_debug(Pp.str"rconstant: "++Printer.pr_leconstr_envgenvsigmaterm++fnl());letres=rconstant(genv,sigma)terminifdebugthen(Printf.printf"rconstant -> %a\n"pp_Rcstres;flushstdout);resletparse_qexprgl=parse_exprglqconstant(funexprx->letexp=zconstantglxinmatchexpwith|Mc.Zneg_->(matchexprwith|Mc.PEcq->Mc.PEc(Mc.qpowerqexp)|_->raiseParseError)|_->letexp=Mc.Z.to_NexpinMc.PEpow(expr,exp))qop_specletparse_rexpr(genv,sigma)=parse_expr(genv,sigma)rconstant(funexprx->letexp=Mc.N.of_nat(parse_natsigmax)inMc.PEpow(expr,exp))rop_specletparse_arithparse_opparse_expr(k:Mc.kind)envcstr(genv,sigma)=ifdebugthenFeedback.msg_debug(Pp.str"parse_arith: "++Printer.pr_leconstr_envgenvsigmacstr++fnl());matchEConstr.kindsigmacstrwith|App(op,args)->letop,lhs,rhs=parse_op(genv,sigma)k(op,args)inlete1,env=parse_expr(genv,sigma)envlhsinlete2,env=parse_expr(genv,sigma)envrhsin({Mc.flhs=e1;Mc.fop=op;Mc.frhs=e2},env)|_->failwith"error : parse_arith(2)"letparse_zarith=parse_arithparse_zopparse_zexprletparse_qarith=parse_arithparse_qopparse_qexprletparse_rarith=parse_arithparse_ropparse_rexpr(* generic parsing of arithmetic expressions *)letmkANDbf1f2=Mc.AND(b,f1,f2)letmkORbf1f2=Mc.OR(b,f1,f2)letmkIffbf1f2=Mc.IFF(b,f1,f2)letmkIMPLbf1f2=Mc.IMPL(b,f1,None,f2)letmkEQf1f2=Mc.EQ(f1,f2)letmkformula_binarybgtermf1f2=match(f1,f2)with|Mc.X(b1,_),Mc.X(b2,_)->Mc.X(b,term)|_->gf1f2(**
* This is the big generic function for formula parsers.
*)letis_propenvsigmaterm=letsort=Retyping.get_sort_ofenvsigmaterminEConstr.ESorts.is_propsigmasorttypeformula_op={op_impl:EConstr.toption(* only for booleans *);op_and:EConstr.t;op_or:EConstr.t;op_iff:EConstr.t;op_not:EConstr.t;op_tt:EConstr.t;op_ff:EConstr.t}letprop_op=lazy{op_impl=None(* implication is Prod *);op_and=Lazy.forcerocq_and;op_or=Lazy.forcerocq_or;op_iff=Lazy.forcerocq_iff;op_not=Lazy.forcerocq_not;op_tt=Lazy.forcerocq_True;op_ff=Lazy.forcerocq_False}letbool_op=lazy{op_impl=Some(Lazy.forcerocq_implb);op_and=Lazy.forcerocq_andb;op_or=Lazy.forcerocq_orb;op_iff=Lazy.forcerocq_eqb;op_not=Lazy.forcerocq_negb;op_tt=Lazy.forcerocq_true;op_ff=Lazy.forcerocq_false}letis_implbsigmalo=matchowithNone->false|Somec->EConstr.eq_constrsigmalcletparse_formula(genv,sigma)parse_atomenvtgterm=letparse_atombenvtgt=tryletat,env=parse_atombenvt(genv,sigma)in(Mc.A(b,at,(tg,t)),env,Tag.nexttg)withParseError->(Mc.X(b,t),env,tg)inletprop_op=Lazy.forceprop_opinletbool_op=Lazy.forcebool_opinleteq=Lazy.forcerocq_eqinletbool=Lazy.forcerocq_boolinletrecxparse_formulaopkenvtgterm=matchEConstr.kindsigmatermwith|App(l,rst)->(matchrstwith|[|a;b|]whenis_implbsigmalop.op_impl->letf,env,tg=xparse_formulaopkenvtgainletg,env,tg=xparse_formulaopkenvtgbin(mkformula_binaryk(mkIMPLk)termfg,env,tg)|[|a;b|]whenEConstr.eq_constrsigmalop.op_and->letf,env,tg=xparse_formulaopkenvtgainletg,env,tg=xparse_formulaopkenvtgbin(mkformula_binaryk(mkANDk)termfg,env,tg)|[|a;b|]whenEConstr.eq_constrsigmalop.op_or->letf,env,tg=xparse_formulaopkenvtgainletg,env,tg=xparse_formulaopkenvtgbin(mkformula_binaryk(mkORk)termfg,env,tg)|[|a;b|]whenEConstr.eq_constrsigmalop.op_iff->letf,env,tg=xparse_formulaopkenvtgainletg,env,tg=xparse_formulaopkenvtgbin(mkformula_binaryk(mkIffk)termfg,env,tg)|[|ty;a;b|]whenEConstr.eq_constrsigmaleq&&is_convertiblegenvsigmatybool->letf,env,tg=xparse_formulabool_opMc.IsBoolenvtgainletg,env,tg=xparse_formulabool_opMc.IsBoolenvtgbin(mkformula_binaryMc.IsPropmkEQtermfg,env,tg)|[|a|]whenEConstr.eq_constrsigmalop.op_not->letf,env,tg=xparse_formulaopkenvtgain(Mc.NOT(k,f),env,tg)|_->parse_atomkenvtgterm)|Prod(typ,a,b)whenkind_is_propk&&(typ.binder_name=Anonymous||EConstr.Vars.noccurnsigma1b)->letf,env,tg=xparse_formulaopkenvtgainletg,env,tg=xparse_formulaopkenvtgbin(mkformula_binaryMc.IsProp(mkIMPLMc.IsProp)termfg,env,tg)|_->ifEConstr.eq_constrsigmatermop.op_ttthen(Mc.TTk,env,tg)elseifEConstr.eq_constrsigmatermop.op_ffthenMc.(FFk,env,tg)else(Mc.X(k,term),env,tg)inxparse_formulaprop_opMc.IsPropenvtg(*Reductionops.whd_zeta*)term(* let dump_bool b = Lazy.force (if b then rocq_true else rocq_false)*)letundump_kindsigmak=ifEConstr.eq_constrsigmak(Lazy.forcerocq_IsProp)thenMc.IsPropelseMc.IsBoolletdump_kindk=Lazy.force(matchkwithMc.IsProp->rocq_IsProp|Mc.IsBool->rocq_IsBool)letundump_formulaundump_atomtgsigmaf=letiscc'=EConstr.eq_constrsigmac(Lazy.forcec')inletkindk=undump_kindsigmakinletrecxundumpf=matchEConstr.kindsigmafwith|App(c,[|_;_;_;_;k|])wheniscrocq_TT->Mc.TT(kindk)|App(c,[|_;_;_;_;k|])wheniscrocq_FF->Mc.FF(kindk)|App(c,[|_;_;_;_;k;f1;f2|])wheniscrocq_AND->Mc.AND(kindk,xundumpf1,xundumpf2)|App(c,[|_;_;_;_;k;f1;f2|])wheniscrocq_OR->Mc.OR(kindk,xundumpf1,xundumpf2)|App(c,[|_;_;_;_;k;f1;_;f2|])wheniscrocq_IMPL->Mc.IMPL(kindk,xundumpf1,None,xundumpf2)|App(c,[|_;_;_;_;k;f|])wheniscrocq_NOT->Mc.NOT(kindk,xundumpf)|App(c,[|_;_;_;_;k;f1;f2|])wheniscrocq_IFF->Mc.IFF(kindk,xundumpf1,xundumpf2)|App(c,[|_;_;_;_;f1;f2|])wheniscrocq_EQ->Mc.EQ(xundumpf1,xundumpf2)|App(c,[|_;_;_;_;k;x;_|])wheniscrocq_Atom->Mc.A(kindk,undump_atomsigmax,tg)|App(c,[|_;_;_;_;k;x|])wheniscrocq_X->Mc.X(kindk,x)|_->raiseParseErrorinxundumpfletdump_formulatypdump_atomf=letapp_ctorcargs=EConstr.mkApp(Lazy.forcec,Array.of_list(typ::Lazy.forcerocq_eKind::Lazy.forcerocq_unit::Lazy.forcerocq_unit::args))inletrecxdumpf=matchfwith|Mc.TTk->app_ctorrocq_TT[dump_kindk]|Mc.FFk->app_ctorrocq_FF[dump_kindk]|Mc.AND(k,x,y)->app_ctorrocq_AND[dump_kindk;xdumpx;xdumpy]|Mc.OR(k,x,y)->app_ctorrocq_OR[dump_kindk;xdumpx;xdumpy]|Mc.IMPL(k,x,_,y)->app_ctorrocq_IMPL[dump_kindk;xdumpx;EConstr.mkApp(Lazy.forcerocq_None,[|Lazy.forcerocq_unit|]);xdumpy]|Mc.NOT(k,x)->app_ctorrocq_NOT[dump_kindk;xdumpx]|Mc.IFF(k,x,y)->app_ctorrocq_IFF[dump_kindk;xdumpx;xdumpy]|Mc.EQ(x,y)->app_ctorrocq_EQ[xdumpx;xdumpy]|Mc.A(k,x,_)->app_ctorrocq_Atom[dump_kindk;dump_atomx;Lazy.forcerocq_tt]|Mc.X(k,t)->app_ctorrocq_X[dump_kindk;t]inxdumpfletprop_env_of_formulaglform=Mc.(letrecdoitenv=function|TT_|FF_|A(_,_,_)->env|X(b,t)->fst(Env.compute_rank_addenvtb)|AND(b,f1,f2)|OR(b,f1,f2)|IMPL(b,f1,_,f2)|IFF(b,f1,f2)->doit(doitenvf1)f2|NOT(b,f)->doitenvf|EQ(f1,f2)->doit(doitenvf1)f2indoit(Env.emptygl)form)letvar_env_of_formulaform=letrecvars_of_expr=function|Mc.PEXn->ISet.singleton(CoqToCaml.positiven)|Mc.PEcz->ISet.empty|Mc.PEadd(e1,e2)|Mc.PEmul(e1,e2)|Mc.PEsub(e1,e2)->ISet.union(vars_of_expre1)(vars_of_expre2)|Mc.PEoppe|Mc.PEpow(e,_)->vars_of_expreinletvars_of_atom{Mc.flhs;Mc.fop;Mc.frhs}=ISet.union(vars_of_exprflhs)(vars_of_exprfrhs)inMc.(letrecdoit=function|TT_|FF_|X_->ISet.empty|A(_,a,(t,c))->vars_of_atoma|AND(_,f1,f2)|OR(_,f1,f2)|IMPL(_,f1,_,f2)|IFF(_,f1,f2)|EQ(f1,f2)->ISet.union(doitf1)(doitf2)|NOT(_,f)->doitfindoitform)type'cstdump_expr={(* 'cst is the type of the syntactic constants *)interp_typ:EConstr.constr;dump_cst:'cst->EConstr.constr;dump_add:EConstr.constr;dump_sub:EConstr.constr;dump_opp:EConstr.constr;dump_mul:EConstr.constr;dump_pow:EConstr.constr;dump_pow_arg:Mc.n->EConstr.constr;dump_op_prop:(Mc.op2*EConstr.constr)list;dump_op_bool:(Mc.op2*EConstr.constr)list}letdump_zexpr=lazy{interp_typ=Lazy.forcerocq_Z;dump_cst=dump_z;dump_add=Lazy.forcerocq_Zplus;dump_sub=Lazy.forcerocq_Zminus;dump_opp=Lazy.forcerocq_Zopp;dump_mul=Lazy.forcerocq_Zmult;dump_pow=Lazy.forcerocq_Zpower;dump_pow_arg=(funn->dump_z(CamlToCoq.z(CoqToCaml.nn)));dump_op_prop=List.map(fun(x,y)->(y,Lazy.forcex))zop_table_prop;dump_op_bool=List.map(fun(x,y)->(y,Lazy.forcex))zop_table_bool}letdump_qexpr=lazy{interp_typ=Lazy.forcerocq_Q;dump_cst=dump_q;dump_add=Lazy.forcerocq_Qplus;dump_sub=Lazy.forcerocq_Qminus;dump_opp=Lazy.forcerocq_Qopp;dump_mul=Lazy.forcerocq_Qmult;dump_pow=Lazy.forcerocq_Qpower;dump_pow_arg=(funn->dump_z(CamlToCoq.z(CoqToCaml.nn)));dump_op_prop=List.map(fun(x,y)->(y,Lazy.forcex))qop_table_prop;dump_op_bool=List.map(fun(x,y)->(y,Lazy.forcex))qop_table_bool}letrecdump_Rcst_as_Rcst=matchcstwith|Mc.C0->Lazy.forcerocq_R0|Mc.C1->Lazy.forcerocq_R1|Mc.CQq->EConstr.mkApp(Lazy.forcerocq_IQR,[|dump_qq|])|Mc.CZz->EConstr.mkApp(Lazy.forcerocq_IZR,[|dump_zz|])|Mc.CPlus(x,y)->EConstr.mkApp(Lazy.forcerocq_Rplus,[|dump_Rcst_as_Rx;dump_Rcst_as_Ry|])|Mc.CMinus(x,y)->EConstr.mkApp(Lazy.forcerocq_Rminus,[|dump_Rcst_as_Rx;dump_Rcst_as_Ry|])|Mc.CMult(x,y)->EConstr.mkApp(Lazy.forcerocq_Rmult,[|dump_Rcst_as_Rx;dump_Rcst_as_Ry|])|Mc.CPow(x,y)->(matchywith|Mc.Inlz->EConstr.mkApp(Lazy.forcerocq_powerZR,[|dump_Rcst_as_Rx;dump_zz|])|Mc.Inrn->EConstr.mkApp(Lazy.forcerocq_Rpower,[|dump_Rcst_as_Rx;dump_natn|]))|Mc.CInvt->EConstr.mkApp(Lazy.forcerocq_Rinv,[|dump_Rcst_as_Rt|])|Mc.COppt->EConstr.mkApp(Lazy.forcerocq_Ropp,[|dump_Rcst_as_Rt|])letdump_rexpr=lazy{interp_typ=Lazy.forcerocq_R;dump_cst=dump_Rcst_as_R;dump_add=Lazy.forcerocq_Rplus;dump_sub=Lazy.forcerocq_Rminus;dump_opp=Lazy.forcerocq_Ropp;dump_mul=Lazy.forcerocq_Rmult;dump_pow=Lazy.forcerocq_Rpower;dump_pow_arg=(funn->dump_nat(CamlToCoq.nat(CoqToCaml.nn)));dump_op_prop=List.map(fun(x,y)->(y,Lazy.forcex))rop_table_prop;dump_op_bool=List.map(fun(x,y)->(y,Lazy.forcex))rop_table_bool}letprodnnenvb=letrecprodrec=function|0,env,b->b|n,(v,t)::l,b->prodrec(n-1,l,EConstr.mkProd(make_annotvERelevance.relevant,t,b))|_->assertfalseinprodrec(n,env,b)(** [make_goal_of_formula depxr vars props form] where
- vars is an environment for the arithmetic variables occurring in form
- props is an environment for the propositions occurring in form
@return a goal where all the variables and propositions of the formula are quantified
*)leteKind=function|Mc.IsProp->EConstr.mkProp|Mc.IsBool->Lazy.forcerocq_boolletmake_goal_of_formulagldexprform=letvars_idx=List.mapi(funiv->(v,i+1))(ISet.elements(var_env_of_formulaform))in(* List.iter (fun (v,i) -> Printf.fprintf stdout "var %i has index %i\n" v i) vars_idx ;*)letprops=prop_env_of_formulaglforminletfresh_varstri=Names.Id.of_string(str^string_of_inti)inletfresh_propstri=Names.Id.of_string(str^string_of_inti)inletvars_n=List.map(fun(_,i)->(fresh_var"__x"i,dexpr.interp_typ))vars_idxinletprops_n=List.mapi(funi(_,k)->(fresh_prop"__p"(i+1),eKindk))(Env.elementsprops)inletvar_name_pos=List.fold_left2(funacc(idx,_)(id,_)->(id,idx)::acc)[]vars_idxvars_ninletdump_exprie=letrecdump_expr=function|Mc.PEXn->EConstr.mkRel(i+List.assoc(CoqToCaml.positiven)vars_idx)|Mc.PEcz->dexpr.dump_cstz|Mc.PEadd(e1,e2)->EConstr.mkApp(dexpr.dump_add,[|dump_expre1;dump_expre2|])|Mc.PEsub(e1,e2)->EConstr.mkApp(dexpr.dump_sub,[|dump_expre1;dump_expre2|])|Mc.PEoppe->EConstr.mkApp(dexpr.dump_opp,[|dump_expre|])|Mc.PEmul(e1,e2)->EConstr.mkApp(dexpr.dump_mul,[|dump_expre1;dump_expre2|])|Mc.PEpow(e,n)->EConstr.mkApp(dexpr.dump_pow,[|dump_expre;dexpr.dump_pow_argn|])indump_expreinletmkop_propope1e2=tryEConstr.mkApp(List.assocopdexpr.dump_op_prop,[|e1;e2|])withNot_found->EConstr.mkApp(Lazy.forcerocq_eq,[|dexpr.interp_typ;e1;e2|])inletdump_cstr_propi{Mc.flhs;Mc.fop;Mc.frhs}=mkop_propfop(dump_expriflhs)(dump_exprifrhs)inletmkop_boolope1e2=tryEConstr.mkApp(List.assocopdexpr.dump_op_bool,[|e1;e2|])withNot_found->EConstr.mkApp(Lazy.forcerocq_eq,[|dexpr.interp_typ;e1;e2|])inletdump_cstr_booli{Mc.flhs;Mc.fop;Mc.frhs}=mkop_boolfop(dump_expriflhs)(dump_exprifrhs)inletrecxdump_proppixif=matchfwith|Mc.TT_->Lazy.forcerocq_True|Mc.FF_->Lazy.forcerocq_False|Mc.AND(_,x,y)->EConstr.mkApp(Lazy.forcerocq_and,[|xdump_proppixix;xdump_proppixiy|])|Mc.OR(_,x,y)->EConstr.mkApp(Lazy.forcerocq_or,[|xdump_proppixix;xdump_proppixiy|])|Mc.IFF(_,x,y)->EConstr.mkApp(Lazy.forcerocq_iff,[|xdump_proppixix;xdump_proppixiy|])|Mc.IMPL(_,x,_,y)->EConstr.mkArrow(xdump_proppixix)ERelevance.relevant(xdump_prop(pi+1)(xi+1)y)|Mc.NOT(_,x)->EConstr.mkArrow(xdump_proppixix)ERelevance.relevant(Lazy.forcerocq_False)|Mc.EQ(x,y)->EConstr.mkApp(Lazy.forcerocq_eq,[|Lazy.forcerocq_bool;xdump_boolpixix;xdump_boolpixiy|])|Mc.A(_,x,_)->dump_cstr_propxix|Mc.X(_,t)->letidx=Env.get_rankpropstinEConstr.mkRel(pi+idx)andxdump_boolpixif=matchfwith|Mc.TT_->Lazy.forcerocq_true|Mc.FF_->Lazy.forcerocq_false|Mc.AND(_,x,y)->EConstr.mkApp(Lazy.forcerocq_andb,[|xdump_boolpixix;xdump_boolpixiy|])|Mc.OR(_,x,y)->EConstr.mkApp(Lazy.forcerocq_orb,[|xdump_boolpixix;xdump_boolpixiy|])|Mc.IFF(_,x,y)->EConstr.mkApp(Lazy.forcerocq_eqb,[|xdump_boolpixix;xdump_boolpixiy|])|Mc.IMPL(_,x,_,y)->EConstr.mkApp(Lazy.forcerocq_implb,[|xdump_boolpixix;xdump_boolpixiy|])|Mc.NOT(_,x)->EConstr.mkApp(Lazy.forcerocq_negb,[|xdump_boolpixix|])|Mc.EQ(x,y)->assertfalse|Mc.A(_,x,_)->dump_cstr_boolxix|Mc.X(_,t)->letidx=Env.get_rankpropstinEConstr.mkRel(pi+idx)inletnb_vars=List.lengthvars_ninletnb_props=List.lengthprops_nin(* Printf.fprintf stdout "NBProps : %i\n" nb_props ;*)letsubst_propp=letidx=Env.get_rankpropspinEConstr.mkVar(Names.Id.of_string(Printf.sprintf"__p%i"idx))inletform'=Mc.mapX(fun_p->subst_propp)Mc.IsPropformin(prodnnb_props(List.map(fun(x,y)->(Name.Namex,y))props_n)(prodnnb_vars(List.map(fun(x,y)->(Name.Namex,y))vars_n)(xdump_prop(List.lengthvars_n)0form)),List.revprops_n,var_name_pos,form')(**
* Given a conclusion and a list of affectations, rebuild a term prefixed by
* the appropriate letins.
* TODO: reverse the list of bindings!
*)letsetsigmalconcl=letrecxsetacc=function|[]->acc|e::l->letname,expr,typ=einxset(EConstr.mkNamedLetInsigma(make_annot(Names.Id.of_stringname)ERelevance.relevant)exprtypacc)linxsetconcllletrocq_Branch=lazy(constr_of_ref"micromega.VarMap.Branch")letrocq_Elt=lazy(constr_of_ref"micromega.VarMap.Elt")letrocq_Empty=lazy(constr_of_ref"micromega.VarMap.Empty")letrocq_VarMap=lazy(constr_of_ref"micromega.VarMap.type")letrecdump_varmaptypm=matchmwith|Mc.Empty->EConstr.mkApp(Lazy.forcerocq_Empty,[|typ|])|Mc.Eltv->EConstr.mkApp(Lazy.forcerocq_Elt,[|typ;v|])|Mc.Branch(l,o,r)->EConstr.mkApp(Lazy.forcerocq_Branch,[|typ;dump_varmaptypl;o;dump_varmaptypr|])letvm_of_listenv=matchenvwith|[]->Mc.Empty|(d,_)::_->List.fold_left(funvm(c,i)->Mc.vm_addd(CamlToCoq.positivei)cvm)Mc.Emptyenvletrecdump_proof_term=function|Micromega.DoneProof->Lazy.forcerocq_doneProof|Micromega.RatProof(cone,rst)->EConstr.mkApp(Lazy.forcerocq_ratProof,[|dump_psatzrocq_Zdump_zcone;dump_proof_termrst|])|Micromega.CutProof(cone,prf)->EConstr.mkApp(Lazy.forcerocq_cutProof,[|dump_psatzrocq_Zdump_zcone;dump_proof_termprf|])|Micromega.SplitProof(p,prf1,prf2)->EConstr.mkApp(Lazy.forcerocq_splitProof,[|dump_pol(Lazy.forcerocq_Z)dump_zp;dump_proof_termprf1;dump_proof_termprf2|])|Micromega.EnumProof(c1,c2,prfs)->EConstr.mkApp(Lazy.forcerocq_enumProof,[|dump_psatzrocq_Zdump_zc1;dump_psatzrocq_Zdump_zc2;dump_list(Lazy.forcerocq_proofTerm)dump_proof_termprfs|])|Micromega.ExProof(p,prf)->EConstr.mkApp(Lazy.forcerocq_ExProof,[|dump_positivep;dump_proof_termprf|])letrecsize_of_psatz=function|Micromega.PsatzIn_->1|Micromega.PsatzSquare_->1|Micromega.PsatzMulC(_,p)->1+size_of_psatzp|Micromega.PsatzLet(p1,p2)|Micromega.PsatzMulE(p1,p2)|Micromega.PsatzAdd(p1,p2)->size_of_psatzp1+size_of_psatzp2|Micromega.PsatzC_->1|Micromega.PsatzZ->1letrecsize_of_pf=function|Micromega.DoneProof->1|Micromega.RatProof(p,a)->size_of_pfa+size_of_psatzp|Micromega.CutProof(p,a)->size_of_pfa+size_of_psatzp|Micromega.SplitProof(_,p1,p2)->size_of_pfp1+size_of_pfp2|Micromega.EnumProof(p1,p2,l)->size_of_psatzp1+size_of_psatzp2+List.fold_left(funaccp->size_of_pfp+acc)0l|Micromega.ExProof(_,a)->size_of_pfa+1letdump_proof_termt=ifdebugthenPrintf.printf"dump_proof_term %i\n"(size_of_pft);dump_proof_termtletpp_qoq=Printf.fprintfo"%a/%a"pp_zq.Micromega.qnumpp_positiveq.Micromega.qdenletrecparse_hyps(genv,sigma)parse_arithenvtg(hyps:(Names.Id.t*EConstr.types)list)=matchhypswith|[]->([],env,tg)|(i,t)::l->letlhyps,env,tg=parse_hyps(genv,sigma)parse_arithenvtglinifis_propgenvsigmatthentryletc,env,tg=parse_formula(genv,sigma)parse_arithenvtgtin((i,c)::lhyps,env,tg)withParseError->(lhyps,env,tg)else(lhyps,env,tg)letparse_goalglparse_arith(env:Env.t)(hyps:(Names.Id.t*EConstr.types)list)term=letf,env,tg=parse_formulaglparse_arithenv(Tag.from0)terminletlhyps,env,tg=parse_hypsglparse_arithenvtghypsin(lhyps,f,env)(**
* The datastructures that aggregate theory-dependent proof values.
*)type('synt_c,'prf)domain_spec={typ:EConstr.constr;(* is the type of the interpretation domain - Z, Q, R*)coeff:EConstr.constr;(* is the type of the syntactic coeffs - Z , Q , Rcst *)dump_coeff:'synt_c->EConstr.constr;undump_coeff:Evd.evar_map->EConstr.constr->'synt_c;proof_typ:EConstr.constr;dump_proof:'prf->EConstr.constr;coeff_eq:'synt_c->'synt_c->bool}letzz_domain_spec=lazy{typ=Lazy.forcerocq_Z;coeff=Lazy.forcerocq_Z;dump_coeff=dump_z;undump_coeff=parse_z;proof_typ=Lazy.forcerocq_proofTerm;dump_proof=dump_proof_term;coeff_eq=Mc.Z.eqb}letqq_domain_spec=lazy{typ=Lazy.forcerocq_Q;coeff=Lazy.forcerocq_Q;dump_coeff=dump_q;undump_coeff=parse_q;proof_typ=Lazy.forcerocq_QWitness;dump_proof=dump_psatzrocq_Qdump_q;coeff_eq=Mc.qeq_bool}letmax_tagf=1+Tag.to_int(Mc.foldA(funt1(t2,_)->Tag.maxt1t2)Mc.IsPropf(Tag.from0))(** Naive topological sort of constr according to the subterm-ordering *)(* An element is minimal x is minimal w.r.t y if
x <= y or (x and y are incomparable) *)(**
* Instantiate the current Rocq goal with a Micromega formula, a varmap, and a
* witness.
*)letmicromega_order_changespeccertcert_typenvff(*: unit Proofview.tactic*)=(* let ids = Util.List.map_i (fun i _ -> (Names.Id.of_string ("__v"^(string_of_int i)))) 0 env in *)letformula_typ=EConstr.mkApp(Lazy.forcerocq_Cstr,[|spec.coeff|])inletff=dump_formulaformula_typ(dump_cstrspec.coeffspec.dump_coeff)ffinletvm=dump_varmapspec.typ(vm_of_listenv)in(* todo : directly generate the proof term - or generalize before conversion? *)Proofview.Goal.enter(fungl->letsigma=Proofview.Goal.sigmaglinTacticals.tclTHENLIST[Tactics.change_concl(setsigma[("__ff",ff,EConstr.mkApp(Lazy.forcerocq_Formula,[|formula_typ;Lazy.forcerocq_IsProp|]));("__varmap",vm,EConstr.mkApp(Lazy.forcerocq_VarMap,[|spec.typ|]));("__wit",cert,cert_typ)](Tacmach.pf_conclgl))])(**
* The datastructures that aggregate prover attributes.
*)openCertificatetype('option,'a,'prf,'model)prover={name:string;(* name of the prover *)get_option:unit->'option;(* find the options of the prover *)prover:'option*'alist->('prf,'model)Certificate.res;(* the prover itself *)hyps:'prf->ISet.t;(* extract the indexes of the hypotheses really used in the proof *)compact:'prf->(int->int)->'prf;(* remap the hyp indexes according to function *)pp_prf:out_channel->'prf->unit;(* pretting printing of proof *)pp_f:out_channel->'a->unit(* pretty printing of the formulas (polynomials)*)}(**
* Given a prover and a disjunction of atoms, find a proof of any of
* the atoms. Returns an (optional) pair of a proof and a prover
* datastructure.
*)letfind_witnessppolys1=letpolys1=List.mapfstpolys1inp.prover(p.get_option(),polys1)(**
* Given a prover and a CNF, find a proof for each of the clauses.
* Return the proofs as a list.
*)letwitness_listproverl=letrecxwitness_liststackl=matchstackwith|[]->Prfl|e::stack->matchfind_witnessproverewith|Modelm->(Model(m,e))|Unknown->Unknown|Prfw->xwitness_liststack(w::l)inxwitness_list(List.revl)[](* let t1 = System.get_time () in
let res = witness_list p g in
let t2 = System.get_time () in
Feedback.msg_info Pp.(str "Witness generation "++int (List.length g) ++ str " "++System.fmt_time_difference t1 t2) ;
res
*)(**
* Prune the proof object, according to the 'diff' between two cnf formulas.
*)letcompact_proofsprover(eq_cst:'cst->'cst->bool)(cnf_ff:'cstcnf)res(cnf_ff':'cstcnf)=leteq_formula(p1,o1)(p2,o2)=letopenMutils.Hashineq_poleq_cstp1p2&&eq_op1o1o2inletcompact_proof(old_cl:'cstclause)prf(new_cl:'cstclause)=letnew_cl=List.mapi(funi(f,_)->(f,i))new_clinletremapi=letformula=tryfst(List.nthold_cli)withFailure_->failwith"bad old index"inCList.assoc_feq_formulaformulanew_clin(* if debug then
begin
Printf.printf "\ncompact_proof : %a %a %a"
(pp_ml_list prover.pp_f) (List.map fst old_cl)
prover.pp_prf prf
(pp_ml_list prover.pp_f) (List.map fst new_cl) ;
flush stdout
end ; *)letres=tryprover.compactprfremapwithxwhenCErrors.noncriticalx->(ifdebugthenPrintf.fprintfstdout"Proof compaction %s"(Printexc.to_stringx);(* This should not happen -- this is the recovery plan... *)matchprover.prover(prover.get_option(),List.mapfstnew_cl)with|Unknown|Model_->failwith"proof compaction error"|Prfp->p)inifdebugthenbeginPrintf.printf" -> %a\n"prover.pp_prfres;flushstdoutend;resinletis_proof_compatible(hyps,(old_cl:'cstclause),prf)(new_cl:'cstclause)=leteq(f1,(t1,e1))(f2,(t2,e2))=Int.equal(Tag.comparet1t2)0&&eq_formulaf1f2(* We do not have to compare [e1] with [e2] because [t1 = t2] ensures
by uid generation that they must be the same *)inis_sublisteq(Lazy.forcehyps)new_clinletmapaccclprf=lethyps=lazy(selecti(prover.hypsprf)cl)in(hyps,cl,prf)::accinletcnf_res=List.rev(List.fold_left2map[]cnf_ffres)in(* we get pairs clause * proof *)ifdebugthenbeginPrintf.printf"CNFRES\n";flushstdout;Printf.printf"CNFOLD %a\n"pp_cnf_tagcnf_ff;List.iter(fun(lazyhyps,cl,prf)->Printf.printf"\nProver %a -> %a\n"pp_clause_tagclpp_clause_taghyps;flushstdout)cnf_res;Printf.printf"CNFNEW %a\n"pp_cnf_tagcnf_ff'end;List.map(funx->let_,o,p=tryList.find(funp->is_proof_compatiblepx)cnf_reswithNot_found->Printf.printf"ERROR: no compatible proof";flushstdout;failwith"Cannot find compatible proof"incompact_proofopx)cnf_ff'(**
* "Hide out" tagged atoms of a formula by transforming them into generic
* variables. See the Tag module in mutils.ml for more.
*)letabstract_formula:TagSet.t->'aformula->'aformula=funhypsf->letto_constr=Mc.{mkTT=(letrocq_True=Lazy.forcerocq_Trueinletrocq_true=Lazy.forcerocq_trueinfunctionMc.IsProp->rocq_True|Mc.IsBool->rocq_true);mkFF=(letrocq_False=Lazy.forcerocq_Falseinletrocq_false=Lazy.forcerocq_falseinfunctionMc.IsProp->rocq_False|Mc.IsBool->rocq_false);mkA=(funka(tg,t)->t);mkAND=(letrocq_and=Lazy.forcerocq_andinletrocq_andb=Lazy.forcerocq_andbinfunkxy->EConstr.mkApp((matchkwithMc.IsProp->rocq_and|Mc.IsBool->rocq_andb),[|x;y|]));mkOR=(letrocq_or=Lazy.forcerocq_orinletrocq_orb=Lazy.forcerocq_orbinfunkxy->EConstr.mkApp((matchkwithMc.IsProp->rocq_or|Mc.IsBool->rocq_orb),[|x;y|]));mkIMPL=(funkxy->matchkwith|Mc.IsProp->EConstr.mkArrowxERelevance.relevanty|Mc.IsBool->EConstr.mkApp(Lazy.forcerocq_implb,[|x;y|]));mkIFF=(letrocq_iff=Lazy.forcerocq_iffinletrocq_eqb=Lazy.forcerocq_eqbinfunkxy->EConstr.mkApp((matchkwithMc.IsProp->rocq_iff|Mc.IsBool->rocq_eqb),[|x;y|]));mkNOT=(letrocq_not=Lazy.forcerocq_notinletrocq_negb=Lazy.forcerocq_negbinfunkx->EConstr.mkApp((matchkwithMc.IsProp->rocq_not|Mc.IsBool->rocq_negb),[|x|]));mkEQ=(letrocq_eq=Lazy.forcerocq_eqinfunxy->EConstr.mkApp(rocq_eq,[|Lazy.forcerocq_bool;x;y|]))}inMc.abst_formto_constr(fun(t,_)->TagSet.memthyps)trueMc.IsPropf(* [abstract_wrt_formula] is used in contexts whre f1 is already an abstraction of f2 *)letrecabstract_wrt_formulaf1f2=Mc.(match(f1,f2)with|X(b,c),_->X(b,c)|A_,A_->f2|AND(b,f1,f2),AND(_,f1',f2')->AND(b,abstract_wrt_formulaf1f1',abstract_wrt_formulaf2f2')|OR(b,f1,f2),OR(_,f1',f2')->OR(b,abstract_wrt_formulaf1f1',abstract_wrt_formulaf2f2')|IMPL(b,f1,_,f2),IMPL(_,f1',x,f2')->IMPL(b,abstract_wrt_formulaf1f1',x,abstract_wrt_formulaf2f2')|IFF(b,f1,f2),IFF(_,f1',f2')->IFF(b,abstract_wrt_formulaf1f1',abstract_wrt_formulaf2f2')|EQ(f1,f2),EQ(f1',f2')->EQ(abstract_wrt_formulaf1f1',abstract_wrt_formulaf2f2')|FFb,FF_->FFb|TTb,TT_->TTb|NOT(b,x),NOT(_,y)->NOT(b,abstract_wrt_formulaxy)|_->failwith"abstract_wrt_formula")(**
* This exception is raised by really_call_csdpcert if Rocq's configure didn't
* find a CSDP executable.
*)exceptionCsdpNotFoundletfail_csdp_not_found()=flushstdout;lets="Skipping the rest of this tactic: the complexity of the \
goal requires the use of an external tool called CSDP. \n\n\
However, the \"csdp\" binary is not present in the search path. \n\n\
Some OS distributions include CSDP (package \"coinor-csdp\" on Debian \
for instance). You can download binaries \
and source code from <https://github.com/coin-or/csdp>."inTacticals.tclFAIL(Pp.strs)(**
* This is the core of Micromega: apply the prover, analyze the result and
* prune unused fomulas, and finally modify the proof state.
*)letformula_hyps_conclhypsconcl=List.fold_right(fun(id,f)(cc,ids)->matchfwith|Mc.X_->(cc,ids)|_->(Mc.IMPL(Mc.IsProp,f,Someid,cc),id::ids))hyps(concl,[])(* let time str f x =
let t1 = System.get_time () in
let res = f x in
let t2 = System.get_time () in
Feedback.msg_info (Pp.str str ++ Pp.str " " ++ System.fmt_time_difference t1 t2) ;
res
*)letrecfold_tracefaccutr=letopenMicromegainmatchtrwith|Null->accu|Push(x,t)->fold_tracef(faccux)t|Merge(Null,t2)->fold_tracefaccut2|Merge(Push(x,t1),t2)->fold_tracef(faccux)(Merge(t1,t2))|Merge(Merge(t1,t2),t3)->fold_tracefaccu(Merge(t1,Merge(t2,t3)))letmicromega_tauto?(abstract=true)pre_processcnfspecprover(polys1:(Names.Id.t*'cstformula)list)(polys2:'cstformula)=(* Express the goal as one big implication *)letff,ids=formula_hyps_conclpolys1polys2inletmt=CamlToCoq.positive(max_tagff)in(* Construction of cnf *)letpre_ff=pre_processmt(ff:'aformula)inletcnf_ff,cnf_ff_tags=cnfMc.IsProppre_ffinmatchwitness_listprovercnf_ffwith|Modelm->Modelm|Unknown->Unknown|Prfres->(*Printf.printf "\nList %i" (List.length `res); *)letdeps=List.fold_left2(funsclprf->lettags=ISet.fold(funis->lett=fst(snd(List.nthcli))inifdebugthenPrintf.fprintfstdout"T : %i -> %a"iTag.ppt;(*try*)TagSet.addts(* with Invalid_argument _ -> s*))(prover.hypsprf)TagSet.emptyinTagSet.unionstags)(fold_trace(funs(i,_)->TagSet.addis)TagSet.emptycnf_ff_tags)cnf_ffresinletff'=ifabstractthenabstract_formuladepsffelseffinletpre_ff'=pre_processmtff'inletcnf_ff',_=cnfMc.IsProppre_ff'inifdebugthenbeginoutput_stringstdout"\n";Printf.printf"TForm : %a\n"pp_formulaff;flushstdout;Printf.printf"CNF : %a\n"pp_cnf_tagcnf_ff;flushstdout;Printf.printf"TFormAbs : %a\n"pp_formulaff';flushstdout;Printf.printf"TFormPre : %a\n"pp_formulapre_ff;flushstdout;Printf.printf"TFormPreAbs : %a\n"pp_formulapre_ff';flushstdout;Printf.printf"CNF : %a\n"pp_cnf_tagcnf_ff';flushstdoutend;(* Even if it does not work, this does not mean it is not provable
-- the prover is REALLY incomplete *)(* if debug then
begin
(* recompute the proofs *)
match witness_list_tags prover cnf_ff' with
| None -> failwith "abstraction is wrong"
| Some res -> ()
end ; *)letres'=compact_proofsproverspec.coeff_eqcnf_ffrescnf_ff'inletff',res',ids=(ff',res',Mc.ids_of_formulaMc.IsPropff')inletres'=dump_listspec.proof_typspec.dump_proofres'inifshow_used_hyps()thenFeedback.msg_infoPp.(str"Micromega used hypotheses: "++pr_enumNames.Id.printids);Prf(ids,ff',res')letmicromega_tauto?abstractpre_processcnfspecprover(polys1:(Names.Id.t*'cstformula)list)(polys2:'cstformula)=trymicromega_tauto?abstractpre_processcnfspecproverpolys1polys2withNot_found->Printexc.print_backtracestdout;flushstdout;Unknown(**
* Parse the proof environment, and call micromega_tauto
*)letfresh_idavoididgl=Tactics.fresh_id_in_envavoidid(Proofview.Goal.envgl)letclear_all_no_check=Proofview.Goal.enter(fungl->letconcl=Tacmach.pf_conclglinletenv=Environ.reset_with_named_contextEnviron.empty_named_context_val(Tacmach.pf_envgl)inRefine.refine_with_principal~typecheck:false(funsigma->letsigma,ev=Evarutil.new_evarenvsigmaconclinsigma,ev,Some(fst(EConstr.destEvarsigmaev))))letmicromega_genparse_arithpre_processcnfspecdumpexprprovertac=Proofview.Goal.enter(fungl->letsigma=Tacmach.projectglinletgenv=Tacmach.pf_envglinletconcl=Tacmach.pf_conclglinlethyps=Tacmach.pf_hyps_typesglintrylethyps,concl,env=parse_goal(genv,sigma)parse_arith(Env.empty(genv,sigma))hypsconclinletenv=Env.elementsenvinletspec=Lazy.forcespecinletdumpexpr=Lazy.forcedumpexprinifdebugthenFeedback.msg_debug(Pp.str"Env "++Env.pp(genv,sigma)env);matchmicromega_tautopre_processcnfspecproverhypsconclwith|Unknown->flushstdout;Tacticals.tclFAIL(Pp.str" Cannot find witness")|Model(m,e)->Tacticals.tclFAIL(Pp.str" Cannot find witness")|Prf(ids,ff',res')->letarith_goal,props,vars,ff_arith=make_goal_of_formula(genv,sigma)dumpexprff'inletintro(id,_)=Tactics.introductionidinletintro_vars=Tacticals.tclTHENLIST(List.mapintrovars)inletintro_props=Tacticals.tclTHENLIST(List.mapintroprops)in(* let ipat_of_name id = Some (CAst.make @@ IntroNaming (Namegen.IntroIdentifier id)) in*)letgoal_name=fresh_idId.Set.empty(Names.Id.of_string"__arith")glinletenv'=List.map(fun(id,i)->(EConstr.mkVarid,i))varsinlettac_arith=Tacticals.tclTHENLIST[clear_all_no_check;intro_props;intro_vars;micromega_order_changespecres'(EConstr.mkApp(Lazy.forcerocq_list,[|spec.proof_typ|]))env'ff_arith]inletgoal_props=List.rev(List.mapfst(Env.elements(prop_env_of_formula(genv,sigma)ff')))inletgoal_vars=List.map(fun(_,i)->fst(List.nthenv(i-1)))varsinletarith_args=goal_props@goal_varsinletkill_arith=Tacticals.tclTHENtac_arithtacin(*
(*tclABSTRACT fails in certain corner cases.*)
Tacticals.tclTHEN
clear_all_no_check
(Abstract.tclABSTRACT ~opaque:false None (Tacticals.tclTHEN tac_arith tac)) in *)Tacticals.tclTHEN(Tactics.assert_by(Names.Namegoal_name)arith_goal(*Proofview.tclTIME (Some "kill_arith")*)kill_arith)((*Proofview.tclTIME (Some "apply_arith") *)Tactics.exact_check(EConstr.applist(EConstr.mkVargoal_name,arith_args@List.mapEConstr.mkVarids)))with|CsdpNotFound->fail_csdp_not_found())letmicromega_wit_genpre_processcnfspecproverwit_idff=Proofview.Goal.enter(fungl->letsigma=Tacmach.projectglintryletspec=Lazy.forcespecinletundump_cstr=undump_cstrspec.undump_coeffinlettg=Tag.from0,Lazy.forcerocq_ttinletff=undump_formulaundump_cstrtgsigmaffinmatchmicromega_tauto~abstract:falsepre_processcnfspecprover[]ffwith|Unknown->flushstdout;Tacticals.tclFAIL(Pp.str" Cannot find witness")|Model(m,e)->Tacticals.tclFAIL(Pp.str" Cannot find witness")|Prf(_ids,_ff',res')->lettres'=EConstr.mkApp(Lazy.forcerocq_list,[|spec.proof_typ|])inTactics.letin_tacNone(Names.Namewit_id)res'(Sometres')Locusops.nowherewithCsdpNotFound->fail_csdp_not_found())letmicromega_order_changercertenvff=(*let ids = Util.List.map_i (fun i _ -> (Names.Id.of_string ("__v"^(string_of_int i)))) 0 env in *)letcoeff=Lazy.forcerocq_Rcstinletdump_coeff=dump_Rcstinlettyp=Lazy.forcerocq_Rinletcert_typ=EConstr.mkApp(Lazy.forcerocq_list,[|Lazy.forcerocq_QWitness|])inletformula_typ=EConstr.mkApp(Lazy.forcerocq_Cstr,[|coeff|])inletff=dump_formulaformula_typ(dump_cstrcoeffdump_coeff)ffinletvm=dump_varmaptyp(vm_of_listenv)inProofview.Goal.enter(fungl->letsigma=Proofview.Goal.sigmaglinTacticals.tclTHENLIST[Tactics.change_concl(setsigma[("__ff",ff,EConstr.mkApp(Lazy.forcerocq_Formula,[|formula_typ;Lazy.forcerocq_IsProp|]));("__varmap",vm,EConstr.mkApp(Lazy.forcerocq_VarMap,[|typ|]));("__wit",cert,cert_typ)](Tacmach.pf_conclgl))(* Tacticals.tclTHENLIST (List.map (fun id -> (Tactics.introduction id)) ids)*)])letmicromega_genrprovertac=letparse_arith=parse_rarithinletspec=lazy{typ=Lazy.forcerocq_R;coeff=Lazy.forcerocq_Rcst;dump_coeff=dump_q;undump_coeff=parse_q;proof_typ=Lazy.forcerocq_QWitness;dump_proof=dump_psatzrocq_Qdump_q;coeff_eq=Mc.qeq_bool}inProofview.Goal.enter(fungl->letsigma=Tacmach.projectglinletgenv=Tacmach.pf_envglinletconcl=Tacmach.pf_conclglinlethyps=Tacmach.pf_hyps_typesglintrylethyps,concl,env=parse_goal(genv,sigma)parse_arith(Env.empty(genv,sigma))hypsconclinletenv=Env.elementsenvinletspec=Lazy.forcespecinlethyps'=List.map(fun(n,f)->(n,Mc.map_bformulaMc.IsProp(Micromega.map_FormulaMicromega.q_of_Rcst)f))hypsinletconcl'=Mc.map_bformulaMc.IsProp(Micromega.map_FormulaMicromega.q_of_Rcst)conclinmatchmicromega_tauto(fun_x->x)Mc.cnfQspecproverhyps'concl'with|Unknown|Model_->flushstdout;Tacticals.tclFAIL(Pp.str" Cannot find witness")|Prf(ids,ff',res')->letff,ids=formula_hyps_concl(List.filter(fun(n,_)->CList.mem_fId.equalnids)hyps)conclinletff'=abstract_wrt_formulaff'ffinletarith_goal,props,vars,ff_arith=make_goal_of_formula(genv,sigma)(Lazy.forcedump_rexpr)ff'inletintro(id,_)=Tactics.introductionidinletintro_vars=Tacticals.tclTHENLIST(List.mapintrovars)inletintro_props=Tacticals.tclTHENLIST(List.mapintroprops)inletipat_of_nameid=Some(CAst.make@@IntroNaming(Namegen.IntroIdentifierid))inletgoal_name=fresh_idId.Set.empty(Names.Id.of_string"__arith")glinletenv'=List.map(fun(id,i)->(EConstr.mkVarid,i))varsinlettac_arith=Tacticals.tclTHENLIST[clear_all_no_check;intro_props;intro_vars;micromega_order_changerres'env'ff_arith]inletgoal_props=List.rev(List.mapfst(Env.elements(prop_env_of_formula(genv,sigma)ff')))inletgoal_vars=List.map(fun(_,i)->fst(List.nthenv(i-1)))varsinletarith_args=goal_props@goal_varsinletkill_arith=Tacticals.tclTHENtac_arithtacin(* Tacticals.tclTHEN
(Tactics.keep [])
(Tactics.tclABSTRACT None*)Tacticals.tclTHENS(Tactics.forwardtrue(SomeNone)(ipat_of_namegoal_name)arith_goal)[kill_arith;Tacticals.tclTHENLIST[Generalize.generalize(List.mapEConstr.mkVarids);Tactics.exact_check(EConstr.applist(EConstr.mkVargoal_name,arith_args))]]withCsdpNotFound->fail_csdp_not_found())letlift_ratproofproverl=matchproverlwith|Unknown|Model_->Unknown|Prfc->Prf(Mc.RatProof(c,Mc.DoneProof))typemicromega_polys=(Micromega.qMc.pol*Mc.op1)list[@@@ocaml.warning"-37"]typecsdp_certificate=SofSos_types.positivstellensatzoption|Fofstring(* Used to read the result of the execution of csdpcert *)typeprovername=string*intoption(**
* The caching mechanism.
*)moduleMakeCache(T:sigtypeprover_optiontypecoeffvalhash_prover_option:int->prover_option->intvalhash_coeff:int->coeff->intvaleq_prover_option:prover_option->prover_option->boolvaleq_coeff:coeff->coeff->boolend):sigtypekey=T.prover_option*(T.coeffMc.pol*Mc.op1)listvalmemo_opt:(unit->bool)->string->(key->'a)->key->'aend=structmoduleE=structtypet=T.prover_option*(T.coeffMc.pol*Mc.op1)listletequal=Hash.(eq_pairT.eq_prover_option(CList.equal(eq_pair(eq_polT.eq_coeff)Hash.eq_op1)))lethash=lethash_cstr=Hash.(hash_pair(hash_polT.hash_coeff)hash_op1)inHash.((hash_pairT.hash_prover_option(List.fold_lefthash_cstr))0)endincludePersistent_cache.PHashtable(E)letmemo_optuse_cachecache_filef=letmemof=memocache_filefinfunx->ifuse_cache()thenmemofxelsefxendmoduleCacheCsdp=MakeCache(structtypeprover_option=provernametypecoeff=Mc.qlethash_prover_option=Hash.(hash_pairhash_string(hash_elt(Option.hash(funx->x))))leteq_prover_option=Hash.(eq_pairString.equal(Option.equalInt.equal))lethash_coeff=Hash.hash_qleteq_coeff=Hash.eq_qend)(**
* Build the command to call csdpcert, and launch it. This in turn will call
* the sos driver to the csdp executable.
* Throw CsdpNotFound if Rocq isn't aware of any csdp executable.
*)letrequire_csdp=lazy(ifSystem.is_in_system_path"csdp"then()elseraiseCsdpNotFound)letreally_call_csdpcert:provername->micromega_polys->Sos_types.positivstellensatzoption=funprovernamepoly->Lazy.forcerequire_csdp;letcmdname=letenv=Boot.Env.init()inletplugin_dir=Boot.Env.pluginsenv|>Boot.Path.to_stringinList.fold_leftFilename.concatplugin_dir["micromega";"csdpcert"^Coq_config.exec_extension]inletcmdname=ifSys.file_existscmdnamethencmdnameelse"csdpcert"inmatch(commandcmdname[|cmdname|](provername,poly):csdp_certificate)with|Fstr->ifdebugthenPrintf.fprintfstdout"really_call_csdpcert : %s\n"str;raise(failwithstr)|Sres->res(**
* Check the cache before calling the prover.
*)letxcall_csdpcert=CacheCsdp.memo_optuse_csdp_cache".csdp.cache"(fun(prover,pb)->really_call_csdpcertproverpb)(**
* Prover callback functions.
*)letcall_csdpcertproverpb=xcall_csdpcert(prover,pb)letrecz_to_q_pole=matchewith|Mc.Pcz->Mc.Pc{Mc.qnum=z;Mc.qden=Mc.XH}|Mc.Pinj(p,pol)->Mc.Pinj(p,z_to_q_polpol)|Mc.PX(pol1,p,pol2)->Mc.PX(z_to_q_polpol1,p,z_to_q_polpol2)letcall_csdpcert_qprovernamepoly=matchcall_csdpcertprovernamepolywith|None->Unknown|Somecert->letcert=Certificate.q_cert_of_poscertinifMc.qWeakCheckerpolycertthenPrfcertelse(print_string"buggy certificate";Unknown)letcall_csdpcert_zprovernamepoly=letl=List.map(fun(e,o)->(z_to_q_pole,o))polyinmatchcall_csdpcertprovernamelwith|None->Unknown|Somecert->letcert=Certificate.z_cert_of_poscertinifMc.zWeakCheckerpolycertthenPrfcertelse(print_string"buggy certificate";flushstdout;Unknown)letrecxhyps_of_conebaseaccprf=matchprfwith|Mc.PsatzC_|Mc.PsatzZ|Mc.PsatzSquare_->acc|Mc.PsatzInn->letn=CoqToCaml.natninifn>=basethenISet.add(n-base)accelseacc|Mc.PsatzLet(e1,e2)->xhyps_of_cone(base+1)(xhyps_of_conebaseacce1)e2|Mc.PsatzMulC(_,c)->xhyps_of_conebaseaccc|Mc.PsatzAdd(e1,e2)|Mc.PsatzMulE(e1,e2)->xhyps_of_conebase(xhyps_of_conebaseacce2)e1lethyps_of_coneprf=xhyps_of_cone0ISet.emptyprflethyps_of_ptpt=letrecxhypsbaseptacc=matchptwith|Mc.DoneProof->acc|Mc.RatProof(c,pt)->xhyps(base+1)pt(xhyps_of_conebaseaccc)|Mc.CutProof(c,pt)->xhyps(base+1)pt(xhyps_of_conebaseaccc)|Mc.SplitProof(p,p1,p2)->xhyps(base+1)p1(xhyps(base+1)p2acc)|Mc.EnumProof(c1,c2,l)->lets=xhyps_of_conebase(xhyps_of_conebaseaccc2)c1inList.fold_left(funsx->xhyps(base+1)xs)sl|Mc.ExProof(_,pt)->xhyps(base+3)ptaccinxhyps0ptISet.emptyletcompact_coneprff=lettranslateofsetx=ifx<ofsetthenxelsef(x-ofset)+ofsetinletnpofsetn=CamlToCoq.nat(translateofset(CoqToCaml.natn))inletrecxinterpofsetprf=matchprfwith|Mc.PsatzC_|Mc.PsatzZ|Mc.PsatzSquare_->prf|Mc.PsatzInn->Mc.PsatzIn(npofsetn)|Mc.PsatzLet(e1,e2)->Mc.PsatzLet(xinterpofsete1,xinterp(ofset+1)e2)|Mc.PsatzMulC(e,c)->Mc.PsatzMulC(e,xinterpofsetc)|Mc.PsatzAdd(e1,e2)->Mc.PsatzAdd(xinterpofsete1,xinterpofsete2)|Mc.PsatzMulE(e1,e2)->Mc.PsatzMulE(xinterpofsete1,xinterpofsete2)inxinterp0prfletcompact_ptptf=lettranslateofsetx=ifx<ofsetthenxelsef(x-ofset)+ofsetinletreccompact_ptofsetpt=matchptwith|Mc.DoneProof->Mc.DoneProof|Mc.RatProof(c,pt)->Mc.RatProof(compact_conec(translateofset),compact_pt(ofset+1)pt)|Mc.CutProof(c,pt)->Mc.CutProof(compact_conec(translateofset),compact_pt(ofset+1)pt)|Mc.SplitProof(p,p1,p2)->Mc.SplitProof(p,compact_pt(ofset+1)p1,compact_pt(ofset+1)p2)|Mc.EnumProof(c1,c2,l)->Mc.EnumProof(compact_conec1(translateofset),compact_conec2(translateofset),Mc.map(funx->compact_pt(ofset+1)x)l)|Mc.ExProof(x,pt)->Mc.ExProof(x,compact_pt(ofset+3)pt)incompact_pt0pt(**
* Definition of provers.
* Instantiates the type ('a,'prf) prover defined above.
*)letlift_pexpr_proverpl=p(List.map(fun(e,o)->(Mc.denorme,o))l)moduleCacheZ=MakeCache(structtypeprover_option=bool*bool*inttypecoeff=Mc.zlethash_prover_option:int->prover_option->int=Hash.hash_eltHashtbl.hashleteq_prover_option:prover_option->prover_option->bool=(=)leteq_coeff=Hash.eq_zlethash_coeff=Hash.hash_zend)moduleCacheQ=MakeCache(structtypeprover_option=inttypecoeff=Mc.qlethash_prover_option:int->int->int=Hash.hash_eltHashtbl.hashleteq_prover_option=Int.equalleteq_coeff=Hash.eq_qlethash_coeff=Hash.hash_qend)letmemo_lia=CacheZ.memo_optuse_lia_cache".lia.cache"(fun((_,_,b),s)->lift_pexpr_prover(Certificate.liab)s)letmemo_nlia=CacheZ.memo_optuse_nia_cache".nia.cache"(fun((_,_,b),s)->lift_pexpr_prover(Certificate.nliab)s)letmemo_nra=CacheQ.memo_optuse_nra_cache".nra.cache"(fun(o,s)->lift_pexpr_prover(Certificate.nlinear_provero)s)letlinear_prover_Q={name="linear prover";get_option=lra_proof_depth;prover=(fun(o,l)->lift_pexpr_prover(Certificate.linear_prover_with_certo)l);hyps=hyps_of_cone;compact=compact_cone;pp_prf=pp_psatzpp_q;pp_f=(funox->pp_polpp_qo(fstx))}letlinear_prover_R={name="linear prover";get_option=lra_proof_depth;prover=(fun(o,l)->lift_pexpr_prover(Certificate.linear_prover_with_certo)l);hyps=hyps_of_cone;compact=compact_cone;pp_prf=pp_psatzpp_q;pp_f=(funox->pp_polpp_qo(fstx))}letnlinear_prover_R={name="nra";get_option=lra_proof_depth;prover=memo_nra;hyps=hyps_of_cone;compact=compact_cone;pp_prf=pp_psatzpp_q;pp_f=(funox->pp_polpp_qo(fstx))}letnon_linear_prover_Qstro={name="real nonlinear prover";get_option=(fun()->(str,o));prover=(fun(o,l)->call_csdpcert_qol);hyps=hyps_of_cone;compact=compact_cone;pp_prf=pp_psatzpp_q;pp_f=(funox->pp_polpp_qo(fstx))}letnon_linear_prover_Rstro={name="real nonlinear prover";get_option=(fun()->(str,o));prover=(fun(o,l)->call_csdpcert_qol);hyps=hyps_of_cone;compact=compact_cone;pp_prf=pp_psatzpp_q;pp_f=(funox->pp_polpp_qo(fstx))}letnon_linear_prover_Zstro={name="real nonlinear prover";get_option=(fun()->(str,o));prover=(fun(o,l)->lift_ratproof(call_csdpcert_zo)l);hyps=hyps_of_pt;compact=compact_pt;pp_prf=pp_proof_term;pp_f=(funox->pp_polpp_zo(fstx))}letlinear_Z={name="lia";get_option=get_lia_option;prover=memo_lia;hyps=hyps_of_pt;compact=compact_pt;pp_prf=pp_proof_term;pp_f=(funox->pp_polpp_zo(fstx))}letnlinear_Z={name="nlia";get_option=get_lia_option;prover=memo_nlia;hyps=hyps_of_pt;compact=compact_pt;pp_prf=pp_proof_term;pp_f=(funox->pp_polpp_zo(fstx))}(**
* Functions instantiating micromega_gen with the appropriate theories and
* solvers
*)letexfalso_if_concl_not_Prop=Proofview.Goal.enter(fungl->Tacmach.(ifis_prop(pf_envgl)(projectgl)(pf_conclgl)thenTacticals.tclIDTACelseTactics.exfalso))letmicromega_genparse_arithpre_processcnfspecdumpexprprovertac=Tacticals.tclTHENexfalso_if_concl_not_Prop(micromega_genparse_arithpre_processcnfspecdumpexprprovertac)letmicromega_genrprovertac=Tacticals.tclTHENexfalso_if_concl_not_Prop(micromega_genrprovertac)letxlra_Q=micromega_genparse_qarith(fun_x->x)Mc.cnfQqq_domain_specdump_qexprlinear_prover_Qletwlra_Q=micromega_wit_gen(fun_x->x)Mc.cnfQqq_domain_speclinear_prover_Qletxlra_R=micromega_genrlinear_prover_Rletxlia=micromega_genparse_zarith(fun_x->x)Mc.cnfZzz_domain_specdump_zexprlinear_Zletwlia=micromega_wit_gen(fun_x->x)Mc.cnfZzz_domain_speclinear_Zletxnra_Q=micromega_genparse_qarith(fun_x->x)Mc.cnfQqq_domain_specdump_qexprnlinear_prover_Rletwnra_Q=micromega_wit_gen(fun_x->x)Mc.cnfQqq_domain_specnlinear_prover_Rletxnra_R=micromega_genrnlinear_prover_Rletxnia=micromega_genparse_zarith(fun_x->x)Mc.cnfZzz_domain_specdump_zexprnlinear_Zletwnia=micromega_wit_gen(fun_x->x)Mc.cnfZzz_domain_specnlinear_Zletxsos_Q=micromega_genparse_qarith(fun_x->x)Mc.cnfQqq_domain_specdump_qexpr(non_linear_prover_Q"pure_sos"None)letwsos_Q=micromega_wit_gen(fun_x->x)Mc.cnfQqq_domain_spec(non_linear_prover_Q"pure_sos"None)letxsos_R=micromega_genr(non_linear_prover_R"pure_sos"None)letxsos_Z=micromega_genparse_zarith(fun_x->x)Mc.cnfZzz_domain_specdump_zexpr(non_linear_prover_Z"pure_sos"None)letwsos_Z=micromega_wit_gen(fun_x->x)Mc.cnfZzz_domain_spec(non_linear_prover_Z"pure_sos"None)letxpsatz_Qi=micromega_genparse_qarith(fun_x->x)Mc.cnfQqq_domain_specdump_qexpr(non_linear_prover_Q"real_nonlinear_prover"(Somei))letwpsatz_Qi=micromega_wit_gen(fun_x->x)Mc.cnfQqq_domain_spec(non_linear_prover_Q"real_nonlinear_prover"(Somei))letxpsatz_Ri=micromega_genr(non_linear_prover_R"real_nonlinear_prover"(Somei))letxpsatz_Zi=micromega_genparse_zarith(fun_x->x)Mc.cnfZzz_domain_specdump_zexpr(non_linear_prover_Z"real_nonlinear_prover"(Somei))letwpsatz_Zi=micromega_wit_gen(fun_x->x)Mc.cnfZzz_domain_spec(non_linear_prover_Z"real_nonlinear_prover"(Somei))letprint_lia_profile()=Simplex.(let{number_of_successes;number_of_failures;success_pivots;failure_pivots;average_pivots;maximum_pivots}=Simplex.get_profile_info()inFeedback.msg_noticePp.((* successes *)str"number of successes: "++intnumber_of_successes++fnl()(* success pivots *)++str"number of success pivots: "++intsuccess_pivots++fnl()(* failure *)++str"number of failures: "++intnumber_of_failures++fnl()(* failure pivots *)++str"number of failure pivots: "++intfailure_pivots++fnl()(* Other *)++str"average number of pivots: "++intaverage_pivots++fnl()++str"maximum number of pivots: "++intmaximum_pivots++fnl()))(* Local Variables: *)(* coding: utf-8 *)(* End: *)