12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097(**************************************************************************)(* *)(* This file is part of WP plug-in of Frama-C. *)(* *)(* Copyright (C) 2007-2023 *)(* CEA (Commissariat a l'energie atomique et aux energies *)(* alternatives) *)(* *)(* you can redistribute it and/or modify it under the terms of the GNU *)(* Lesser General Public License as published by the Free Software *)(* Foundation, version 2.1. *)(* *)(* It is distributed in the hope that it will be useful, *)(* but WITHOUT ANY WARRANTY; without even the implied warranty of *)(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *)(* GNU Lesser General Public License for more details. *)(* *)(* See the GNU Lesser General Public License version 2.1 *)(* for more details (enclosed in the file licenses/LGPLv2.1). *)(* *)(**************************************************************************)(* -------------------------------------------------------------------------- *)(* --- Logical Language --- *)(* -------------------------------------------------------------------------- *)openCil_typesopenCil_datatypeopenCtypesopenQedopenQed.Logicletdkey_pretty=Wp_parameters.register_category"pretty"(* -------------------------------------------------------------------------- *)letbasenamedefname=letreclookupdefskn=ifk<nthenletc=s.[k]inif('a'<=c&&c<='z')||('A'<=c&&c<='Z')thenString.subsk1elselookupdefs(succk)nelsedefinlookupdefname0(String.lengthname)(* -------------------------------------------------------------------------- *)(* Naming Prefixes
Names starting with a lower-case character belong to logic language
or external model(s).
'pointer' Pointer type
'Lit_<hex>' String Literal Values
'Str_<eid>' String Literal Pointers
'S_<s>' Structure <s>
'U_<u>' Union <u>
'F_<c>_<f>' Field <f> in compound <c>
'A_<t>' ACSL Logic type <t>
'C_<c>' ACSL Constructor <c>
'P_<p>' ACSL Predicate <p> (see LogicUsage.get_name)
'L_<f>' ACSL Logic function <f> (see LogicUsage.get_name)
'FixP_<p>' ACSL Recursive Predicate <p> (see LogicUsage.get_name)
'FixL_<f>' ACSL Recursive Logic function <f> (see LogicUsage.get_name)
'Q_<l>' ACSL Lemma or Axiom
'S_<n>' Set comprehension predicate
'Is<phi>' Typing predicate for type <phi>
'Null<phi>' Null value for type <phi>
*)letavoid_leading_backlashs=ifs.[0]='\\'thenlets=Bytes.of_stringsinBytes.sets0'_';Bytes.to_stringselsesletcomp_idc=letprefix=ifc.cstructthen'S'else'U'inifc.corig_name=""thenPrintf.sprintf"%c%d"prefixc.ckeyelsePrintf.sprintf"%c%d_%s"prefixc.ckeyc.corig_nameletfield_idf=letc=f.fcompinifc.corig_name=""thenPrintf.sprintf"F%d_%s"c.ckeyf.fnameelsePrintf.sprintf"F%d_%s_%s"c.ckeyc.corig_namef.fnameletinit_id(f:'a->string)(x:'a)="Init_"^(fx)letcomp_init_id=init_idcomp_idletfield_init_id=init_idfield_idlettype_idl=Printf.sprintf"A_%s"l.lt_nameletlogic_idf=letname=avoid_leading_backlash(LogicUsage.get_namef)iniff.l_type=NonethenPrintf.sprintf"P_%s"nameelsePrintf.sprintf"L_%s"nameletctor_idc=Printf.sprintf"C_%s"(avoid_leading_backlashc.ctor_name)letlemma_idl=Printf.sprintf"Q_%s"(avoid_leading_backlashl)(* -------------------------------------------------------------------------- *)typelibrary=stringtypedatakind=KValue|KInittypeadt=|Mtypeofmdt(* Model type *)|Mrecordofmdt*fields(* Model record-type *)|Atypeoflogic_type_info(* Logic Type *)|Compofcompinfo*datakind(* C-code struct or union *)(** name to print to the provers *)andmdt=stringexternand'aextern={ext_id:int;ext_link:'a;ext_library:library;(** a library which it depends on *)ext_debug:string;(** just for printing during debugging *)}andfields={mutablefields:fieldlist}andfield=|Mfieldofmdt*fields*string*tau|Cfieldoffieldinfo*datakindandtau=(field,adt)Logic.datatypeletpointer=Context.create"Lang.pointer"letfloats=Context.create"Lang.floats"letnew_extern_id=ref(-1)letnew_extern~debug~library~link=incrnew_extern_id;{ext_id=!new_extern_id;ext_library=library;ext_debug=debug;ext_link=link}letext_compareab=Datatype.Int.comparea.ext_idb.ext_id(* -------------------------------------------------------------------------- *)(* --- Sorting & Typing --- *)(* -------------------------------------------------------------------------- *)letsort_of_object=function|C_int_->Logic.Sint|C_pointer_|C_comp_|C_array_->Logic.Sdata|C_floatf->Qed.Kind.of_tau(Context.getfloatsf)letinit_sort_of_object=function|C_int_|C_float_|C_pointer_->Logic.Sbool|C_comp_|C_array_->Logic.Sdataletsort_of_ctypet=sort_of_object(Ctypes.object_oft)letsort_of_ltypet=matchLogic_utils.unroll_type~unroll_typedef:falsetwith|Ctypetyp->sort_of_ctypetyp|Ltype_|Lvar_|Larrow_->Logic.Sdata|Linteger->Logic.Sint|Lreal->Logic.Sreallett_int=Logic.Intlett_bool=Logic.Boollett_real=Logic.Reallett_prop=Logic.Proplett_addr()=Context.getpointerlett_floatf=Context.getfloatsflett_compc=Logic.Data(Comp(c,KValue),[])lett_initc=Logic.Data(Comp(c,KInit),[])lett_arraya=Logic.Array(Logic.Int,a)lett_farrayab=Logic.Array(a,b)lett_datatypeadtts=Logic.Data(adt,ts)letrect_matrixan=ifn>0thent_matrix(t_arraya)(predn)elsealetrectau_of_object=function|C_int_->Logic.Int|C_floatf->t_floatf|C_pointer_->Context.getpointer|C_compc->t_compc|C_array{arr_element=typ}->t_array(tau_of_ctypetyp)andtau_of_ctypetyp=tau_of_object(Ctypes.object_oftyp)letpoly=Context.create"Wp.Lang.poly"letrecinit_of_object=function|C_int_|C_float_|C_pointer_->Logic.Bool|C_compc->t_initc|C_array{arr_element=typ}->t_array(init_of_ctypetyp)andinit_of_ctypetyp=init_of_object(Ctypes.object_oftyp)letrecvarpolykx=function|[]->Warning.error"Unbound type parameter <%s>"x|y::ys->ifx=ythenkelsevarpoly(succk)xystypet_builtin=E_mdtofmdt|E_polyof(taulist->tau)letbuiltin_types=Context.create"Wp.Lang.builtin_types"letfind_builtinname=Context.getbuiltin_typesnameletadtlt=trymatchfind_builtinlt.lt_namewith|E_mdtm->Mtypem|E_poly_->assertfalsewithNot_found->Atypeltletatypeltts=trymatchfind_builtinlt.lt_namewith|E_mdtm->Logic.Data(Mtypem,ts)|E_polyftau->ftautswithNot_found->Logic.Data(Atypelt,ts)letrectau_of_ltypet=matchLogic_utils.unroll_type~unroll_typedef:falsetwith|Linteger->Logic.Int|Lreal->Logic.Real|Ctypetyp->tau_of_ctypetyp|Lvarx->Logic.Tvar(varpoly1x(Context.getpoly))|Larrow_->Warning.error"array type non-supported(%a)"Printer.pp_logic_typet|Ltype_asbwhenLogic_const.is_boolean_typeb->Logic.Bool|Ltype(lt,lts)->atypelt(List.maptau_of_ltypelts)lettau_of_return=functionNone->Logic.Prop|Somet->tau_of_ltypet(* -------------------------------------------------------------------------- *)(* --- Datatypes --- *)(* -------------------------------------------------------------------------- *)moduleADT=structtypet=adtletbasename=function|Mtypea->basename"M"a.ext_link|Mrecord(r,_)->basename"R"r.ext_link|Comp(c,KValue)->basename(ifc.cstructthen"S"else"U")c.corig_name|Comp(c,KInit)->basename(ifc.cstructthen"IS"else"IU")c.corig_name|Atypelt->basename"A"lt.lt_nameletdebug=function|Mtypea->a.ext_debug|Mrecord(a,_)->a.ext_debug|Comp(c,KValue)->comp_idc|Comp(c,KInit)->comp_init_idc|Atypelt->type_idltlethash=function|Mtypea|Mrecord(a,_)->FCHashtbl.hasha|Comp(c,KValue)->Compinfo.hashc|Comp(c,KInit)->13*Compinfo.hashc|Atypelt->Logic_type_info.hashltletcompareab=ifa==bthen0elsematcha,bwith|Mtypea,Mtypeb->ext_compareab|Mtype_,_->(-1)|_,Mtype_->1|Mrecord(a,_),Mrecord(b,_)->ext_compareab|Mrecord_,_->(-1)|_,Mrecord_->1|Comp(a,KValue),Comp(b,KValue)|Comp(a,KInit),Comp(b,KInit)->Compinfo.compareab|Comp(_,KValue),Comp(_,KInit)->(-1)|Comp(_,KInit),Comp(_,KValue)->1|Comp_,_->(-1)|_,Comp_->1|Atypea,Atypeb->Logic_type_info.compareabletequalab=(compareab=0)letprettyfmta=Format.pp_print_stringfmt(debuga)end(* -------------------------------------------------------------------------- *)(* --- Datatypes --- *)(* -------------------------------------------------------------------------- *)letget_builtin_type~name=matchfind_builtinnamewith|E_mdtm->Mtypem|E_poly_->assertfalseletmem_builtin_type~name=tryignore(find_builtinname);truewithNot_found->falseletis_builtinlt=mem_builtin_type~name:lt.lt_nameletis_builtin_type~name=function|Data(Mtypem,_)->begintrymatchfind_builtinnamewith|E_mdtm0->m==m0|_->falsewithNot_found->falseend|_->falseletdatatype~libraryname=letm=new_extern~link:name~library~debug:nameinMtypemletrecord~link~libraryfts=letm=new_extern~link~library~debug:linkinletr={fields=[]}inletfs=List.map(fun(f,t)->Mfield(m,r,f,t))ftsinr.fields<-fs;Mrecord(m,r)letfieldtf=matchtwith|Mrecord(_,r)->begintryList.find(functionMfield(_,_,g,_)->f=g|_->false)r.fieldswithNot_found->Wp_parameters.fatal"No field <%s> in record"fend|_->Wp_parameters.fatal"No field <%s> in type '%a'"fADT.prettytletcompc=Comp(c,KValue)letcomp_initc=Comp(c,KInit)letfields_of_adt=function|Mrecord(_,r)->r.fields|Comp(c,k)->List.map(funf->Cfield(f,k))(Option.value~default:[]c.cfields)|_->[]letfields_of_tau=function|Recordfts->List.mapfstfts|Data(adt,_)->fields_of_adtadt|_->[]letfields_of_field=function|Mfield(_,r,_,_)->r.fields|Cfield(f,k)->List.map(funf->Cfield(f,k))(Option.value~default:[]f.fcomp.cfields)lettau_of_field=function|Mfield(_,_,_,t)->t|Cfield(f,KValue)->tau_of_ctypef.ftype|Cfield(f,KInit)->init_of_ctypef.ftypelettau_of_record=function|Mfield(mdt,fs,_,_)->Logic.Data(Mrecord(mdt,fs),[])|Cfield(f,KValue)->t_compf.fcomp|Cfield(f,KInit)->t_initf.fcompmoduleField=structtypet=fieldletdebug=function|Mfield(_,_,f,_)->f|Cfield(f,KValue)->field_idf|Cfield(f,KInit)->field_init_idflethash=function|Mfield(_,_,f,_)->FCHashtbl.hashf|Cfield(f,KValue)->Fieldinfo.hashf|Cfield(f,KInit)->13*Fieldinfo.hashfletcomparefg=iff==gthen0elsematchf,gwith|Mfield(_,_,f,_),Mfield(_,_,g,_)->String.comparefg|Mfield_,Cfield_->(-1)|Cfield_,Mfield_->1|Cfield(f,KValue),Cfield(g,KValue)|Cfield(f,KInit),Cfield(g,KInit)->Fieldinfo.comparefg|Cfield(_,KInit),Cfield(_,KValue)->(-1)|Cfield(_,KValue),Cfield(_,KInit)->1letequalfg=(comparefg=0)letprettyfmtf=Format.pp_print_stringfmt(debugf)letsort=function|Mfield(_,_,_,s)->Qed.Kind.of_taus|Cfield(f,KValue)->sort_of_object(Ctypes.object_off.ftype)|Cfield(f,KInit)->init_sort_of_object(Ctypes.object_off.ftype)end(* -------------------------------------------------------------------------- *)(* --- Functions & Predicates --- *)(* -------------------------------------------------------------------------- *)typelfun=|ACSLofCil_types.logic_info(** Registered in Definition.t, only *)|CTORofCil_types.logic_ctor_info(** Not registered in Definition.t, directly converted/printed *)|Modelofmodel(** Generated or External function *)andmodel={m_category:lfuncategory;m_params:sortlist;m_result:sort;m_typeof:tauoptionlist->tau;m_source:source;m_coloring:bool;}andsource=|GeneratedofWpContext.contextoption*string|ExternofEngine.linkexternlettau_of_lfunphits=matchphiwith|ACSLf->tau_of_returnf.l_type|CTORc->ifc.ctor_type.lt_params=[]thenLogic.Data(Atypec.ctor_type,[])elseraiseNot_found|Modelm->matchm.m_resultwith|Sint->Int|Sreal->Real|Sbool->Bool|_->m.m_typeoftsletis_coloring_lfun=function|ACSL_|CTOR_->false|Model{m_coloring}->m_coloringtypebalance=Nary|Left|Rightletnot_found_=raiseNot_foundletgenerated?(context=false)name=letctxt=ifcontextthenSome(WpContext.get_context())elseNoneinGenerated(ctxt,name)letsymbolf?library?context?link?(balance=Nary)(* specify a default for link *)?(category=Logic.Function)?(params=[])?(sort=Logic.Sdata)?(result:tauoption)?(coloring=false)?(typecheck:(tauoptionlist->tau)option)name=letbuffer=Buffer.create80inFormat.kfprintf(funfmt->Format.pp_print_flushfmt();letname=Buffer.contentsbufferinletsource=matchlibrarywith|None->assert(link=None);generated?contextname|Someth->letconvn=function|Nary->Engine.F_calln|Left->Engine.F_leftn|Right->Engine.F_rightninletlink=matchlinkwith|None->convnamebalance|Someinfo->infoinExtern(new_extern~library:th~link~debug:name)inlettypeof=matchtypecheckwithSomephi->phi|None->matchresultwithSomet->fun_->t|None->not_foundinletresult=matchresultwithSomet->Kind.of_taut|None->sortinModel{m_category=category;m_params=params;m_result=result;m_typeof=typeof;m_source=source;m_coloring=coloring;})(Format.formatter_of_bufferbuffer)nameletextern_s~library?link?category?params?sort?result?coloring?typecheckname=symbolf~library?category?params?sort?result?coloring?typecheck?link"%s"nameletextern_f~library?link?balance?category?params?sort?result?coloring?typecheckname=symbolf~library?category?params?link?balance?sort?result?coloring?typechecknameletextern_p~library?bool?prop?link?(params=[])?(coloring=false)()=letlink=matchbool,prop,linkwith|Someb,Somep,None->Engine.F_bool_prop(b,p)|_,_,Someinfo->info|_,_,_->assertfalseinletdebug=Export.debuglinkinModel{m_category=Logic.Function;m_params=params;m_result=Logic.Sprop;m_typeof=not_found;m_source=Extern(new_extern~library~link~debug);m_coloring=coloring;}letextern_fp~library?(params=[])?link?(coloring=false)phi=letlink=matchlinkwith|None->Engine.F_callphi|Somelink->Engine.F_calllinkinModel{m_category=Logic.Function;m_params=params;m_result=Logic.Sprop;m_typeof=not_found;m_source=Extern(new_extern~library~link~debug:phi);m_coloring=coloring;}letgenerated_f?context?category?params?sort?result?coloringname=symbolf?context?category?params?sort?result?coloringnameletgenerated_p?context?(coloring=false)name=Model{m_category=Logic.Function;m_params=[];m_result=Logic.Sprop;m_typeof=not_found;m_source=generated?contextname;m_coloring=coloring;}letextern_tname~link~library=new_extern~link~library~debug:namemoduleFun=structtypet=lfunletdebug=function|ACSLf->logic_idf|CTORc->ctor_idc|Model({m_source=Generated(_,n)})->n|Model({m_source=Externe})->e.ext_debuglethash=function|ACSLf->Logic_info.hashf|CTORc->Logic_ctor_info.hashc|Model({m_source=Generated(_,n)})->Datatype.String.hashn|Model({m_source=Externe})->e.ext_idletcompare_contextc1c2=matchc1,c2with|None,None->0|None,_->(-1)|_,None->1|Somec1,Somec2->WpContext.S.comparec1c2letcompare_sources1s2=matchs1,s2with|Generated(m1,f1),Generated(m2,f2)->letcmp=String.comparef1f2inifcmp<>0thencmpelsecompare_contextm1m2|Externf,Externg->ext_comparefg|Generated_,Extern_->(-1)|Extern_,Generated_->1letcomparefg=iff==gthen0elsematchf,gwith|Model{m_source=mf},Model{m_source=mg}->compare_sourcemfmg|Model_,_->(-1)|_,Model_->1|ACSLf,ACSLg->Logic_info.comparefg|ACSL_,_->(-1)|_,ACSL_->1|CTORc,CTORd->Logic_ctor_info.comparecdletequalfg=(comparefg=0)letprettyfmtf=Format.pp_print_stringfmt(debugf)letcategory=function|Modelm->m.m_category|ACSL_->Logic.Function|CTOR_->Logic.Constructorletsort=function|Modelm->m.m_result|ACSL{l_type=None}->Logic.Sprop|ACSL{l_type=Somet}->sort_of_ltypet|CTOR_->Logic.Sdataletparameters=ref(fun_->[])letparams=function|Modelm->m.m_params|CTORct->List.mapsort_of_ltypect.ctor_params|(ACSL_)asf->!parametersfendletparametersphi=Fun.parameters:=phiclassvirtualidprinting=object(self)methodvirtualsanitize:string->stringmethodsanitize_type=self#sanitizemethodsanitize_field=self#sanitizemethodsanitize_fun=self#sanitizemethoddatatype=function|Mtypea->a.ext_link|Mrecord(a,_)->a.ext_link|Comp(c,KValue)->self#sanitize_type(comp_idc)|Comp(c,KInit)->self#sanitize_type(comp_init_idc)|Atypelt->self#sanitize_type(type_idlt)methodfield=function|Mfield(_,_,f,_)->self#sanitize_fieldf|Cfield(f,KValue)->self#sanitize_field(field_idf)|Cfield(f,KInit)->self#sanitize_field(field_init_idf)methodlink=function|ACSLf->Engine.F_call(self#sanitize_fun(logic_idf))|CTORc->Engine.F_call(self#sanitize_fun(ctor_idc))|Model({m_source=Generated(_,n)})->Engine.F_call(self#sanitize_funn)|Model({m_source=Externe})->e.ext_linkendletname_of_lfun=function|ACSLf->logic_idf|CTORc->ctor_idc|Model({m_source=Generated(_,f)})->f|Model({m_source=Externe})->e.ext_debugletname_of_field=function|Mfield(_,_,f,_)->f|Cfield(f,KValue)->field_idf|Cfield(f,KInit)->field_init_idf(* -------------------------------------------------------------------------- *)(* --- Terms --- *)(* -------------------------------------------------------------------------- *)moduleF=structmoduleQZERO=Qed.Term.Make(ADT)(Field)(Fun)(* -------------------------------------------------------------------------- *)(* --- Qed Projectified State --- *)(* -------------------------------------------------------------------------- *)moduleDATA=Datatype.Make(structtypet=QZERO.stateletname="Wp.Qed"letrehash=Datatype.identityletstructural_descr=Structural_descr.t_unknownletreprs=[QZERO.get_state()]letequal=Datatype.undefinedletcompare=Datatype.undefinedlethash=Datatype.undefinedletcopy_old=QZERO.create()letpretty=Datatype.undefinedletmem_project__=falseend)moduleSTATE=State_builder.Register(DATA)(structtypet=QZERO.stateletcreate=QZERO.createletclear=QZERO.clr_stateletget=QZERO.get_stateletset=QZERO.set_stateletclear_some_projects__=falseend)(structletname="Wp.Qed"letdependencies=[Ast.self]letunique_name=nameend)include(STATE:sigend)(* For OCaml-4.0 *)(* -------------------------------------------------------------------------- *)(* --- Term API --- *)(* -------------------------------------------------------------------------- *)modulePretty=Qed.Pretty.Make(QZERO)moduleQED=structincludeQZEROlettypeof?(field=tau_of_field)?(record=tau_of_record)?(call=tau_of_lfun)e=QZERO.typeof~field~record~calleendincludeQED(* Hide force parameter. *)letset_builtinf=QZERO.set_builtinfletset_builtin'f=QZERO.set_builtin'fletset_builtin_eqf=QZERO.set_builtin_eqfletset_builtin_leqf=QZERO.set_builtin_leqfletset_builtin_getf=QZERO.set_builtin_getf(* -------------------------------------------------------------------------- *)(* --- Term Extensions --- *)(* -------------------------------------------------------------------------- *)typeunop=term->termtypebinop=term->term->termlete_zero=QED.constant(e_zintZ.zero)lete_one=QED.constant(e_zintZ.one)lete_minus_one=QED.constant(e_zintZ.minus_one)lete_minus_one_real=QED.constant(e_realQ.minus_one)lete_one_real=QED.constant(e_realQ.one)lete_zero_real=QED.constant(e_realQ.zero)lete_int64z=e_zint(Z.of_string(Int64.to_stringz))lete_factke=e_times(Z.of_intk)elete_bigintz=e_zint(Z.of_string(Integer.to_stringz))lete_rangeab=e_sum[b;e_one;e_oppa]lete_setfieldrfv=(*TODO:NUPW: check for UNIONS *)letr=List.map(fung->g,ifField.equalfgthenvelsee_getfieldrg)(fields_of_fieldf)ine_recordr(* -------------------------------------------------------------------------- *)(* --- Predicates --- *)(* -------------------------------------------------------------------------- *)typepred=termtypecmp=term->term->predtypeoperator=pred->pred->predletp_boolt=tlete_propt=tletp_boolsxs=xslete_propsxs=xslete_liftf=fletp_liftf=fletis_zeroe=matchQED.reprewith|Kintz->Integer.equalzInteger.zero|_->falseleteqp=equalletcomparep=compareletis_ptrue=is_trueletis_pfalse=is_falseletis_equalab=is_true(e_eqab)letis_inte=trytypeofe=Qed.Logic.IntwithNot_found->falseletis_reale=trytypeofe=Qed.Logic.RealwithNot_found->falseletis_prope=trymatchtypeofewithQed.Logic.Prop|Qed.Logic.Bool->true|_->falsewithNot_found->falseletis_arithe=trymatchtypeofewithQed.Logic.Int|Qed.Logic.Real->true|_->falsewithNot_found->falseletp_equal=e_eqletp_equals=List.map(fun(x,y)->p_equalxy)letp_neq=e_neqletp_leq=e_leqletp_lt=e_ltletp_positivee=e_leqe_zeroeletp_true=e_trueletp_false=e_falseletp_not=e_notletp_bind=e_bindletp_forall=e_forallletp_exists=e_existsletp_subst=e_substletp_subst_var=e_subst_varletp_andpq=e_and[p;q]letp_orpq=e_or[p;q]letp_implyhp=e_imply[h]pletp_hypshsp=e_implyhspletp_equiv=e_equivletp_if=e_ifletp_conj=e_andletp_disj=e_orletp_allfxs=e_and(List.mapfxs)letp_anyfxs=e_or(List.mapfxs)lete_varse=List.sortVar.compare(Vars.elements(varse))letp_vars=e_varsletp_call=e_fun~result:Propletp_close=e_close_forallletoccursxt=Vars.memx(varst)letintersectab=Vars.intersect(varsa)(varsb)letoccursp=occursletintersectp=intersectletvarsp=varsletp_expr=reprlete_expr=reprletpp_tau=Pretty.pp_tauletcontext_pp=Context.create"Lang.F.pp"letpp_termfmte=ifWp_parameters.has_dkeydkey_prettythenQED.debugfmteelsematchContext.get_optcontext_ppwith|Someenv->Pretty.pp_term_envenvfmte|None->letenv=Pretty.knownPretty.empty(QED.varse)inPretty.pp_termenvfmteletpp_pred=pp_termletpp_varfmtx=pp_termfmt(e_varx)letpp_varsfmtxs=beginFormat.fprintffmt"@[<hov 2>{";Vars.iter(funx->Format.fprintffmt"@ %a"pp_varx)xs;Format.fprintffmt" }@]";endletdebugp=QED.debugtypeenv=Pretty.envletenvxs=Pretty.knownPretty.emptyxsletmarker=Pretty.marksletmark_e=QED.markletmark_p=QED.markletdefinefenvm=List.fold_left(funenvt->letx,env_x=Pretty.freshenvtinfenvxt;env_x)env(QED.defsm)letpp_eterm=Pretty.pp_termletpp_epred=Pretty.pp_termmodulePmap=TmapmodulePset=Tsetletset_builtin_1fr=set_builtinf(function[e]->re|_->raiseNot_found)letset_builtin_2fr=set_builtinf(function[a;b]->rab|_->raiseNot_found)letset_builtin_2'fr=set_builtin'f(function[a;b]->rab|_->raiseNot_found)letset_builtin_eqp=set_builtin_eqendopenFmoduleN=structlet(+)=e_addlet(~-)x=e_sube_zeroxlet(-)=e_sublet(*)=e_mullet(/)=e_divlet(mod)=e_modlet(=)=p_equallet(<)=p_ltlet(>)xy=p_ltyxlet(<=)=p_leqlet(>=)xy=p_leqyxlet(<>)=p_neqlet(==>)=p_implylet(&&)=p_andlet(||)=p_orletnot=p_notlet($)=e_funlet($$)=p_callend(* -------------------------------------------------------------------------- *)(* --- Local Assumptions --- *)(* -------------------------------------------------------------------------- *)typegamma={mutablehyps:predlist;}letcpool=Context.create"Lang.pool"letcgamma=Context.create"Lang.gamma"letadd_varspool=function|None->()|Somexs->F.add_varspoolxsletnew_pool?copy?(vars=Vars.empty)()=letpool=F.pool?copy()inF.add_varspoolvars;poolletnew_gamma?copy()=matchcopywith|None->{hyps=[]}|Someg->{hyps=g.hyps}letget_pool()=Context.getcpoolletget_gamma()=Context.getcgammalethas_gamma()=Context.definedcgammaletfreshvar?basenametau=F.fresh(Context.getcpool)?basenametauletfreshenx=F.alpha(Context.getcpool)xletlocal?pool?vars?gammaf=letpool=matchpoolwithNone->F.pool()|Somep->pinadd_varspoolvars;letgamma=matchgammawithNone->{hyps=[]}|Someg->ginContext.bindcpoolpool(Context.bindcgammagammaf)letsigma()=F.sigma~pool:(Context.getcpool)()letalpha()=letsigma=sigma()inletalpha=refTmap.emptyinletlookupex=tryTmap.finde!alphawithNot_found->lety=F.Subst.freshsigma(F.tau_of_varx)inletey=e_varyinalpha:=Tmap.addeey!alpha;eyinletcomputee=matchF.reprewith|Fvarx->lookupex|_->raiseNot_foundinF.Subst.add_funsigmacompute;sigmaletsubstxsvs=letsigma=sigma()inbegintryList.iter2(funxv->F.Subst.addsigma(e_varx)v)xsvswithInvalid_argument_->raise(Invalid_argument"Wp.Lang.Subst.sigma")end;sigmalete_substf=letsigma=sigma()inF.Subst.add_funsigmaf;F.e_substsigmaletp_substf=letsigma=sigma()inF.Subst.add_funsigmaf;F.p_substsigma(* -------------------------------------------------------------------------- *)(* --- Hypotheses --- *)(* -------------------------------------------------------------------------- *)letmasked=reffalseletwithout_assumejobx=if!maskedthenjobxelsetrymasked:=true;lety=jobxinmasked:=false;ywitherr->masked:=false;raiseerrletassumep=ifp!=p_true&¬!maskedthenletd=Context.getcgammaind.hyps<-p::d.hypslethypothesesg=g.hypsletget_hypotheses()=(Context.getcgamma).hypsletfilter_hypothesesxs=letd=Context.getcgammainletvars=List.fold_rightVars.addxsVars.emptyinletmatchesp=Vars.intersectvars(varspp)inleths_with_vars,hs_without_vars=List.partitionmatchesd.hypsind.hyps<-hs_without_vars;hs_with_vars(** For why3_api but circular dependency *)moduleFor_export=structtypespecific_equality={for_tau:(tau->bool);mk_new_eq:F.binop;}(** delay the create at most as possible (due to constants handling in qed) *)letstate=refNoneletinit=ref(fun()->())letadd_initf=letold=!initininit:=(fun()->old();f())letget_state()=match!statewith|None->letst=QZERO.create()inQZERO.in_statest!init();state:=Somest;st|Somest->stletrebuild?cachet=QZERO.rebuild_in_state(get_state())?cachetletset_builtinfc=add_init(fun()->QZERO.set_builtin~force:truefc)letset_builtin'fc=add_init(fun()->QZERO.set_builtin'~force:truefc)letset_builtin_eqfc=add_init(fun()->QZERO.set_builtin_eq~force:truefc)letset_builtin_leqfc=add_init(fun()->QZERO.set_builtin_leq~force:truefc)letin_statefv=QZERO.in_state(get_state())fvend(* -------------------------------------------------------------------------- *)(* --- Simplifier --- *)(* -------------------------------------------------------------------------- *)exceptionContradictionclasstypesimplifier=objectmethodname:stringmethodcopy:simplifiermethodassume:F.pred->unitmethodtarget:F.pred->unitmethodfixpoint:unitmethodinfer:F.predlistmethodequivalent_exp:F.term->F.termmethodweaker_hyp:F.pred->F.predmethodequivalent_branch:F.pred->F.predmethodstronger_goal:F.pred->F.predendletis_atomic_pred=function|Neq_|Eq_|Leq_|Lt_|Fun_->true|_->falseletis_literalp=matchreprpwith|Notp->is_atomic_pred(reprp)|_->is_atomic_pred(reprp)letiter_consequence_literalsf_literalp=letf_literal=(funp->ifQED.lc_closedpthenf_literalpelse())inletrecaux_posp=matchreprpwith|Andps->List.iteraux_posps|Notp->aux_negp|Bind((Forall|Exists),_,a)->aux_pos(QED.lc_repra)|repwhenis_atomic_predrep->f_literalp|_->()andaux_negp=matchreprpwith|Imply(hs,p)->List.iteraux_poshs;aux_negp|Orps->List.iteraux_negps|Notp->aux_posp|Bind((Forall|Exists),_,a)->aux_neg(QED.lc_repra)|repwhenis_atomic_predrep->f_literal(e_notp)|_->()inaux_posp(* -------------------------------------------------------------------------- *)