1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596(************************************************************************)(* * 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 *)(* *)(************************************************************************)openPpopenNamesopenGoptionsopenMutilsopenConstropenContextopenTactypesopenMcPrinter(**
* 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_annotvSorts.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.map2(fun(idx,_)(id,_)->(id,idx))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)Sorts.Relevant(xdump_prop(pi+1)(xi+1)y)|Mc.NOT(_,x)->EConstr.mkArrow(xdump_proppixix)Sorts.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,List.revvar_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)Sorts.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=tryletpolys1=List.mapfstpolys1inp.prover(p.get_option(),polys1)withe->beginPrintf.printf"find_witness %s"(Printexc.to_stringe);raiseeend(**
* Given a prover and a CNF, find a proof for each of the clauses.
* Return the proofs as a list.
*)letwitness_listproverl=letrecxwitness_listl=matchlwith|[]->Prf[]|e::l->(matchxwitness_listlwith|Model(m,e)->Model(m,e)|Unknown->Unknown|Prfl->(matchfind_witnessproverewith|Modelm->Model(m,e)|Unknown->Unknown|Prfw->Prf(w::l)))inxwitness_listl(* 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_clinletmapclprf=lethyps=lazy(selecti(prover.hypsprf)cl)inhyps,cl,prfinletcnf_res=List.map2mapcnf_ffresin(* 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.mkArrowxSorts.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_tracefaccu=function|Micromega.Null->accu|Micromega.Merge(t1,t2)->fold_tracef(fold_tracefaccut1)t2|Micromega.Push(x,t)->fold_tracef(faccux)tletmicromega_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_left(funs(cl,prf)->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)(List.combinecnf_ffres)inletff'=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[Tactics.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=ifSystem.is_in_system_path"csdp"thenlazy()elselazy(raiseCsdpNotFound)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: *)