123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592(************************************************************************)(* * 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) *)(************************************************************************)(* *)(* 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()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 Coq data-strustures into Caml and Caml extracted
* code. This includes initializing Caml variables based on Coq terms, parsing
* various Coq expressions into Caml, and dumping Caml expressions into Coq.
*
* 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())(Coqlib.lib_refstr))letcoq_and=lazy(constr_of_ref"core.and.type")letcoq_or=lazy(constr_of_ref"core.or.type")letcoq_not=lazy(constr_of_ref"core.not.type")letcoq_iff=lazy(constr_of_ref"core.iff.type")letcoq_True=lazy(constr_of_ref"core.True.type")letcoq_False=lazy(constr_of_ref"core.False.type")letcoq_bool=lazy(constr_of_ref"core.bool.type")letcoq_true=lazy(constr_of_ref"core.bool.true")letcoq_false=lazy(constr_of_ref"core.bool.false")letcoq_andb=lazy(constr_of_ref"core.bool.andb")letcoq_orb=lazy(constr_of_ref"core.bool.orb")letcoq_implb=lazy(constr_of_ref"core.bool.implb")letcoq_eqb=lazy(constr_of_ref"core.bool.eqb")letcoq_negb=lazy(constr_of_ref"core.bool.negb")letcoq_cons=lazy(constr_of_ref"core.list.cons")letcoq_nil=lazy(constr_of_ref"core.list.nil")letcoq_list=lazy(constr_of_ref"core.list.type")letcoq_O=lazy(constr_of_ref"num.nat.O")letcoq_S=lazy(constr_of_ref"num.nat.S")letcoq_nat=lazy(constr_of_ref"num.nat.type")letcoq_unit=lazy(constr_of_ref"core.unit.type")(* let coq_option = lazy (init_constant "option")*)letcoq_None=lazy(constr_of_ref"core.option.None")letcoq_tt=lazy(constr_of_ref"core.unit.tt")letcoq_Inl=lazy(constr_of_ref"core.sum.inl")letcoq_Inr=lazy(constr_of_ref"core.sum.inr")letcoq_N0=lazy(constr_of_ref"num.N.N0")letcoq_Npos=lazy(constr_of_ref"num.N.Npos")letcoq_xH=lazy(constr_of_ref"num.pos.xH")letcoq_xO=lazy(constr_of_ref"num.pos.xO")letcoq_xI=lazy(constr_of_ref"num.pos.xI")letcoq_Z=lazy(constr_of_ref"num.Z.type")letcoq_ZERO=lazy(constr_of_ref"num.Z.Z0")letcoq_POS=lazy(constr_of_ref"num.Z.Zpos")letcoq_NEG=lazy(constr_of_ref"num.Z.Zneg")letcoq_Q=lazy(constr_of_ref"rat.Q.type")letcoq_Qmake=lazy(constr_of_ref"rat.Q.Qmake")letcoq_R=lazy(constr_of_ref"reals.R.type")letcoq_Rcst=lazy(constr_of_ref"micromega.Rcst.type")letcoq_C0=lazy(constr_of_ref"micromega.Rcst.C0")letcoq_C1=lazy(constr_of_ref"micromega.Rcst.C1")letcoq_CQ=lazy(constr_of_ref"micromega.Rcst.CQ")letcoq_CZ=lazy(constr_of_ref"micromega.Rcst.CZ")letcoq_CPlus=lazy(constr_of_ref"micromega.Rcst.CPlus")letcoq_CMinus=lazy(constr_of_ref"micromega.Rcst.CMinus")letcoq_CMult=lazy(constr_of_ref"micromega.Rcst.CMult")letcoq_CPow=lazy(constr_of_ref"micromega.Rcst.CPow")letcoq_CInv=lazy(constr_of_ref"micromega.Rcst.CInv")letcoq_COpp=lazy(constr_of_ref"micromega.Rcst.COpp")letcoq_R0=lazy(constr_of_ref"reals.R.R0")letcoq_R1=lazy(constr_of_ref"reals.R.R1")letcoq_proofTerm=lazy(constr_of_ref"micromega.ZArithProof.type")letcoq_doneProof=lazy(constr_of_ref"micromega.ZArithProof.DoneProof")letcoq_ratProof=lazy(constr_of_ref"micromega.ZArithProof.RatProof")letcoq_cutProof=lazy(constr_of_ref"micromega.ZArithProof.CutProof")letcoq_splitProof=lazy(constr_of_ref"micromega.ZArithProof.SplitProof")letcoq_enumProof=lazy(constr_of_ref"micromega.ZArithProof.EnumProof")letcoq_ExProof=lazy(constr_of_ref"micromega.ZArithProof.ExProof")letcoq_IsProp=lazy(constr_of_ref"micromega.kind.isProp")letcoq_IsBool=lazy(constr_of_ref"micromega.kind.isBool")letcoq_Zgt=lazy(constr_of_ref"num.Z.gt")letcoq_Zge=lazy(constr_of_ref"num.Z.ge")letcoq_Zle=lazy(constr_of_ref"num.Z.le")letcoq_Zlt=lazy(constr_of_ref"num.Z.lt")letcoq_Zgtb=lazy(constr_of_ref"num.Z.gtb")letcoq_Zgeb=lazy(constr_of_ref"num.Z.geb")letcoq_Zleb=lazy(constr_of_ref"num.Z.leb")letcoq_Zltb=lazy(constr_of_ref"num.Z.ltb")letcoq_Zeqb=lazy(constr_of_ref"num.Z.eqb")letcoq_eq=lazy(constr_of_ref"core.eq.type")letcoq_Zplus=lazy(constr_of_ref"num.Z.add")letcoq_Zminus=lazy(constr_of_ref"num.Z.sub")letcoq_Zopp=lazy(constr_of_ref"num.Z.opp")letcoq_Zmult=lazy(constr_of_ref"num.Z.mul")letcoq_Zpower=lazy(constr_of_ref"num.Z.pow")letcoq_Qle=lazy(constr_of_ref"rat.Q.Qle")letcoq_Qlt=lazy(constr_of_ref"rat.Q.Qlt")letcoq_Qeq=lazy(constr_of_ref"rat.Q.Qeq")letcoq_Qplus=lazy(constr_of_ref"rat.Q.Qplus")letcoq_Qminus=lazy(constr_of_ref"rat.Q.Qminus")letcoq_Qopp=lazy(constr_of_ref"rat.Q.Qopp")letcoq_Qmult=lazy(constr_of_ref"rat.Q.Qmult")letcoq_Qpower=lazy(constr_of_ref"rat.Q.Qpower")letcoq_Rgt=lazy(constr_of_ref"reals.R.Rgt")letcoq_Rge=lazy(constr_of_ref"reals.R.Rge")letcoq_Rle=lazy(constr_of_ref"reals.R.Rle")letcoq_Rlt=lazy(constr_of_ref"reals.R.Rlt")letcoq_Rplus=lazy(constr_of_ref"reals.R.Rplus")letcoq_Rminus=lazy(constr_of_ref"reals.R.Rminus")letcoq_Ropp=lazy(constr_of_ref"reals.R.Ropp")letcoq_Rmult=lazy(constr_of_ref"reals.R.Rmult")letcoq_Rinv=lazy(constr_of_ref"reals.R.Rinv")letcoq_Rpower=lazy(constr_of_ref"reals.R.pow")letcoq_powerZR=lazy(constr_of_ref"reals.R.powerRZ")letcoq_IZR=lazy(constr_of_ref"reals.R.IZR")letcoq_IQR=lazy(constr_of_ref"reals.R.Q2R")letcoq_PEX=lazy(constr_of_ref"micromega.PExpr.PEX")letcoq_PEc=lazy(constr_of_ref"micromega.PExpr.PEc")letcoq_PEadd=lazy(constr_of_ref"micromega.PExpr.PEadd")letcoq_PEopp=lazy(constr_of_ref"micromega.PExpr.PEopp")letcoq_PEmul=lazy(constr_of_ref"micromega.PExpr.PEmul")letcoq_PEsub=lazy(constr_of_ref"micromega.PExpr.PEsub")letcoq_PEpow=lazy(constr_of_ref"micromega.PExpr.PEpow")letcoq_PX=lazy(constr_of_ref"micromega.Pol.PX")letcoq_Pc=lazy(constr_of_ref"micromega.Pol.Pc")letcoq_Pinj=lazy(constr_of_ref"micromega.Pol.Pinj")letcoq_OpEq=lazy(constr_of_ref"micromega.Op2.OpEq")letcoq_OpNEq=lazy(constr_of_ref"micromega.Op2.OpNEq")letcoq_OpLe=lazy(constr_of_ref"micromega.Op2.OpLe")letcoq_OpLt=lazy(constr_of_ref"micromega.Op2.OpLt")letcoq_OpGe=lazy(constr_of_ref"micromega.Op2.OpGe")letcoq_OpGt=lazy(constr_of_ref"micromega.Op2.OpGt")letcoq_PsatzLet=lazy(constr_of_ref"micromega.Psatz.PsatzLet")letcoq_PsatzIn=lazy(constr_of_ref"micromega.Psatz.PsatzIn")letcoq_PsatzSquare=lazy(constr_of_ref"micromega.Psatz.PsatzSquare")letcoq_PsatzMulE=lazy(constr_of_ref"micromega.Psatz.PsatzMulE")letcoq_PsatzMultC=lazy(constr_of_ref"micromega.Psatz.PsatzMulC")letcoq_PsatzAdd=lazy(constr_of_ref"micromega.Psatz.PsatzAdd")letcoq_PsatzC=lazy(constr_of_ref"micromega.Psatz.PsatzC")letcoq_PsatzZ=lazy(constr_of_ref"micromega.Psatz.PsatzZ")(* let coq_GT = lazy (m_constant "GT")*)letcoq_DeclaredConstant=lazy(constr_of_ref"micromega.DeclaredConstant.type")letcoq_TT=lazy(constr_of_ref"micromega.GFormula.TT")letcoq_FF=lazy(constr_of_ref"micromega.GFormula.FF")letcoq_AND=lazy(constr_of_ref"micromega.GFormula.AND")letcoq_OR=lazy(constr_of_ref"micromega.GFormula.OR")letcoq_NOT=lazy(constr_of_ref"micromega.GFormula.NOT")letcoq_Atom=lazy(constr_of_ref"micromega.GFormula.A")letcoq_X=lazy(constr_of_ref"micromega.GFormula.X")letcoq_IMPL=lazy(constr_of_ref"micromega.GFormula.IMPL")letcoq_IFF=lazy(constr_of_ref"micromega.GFormula.IFF")letcoq_EQ=lazy(constr_of_ref"micromega.GFormula.EQ")letcoq_Formula=lazy(constr_of_ref"micromega.BFormula.type")letcoq_eKind=lazy(constr_of_ref"micromega.eKind")(**
* Initialization : a few Caml symbols are derived from other libraries;
* QMicromega, ZArithRing, RingMicromega.
*)letcoq_QWitness=lazy(constr_of_ref"micromega.QWitness.type")letcoq_Build=lazy(constr_of_ref"micromega.Formula.Build_Formula")letcoq_Cstr=lazy(constr_of_ref"micromega.Formula.type")(**
* Parsing and dumping : transformation functions between Caml and Coq
* data-structures.
*
* dump_* functions go from Micromega to Coq terms
* undump_* functions go from Coq to Micromega terms (reverse of dump_)
* parse_* functions go from Coq to Micromega terms
* pp_* functions pretty-print Coq 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.forcecoq_O|Mc.Sp->EConstr.mkApp(Lazy.forcecoq_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.forcecoq_xH|Mc.XOp->EConstr.mkApp(Lazy.forcecoq_xO,[|dump_positivep|])|Mc.XIp->EConstr.mkApp(Lazy.forcecoq_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.forcecoq_N0|Mc.Nposp->EConstr.mkApp(Lazy.forcecoq_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(Typeclasses.resolve_one_typeclassenvevd(EConstr.mkApp(Lazy.forcecoq_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.forcecoq_ZERO|Mc.Zposp->EConstr.mkApp(Lazy.forcecoq_POS,[|dump_positivep|])|Mc.Znegp->EConstr.mkApp(Lazy.forcecoq_NEG,[|dump_positivep|])letdump_qq=EConstr.mkApp(Lazy.forcecoq_Qmake,[|dump_zq.Micromega.qnum;dump_positiveq.Micromega.qden|])letparse_qsigmaterm=matchEConstr.kindsigmatermwith|App(c,args)->ifEConstr.eq_constrsigmac(Lazy.forcecoq_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.forcecoq_C0|Mc.C1->Lazy.forcecoq_C1|Mc.CQq->EConstr.mkApp(Lazy.forcecoq_CQ,[|dump_qq|])|Mc.CZz->EConstr.mkApp(Lazy.forcecoq_CZ,[|dump_zz|])|Mc.CPlus(x,y)->EConstr.mkApp(Lazy.forcecoq_CPlus,[|dump_Rcstx;dump_Rcsty|])|Mc.CMinus(x,y)->EConstr.mkApp(Lazy.forcecoq_CMinus,[|dump_Rcstx;dump_Rcsty|])|Mc.CMult(x,y)->EConstr.mkApp(Lazy.forcecoq_CMult,[|dump_Rcstx;dump_Rcsty|])|Mc.CPow(x,y)->EConstr.mkApp(Lazy.forcecoq_CPow,[|dump_Rcstx;(matchywith|Mc.Inlz->EConstr.mkApp(Lazy.forcecoq_Inl,[|Lazy.forcecoq_Z;Lazy.forcecoq_nat;dump_zz|])|Mc.Inrn->EConstr.mkApp(Lazy.forcecoq_Inr,[|Lazy.forcecoq_Z;Lazy.forcecoq_nat;dump_natn|]))|])|Mc.CInvt->EConstr.mkApp(Lazy.forcecoq_CInv,[|dump_Rcstt|])|Mc.COppt->EConstr.mkApp(Lazy.forcecoq_COpp,[|dump_Rcstt|])letrecdump_listtypdump_eltl=matchlwith|[]->EConstr.mkApp(Lazy.forcecoq_nil,[|typ|])|e::l->EConstr.mkApp(Lazy.forcecoq_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|])whenisccoq_PEX->Mc.PEX(undump_varsigman)|App(c,[|_;z|])whenisccoq_PEc->Mc.PEc(undump_constantsigmaz)|App(c,[|_;e1;e2|])whenisccoq_PEadd->Mc.PEadd(xundumpe1,xundumpe2)|App(c,[|_;e1;e2|])whenisccoq_PEsub->Mc.PEsub(xundumpe1,xundumpe2)|App(c,[|_;e|])whenisccoq_PEopp->Mc.PEopp(xundumpe)|App(c,[|_;e1;e2|])whenisccoq_PEmul->Mc.PEmul(xundumpe1,xundumpe2)|App(c,[|_;e;n|])whenisccoq_PEpow->Mc.PEpow(xundumpe,parse_nsigman)|_->raiseParseErrorinxundumpeletdump_exprtypdump_ze=letrecdump_expre=matchewith|Mc.PEXn->EConstr.mkApp(Lazy.forcecoq_PEX,[|typ;dump_varn|])|Mc.PEcz->EConstr.mkApp(Lazy.forcecoq_PEc,[|typ;dump_zz|])|Mc.PEadd(e1,e2)->EConstr.mkApp(Lazy.forcecoq_PEadd,[|typ;dump_expre1;dump_expre2|])|Mc.PEsub(e1,e2)->EConstr.mkApp(Lazy.forcecoq_PEsub,[|typ;dump_expre1;dump_expre2|])|Mc.PEoppe->EConstr.mkApp(Lazy.forcecoq_PEopp,[|typ;dump_expre|])|Mc.PEmul(e1,e2)->EConstr.mkApp(Lazy.forcecoq_PEmul,[|typ;dump_expre1;dump_expre2|])|Mc.PEpow(e,n)->EConstr.mkApp(Lazy.forcecoq_PEpow,[|typ;dump_expre;dump_nn|])indump_expreletdump_poltypdump_ce=letrecdump_pole=matchewith|Mc.Pcn->EConstr.mkApp(Lazy.forcecoq_Pc,[|typ;dump_cn|])|Mc.Pinj(p,pol)->EConstr.mkApp(Lazy.forcecoq_Pinj,[|typ;dump_positivep;dump_polpol|])|Mc.PX(pol1,p,pol2)->EConstr.mkApp(Lazy.forcecoq_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.forcecoq_PsatzLet,[|z;dump_conee1;dump_conee2|])|Mc.PsatzInn->EConstr.mkApp(Lazy.forcecoq_PsatzIn,[|z;dump_natn|])|Mc.PsatzMulC(e,c)->EConstr.mkApp(Lazy.forcecoq_PsatzMultC,[|z;dump_polzdump_ze;dump_conec|])|Mc.PsatzSquaree->EConstr.mkApp(Lazy.forcecoq_PsatzSquare,[|z;dump_polzdump_ze|])|Mc.PsatzAdd(e1,e2)->EConstr.mkApp(Lazy.forcecoq_PsatzAdd,[|z;dump_conee1;dump_conee2|])|Mc.PsatzMulE(e1,e2)->EConstr.mkApp(Lazy.forcecoq_PsatzMulE,[|z;dump_conee1;dump_conee2|])|Mc.PsatzCp->EConstr.mkApp(Lazy.forcecoq_PsatzC,[|z;dump_zp|])|Mc.PsatzZ->EConstr.mkApp(Lazy.forcecoq_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.forcecoq_OpEq|Mc.OpNEq->Lazy.forcecoq_OpNEq|Mc.OpLe->Lazy.forcecoq_OpLe|Mc.OpGe->Lazy.forcecoq_OpGe|Mc.OpGt->Lazy.forcecoq_OpGt|Mc.OpLt->Lazy.forcecoq_OpLtletundump_cstrundump_constantsigmac=letiscc'=EConstr.eq_constrsigmac(Lazy.forcec')inmatchEConstr.kindsigmacwith|App(c,[|_;e1;o;e2|])whenisccoq_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.forcecoq_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=[(coq_Zgt,Mc.OpGt);(coq_Zge,Mc.OpGe);(coq_Zlt,Mc.OpLt);(coq_Zle,Mc.OpLe)]letzop_table_bool=[(coq_Zgtb,Mc.OpGt);(coq_Zgeb,Mc.OpGe);(coq_Zltb,Mc.OpLt);(coq_Zleb,Mc.OpLe);(coq_Zeqb,Mc.OpEq)]letrop_table_prop=[(coq_Rgt,Mc.OpGt);(coq_Rge,Mc.OpGe);(coq_Rlt,Mc.OpLt);(coq_Rle,Mc.OpLe)]letrop_table_bool=[]letqop_table_prop=[(coq_Qlt,Mc.OpLt);(coq_Qle,Mc.OpLe);(coq_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.forcecoq_eq)&&is_convertibleenvsigmaty(Lazy.forcetyp)then(Mc.OpEq,args.(1),args.(2))elseraiseParseError|_->raiseParseErrorletparse_zop=parse_operatorzop_table_propzop_table_booltruecoq_Zletparse_rop=parse_operatorrop_table_prop[]truecoq_Rletparse_qop=parse_operatorqop_table_prop[]falsecoq_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=[(coq_Zplus,Binop(funxy->Mc.PEadd(x,y)));(coq_Zminus,Binop(funxy->Mc.PEsub(x,y)));(coq_Zmult,Binop(funxy->Mc.PEmul(x,y)));(coq_Zopp,Opp);(coq_Zpower,Power)]letqop_spec=[(coq_Qplus,Binop(funxy->Mc.PEadd(x,y)));(coq_Qminus,Binop(funxy->Mc.PEsub(x,y)));(coq_Qmult,Binop(funxy->Mc.PEmul(x,y)));(coq_Qopp,Opp);(coq_Qpower,Power)]letrop_spec=[(coq_Rplus,Binop(funxy->Mc.PEadd(x,y)));(coq_Rminus,Binop(funxy->Mc.PEsub(x,y)));(coq_Rmult,Binop(funxy->Mc.PEmul(x,y)));(coq_Ropp,Opp);(coq_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=[(coq_Rplus,funxy->Mc.CPlus(x,y));(coq_Rminus,funxy->Mc.CMinus(x,y));(coq_Rmult,funxy->Mc.CMult(x,y))(* coq_Rdiv , (fun x y -> Mc.CMult(x,Mc.CInv y)) ;*)]letrconstant(genv,sigma)term=letrecrconstantterm=matchEConstr.kindsigmatermwith|Constx->ifEConstr.eq_constrsigmaterm(Lazy.forcecoq_R0)thenMc.C0elseifEConstr.eq_constrsigmaterm(Lazy.forcecoq_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.forcecoq_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.forcecoq_Rpower)->Mc.CPow(rconstantargs.(0),Mc.Inr(parse_more_constantnconstant(genv,sigma)args.(1)))|opwhenEConstr.eq_constrsigmaop(Lazy.forcecoq_IQR)->Mc.CQ(qconstant(genv,sigma)args.(0))|opwhenEConstr.eq_constrsigmaop(Lazy.forcecoq_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.forcecoq_and;op_or=Lazy.forcecoq_or;op_iff=Lazy.forcecoq_iff;op_not=Lazy.forcecoq_not;op_tt=Lazy.forcecoq_True;op_ff=Lazy.forcecoq_False}letbool_op=lazy{op_impl=Some(Lazy.forcecoq_implb);op_and=Lazy.forcecoq_andb;op_or=Lazy.forcecoq_orb;op_iff=Lazy.forcecoq_eqb;op_not=Lazy.forcecoq_negb;op_tt=Lazy.forcecoq_true;op_ff=Lazy.forcecoq_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.forcecoq_eqinletbool=Lazy.forcecoq_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 coq_true else coq_false)*)letundump_kindsigmak=ifEConstr.eq_constrsigmak(Lazy.forcecoq_IsProp)thenMc.IsPropelseMc.IsBoolletdump_kindk=Lazy.force(matchkwithMc.IsProp->coq_IsProp|Mc.IsBool->coq_IsBool)letundump_formulaundump_atomtgsigmaf=letiscc'=EConstr.eq_constrsigmac(Lazy.forcec')inletkindk=undump_kindsigmakinletrecxundumpf=matchEConstr.kindsigmafwith|App(c,[|_;_;_;_;k|])whenisccoq_TT->Mc.TT(kindk)|App(c,[|_;_;_;_;k|])whenisccoq_FF->Mc.FF(kindk)|App(c,[|_;_;_;_;k;f1;f2|])whenisccoq_AND->Mc.AND(kindk,xundumpf1,xundumpf2)|App(c,[|_;_;_;_;k;f1;f2|])whenisccoq_OR->Mc.OR(kindk,xundumpf1,xundumpf2)|App(c,[|_;_;_;_;k;f1;_;f2|])whenisccoq_IMPL->Mc.IMPL(kindk,xundumpf1,None,xundumpf2)|App(c,[|_;_;_;_;k;f|])whenisccoq_NOT->Mc.NOT(kindk,xundumpf)|App(c,[|_;_;_;_;k;f1;f2|])whenisccoq_IFF->Mc.IFF(kindk,xundumpf1,xundumpf2)|App(c,[|_;_;_;_;f1;f2|])whenisccoq_EQ->Mc.EQ(xundumpf1,xundumpf2)|App(c,[|_;_;_;_;k;x;_|])whenisccoq_Atom->Mc.A(kindk,undump_atomsigmax,tg)|App(c,[|_;_;_;_;k;x|])whenisccoq_X->Mc.X(kindk,x)|_->raiseParseErrorinxundumpfletdump_formulatypdump_atomf=letapp_ctorcargs=EConstr.mkApp(Lazy.forcec,Array.of_list(typ::Lazy.forcecoq_eKind::Lazy.forcecoq_unit::Lazy.forcecoq_unit::args))inletrecxdumpf=matchfwith|Mc.TTk->app_ctorcoq_TT[dump_kindk]|Mc.FFk->app_ctorcoq_FF[dump_kindk]|Mc.AND(k,x,y)->app_ctorcoq_AND[dump_kindk;xdumpx;xdumpy]|Mc.OR(k,x,y)->app_ctorcoq_OR[dump_kindk;xdumpx;xdumpy]|Mc.IMPL(k,x,_,y)->app_ctorcoq_IMPL[dump_kindk;xdumpx;EConstr.mkApp(Lazy.forcecoq_None,[|Lazy.forcecoq_unit|]);xdumpy]|Mc.NOT(k,x)->app_ctorcoq_NOT[dump_kindk;xdumpx]|Mc.IFF(k,x,y)->app_ctorcoq_IFF[dump_kindk;xdumpx;xdumpy]|Mc.EQ(x,y)->app_ctorcoq_EQ[xdumpx;xdumpy]|Mc.A(k,x,_)->app_ctorcoq_Atom[dump_kindk;dump_atomx;Lazy.forcecoq_tt]|Mc.X(k,t)->app_ctorcoq_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.forcecoq_Z;dump_cst=dump_z;dump_add=Lazy.forcecoq_Zplus;dump_sub=Lazy.forcecoq_Zminus;dump_opp=Lazy.forcecoq_Zopp;dump_mul=Lazy.forcecoq_Zmult;dump_pow=Lazy.forcecoq_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.forcecoq_Q;dump_cst=dump_q;dump_add=Lazy.forcecoq_Qplus;dump_sub=Lazy.forcecoq_Qminus;dump_opp=Lazy.forcecoq_Qopp;dump_mul=Lazy.forcecoq_Qmult;dump_pow=Lazy.forcecoq_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.forcecoq_R0|Mc.C1->Lazy.forcecoq_R1|Mc.CQq->EConstr.mkApp(Lazy.forcecoq_IQR,[|dump_qq|])|Mc.CZz->EConstr.mkApp(Lazy.forcecoq_IZR,[|dump_zz|])|Mc.CPlus(x,y)->EConstr.mkApp(Lazy.forcecoq_Rplus,[|dump_Rcst_as_Rx;dump_Rcst_as_Ry|])|Mc.CMinus(x,y)->EConstr.mkApp(Lazy.forcecoq_Rminus,[|dump_Rcst_as_Rx;dump_Rcst_as_Ry|])|Mc.CMult(x,y)->EConstr.mkApp(Lazy.forcecoq_Rmult,[|dump_Rcst_as_Rx;dump_Rcst_as_Ry|])|Mc.CPow(x,y)->(matchywith|Mc.Inlz->EConstr.mkApp(Lazy.forcecoq_powerZR,[|dump_Rcst_as_Rx;dump_zz|])|Mc.Inrn->EConstr.mkApp(Lazy.forcecoq_Rpower,[|dump_Rcst_as_Rx;dump_natn|]))|Mc.CInvt->EConstr.mkApp(Lazy.forcecoq_Rinv,[|dump_Rcst_as_Rt|])|Mc.COppt->EConstr.mkApp(Lazy.forcecoq_Ropp,[|dump_Rcst_as_Rt|])letdump_rexpr=lazy{interp_typ=Lazy.forcecoq_R;dump_cst=dump_Rcst_as_R;dump_add=Lazy.forcecoq_Rplus;dump_sub=Lazy.forcecoq_Rminus;dump_opp=Lazy.forcecoq_Ropp;dump_mul=Lazy.forcecoq_Rmult;dump_pow=Lazy.forcecoq_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.forcecoq_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.forcecoq_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.forcecoq_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.forcecoq_True|Mc.FF_->Lazy.forcecoq_False|Mc.AND(_,x,y)->EConstr.mkApp(Lazy.forcecoq_and,[|xdump_proppixix;xdump_proppixiy|])|Mc.OR(_,x,y)->EConstr.mkApp(Lazy.forcecoq_or,[|xdump_proppixix;xdump_proppixiy|])|Mc.IFF(_,x,y)->EConstr.mkApp(Lazy.forcecoq_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.forcecoq_False)|Mc.EQ(x,y)->EConstr.mkApp(Lazy.forcecoq_eq,[|Lazy.forcecoq_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.forcecoq_true|Mc.FF_->Lazy.forcecoq_false|Mc.AND(_,x,y)->EConstr.mkApp(Lazy.forcecoq_andb,[|xdump_boolpixix;xdump_boolpixiy|])|Mc.OR(_,x,y)->EConstr.mkApp(Lazy.forcecoq_orb,[|xdump_boolpixix;xdump_boolpixiy|])|Mc.IFF(_,x,y)->EConstr.mkApp(Lazy.forcecoq_eqb,[|xdump_boolpixix;xdump_boolpixiy|])|Mc.IMPL(_,x,_,y)->EConstr.mkApp(Lazy.forcecoq_implb,[|xdump_boolpixix;xdump_boolpixiy|])|Mc.NOT(_,x)->EConstr.mkApp(Lazy.forcecoq_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)linxsetconcllletcoq_Branch=lazy(constr_of_ref"micromega.VarMap.Branch")letcoq_Elt=lazy(constr_of_ref"micromega.VarMap.Elt")letcoq_Empty=lazy(constr_of_ref"micromega.VarMap.Empty")letcoq_VarMap=lazy(constr_of_ref"micromega.VarMap.type")letrecdump_varmaptypm=matchmwith|Mc.Empty->EConstr.mkApp(Lazy.forcecoq_Empty,[|typ|])|Mc.Eltv->EConstr.mkApp(Lazy.forcecoq_Elt,[|typ;v|])|Mc.Branch(l,o,r)->EConstr.mkApp(Lazy.forcecoq_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.forcecoq_doneProof|Micromega.RatProof(cone,rst)->EConstr.mkApp(Lazy.forcecoq_ratProof,[|dump_psatzcoq_Zdump_zcone;dump_proof_termrst|])|Micromega.CutProof(cone,prf)->EConstr.mkApp(Lazy.forcecoq_cutProof,[|dump_psatzcoq_Zdump_zcone;dump_proof_termprf|])|Micromega.SplitProof(p,prf1,prf2)->EConstr.mkApp(Lazy.forcecoq_splitProof,[|dump_pol(Lazy.forcecoq_Z)dump_zp;dump_proof_termprf1;dump_proof_termprf2|])|Micromega.EnumProof(c1,c2,prfs)->EConstr.mkApp(Lazy.forcecoq_enumProof,[|dump_psatzcoq_Zdump_zc1;dump_psatzcoq_Zdump_zc2;dump_list(Lazy.forcecoq_proofTerm)dump_proof_termprfs|])|Micromega.ExProof(p,prf)->EConstr.mkApp(Lazy.forcecoq_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_arithenvtghyps=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)hypsterm=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.forcecoq_Z;coeff=Lazy.forcecoq_Z;dump_coeff=dump_z;undump_coeff=parse_z;proof_typ=Lazy.forcecoq_proofTerm;dump_proof=dump_proof_term;coeff_eq=Mc.zeq_bool}letqq_domain_spec=lazy{typ=Lazy.forcecoq_Q;coeff=Lazy.forcecoq_Q;dump_coeff=dump_q;undump_coeff=parse_q;proof_typ=Lazy.forcecoq_QWitness;dump_proof=dump_psatzcoq_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 Coq 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.forcecoq_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.forcecoq_Formula,[|formula_typ;Lazy.forcecoq_IsProp|]));("__varmap",vm,EConstr.mkApp(Lazy.forcecoq_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=(letcoq_True=Lazy.forcecoq_Trueinletcoq_true=Lazy.forcecoq_trueinfunctionMc.IsProp->coq_True|Mc.IsBool->coq_true);mkFF=(letcoq_False=Lazy.forcecoq_Falseinletcoq_false=Lazy.forcecoq_falseinfunctionMc.IsProp->coq_False|Mc.IsBool->coq_false);mkA=(funka(tg,t)->t);mkAND=(letcoq_and=Lazy.forcecoq_andinletcoq_andb=Lazy.forcecoq_andbinfunkxy->EConstr.mkApp((matchkwithMc.IsProp->coq_and|Mc.IsBool->coq_andb),[|x;y|]));mkOR=(letcoq_or=Lazy.forcecoq_orinletcoq_orb=Lazy.forcecoq_orbinfunkxy->EConstr.mkApp((matchkwithMc.IsProp->coq_or|Mc.IsBool->coq_orb),[|x;y|]));mkIMPL=(funkxy->matchkwith|Mc.IsProp->EConstr.mkArrowxERelevance.relevanty|Mc.IsBool->EConstr.mkApp(Lazy.forcecoq_implb,[|x;y|]));mkIFF=(letcoq_iff=Lazy.forcecoq_iffinletcoq_eqb=Lazy.forcecoq_eqbinfunkxy->EConstr.mkApp((matchkwithMc.IsProp->coq_iff|Mc.IsBool->coq_eqb),[|x;y|]));mkNOT=(letcoq_not=Lazy.forcecoq_notinletcoq_negb=Lazy.forcecoq_negbinfunkx->EConstr.mkApp((matchkwithMc.IsProp->coq_not|Mc.IsBool->coq_negb),[|x|]));mkEQ=(letcoq_eq=Lazy.forcecoq_eqinfunxy->EConstr.mkApp(coq_eq,[|Lazy.forcecoq_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 Coq'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'inPrf(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~typecheck:false(funsigma->Evarutil.new_evarenvsigma~principal:trueconcl))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.forcecoq_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()|x->ifdebugthenTacticals.tclFAIL(Pp.str(Printexc.get_backtrace()))elseraisex)letmicromega_wit_genpre_processcnfspecproverwit_idff=Proofview.Goal.enter(fungl->letsigma=Tacmach.projectglintryletspec=Lazy.forcespecinletundump_cstr=undump_cstrspec.undump_coeffinlettg=Tag.from0,Lazy.forcecoq_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.forcecoq_list,[|spec.proof_typ|])inTactics.letin_tacNone(Names.Namewit_id)res'(Sometres')Locusops.nowherewith|CsdpNotFound->fail_csdp_not_found()|x->ifdebugthenTacticals.tclFAIL(Pp.str(Printexc.get_backtrace()))elseraisex)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.forcecoq_Rcstinletdump_coeff=dump_Rcstinlettyp=Lazy.forcecoq_Rinletcert_typ=EConstr.mkApp(Lazy.forcecoq_list,[|Lazy.forcecoq_QWitness|])inletformula_typ=EConstr.mkApp(Lazy.forcecoq_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.forcecoq_Formula,[|formula_typ;Lazy.forcecoq_IsProp|]));("__varmap",vm,EConstr.mkApp(Lazy.forcecoq_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.forcecoq_R;coeff=Lazy.forcecoq_Rcst;dump_coeff=dump_q;undump_coeff=parse_q;proof_typ=Lazy.forcecoq_QWitness;dump_proof=dump_psatzcoq_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))]]with|CsdpNotFound->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 Coq 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: *)