1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117(**************************************************************************)(* *)(* 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:nameinMtypemletfield_observers=ref[]letfield_observefd=List.iter(funk->kfd)!field_observers;fdleton_fieldf=field_observers:=f::!field_observersletcfield?(kind=KValue)fd=field_observe@@Cfield(fd,kind)letrecord~link~libraryfts=letm=new_extern~link~library~debug:linkinletr={fields=[]}inletfs=List.map(fun(f,t)->field_observe@@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 *)|FUNoflsymbol(** Generated or External function *)andlsymbol={m_category:lfuncategory;m_params:sortlist;m_result:sort;m_typeof:tauoptionlist->tau;m_source:source;m_coloring:bool;}andsource=|GeneratedofWpContext.contextoption*string|ExternofEngine.linkexternletlfun_observers=ref[]letlfun_observelf=List.iter(funk->klf)!lfun_observers;lfleton_lfunf=lfun_observers:=f::!lfun_observersletacsllf=lfun_observe(ACSLlf)letctorcf=lfun_observe(CTORcf)letlsymbolm=lfun_observe(FUNm)lettau_of_lfunphits=matchphiwith|ACSLf->tau_of_returnf.l_type|CTORc->ifc.ctor_type.lt_params=[]thenLogic.Data(Atypec.ctor_type,[])elseraiseNot_found|FUNm->matchm.m_resultwith|Sint->Int|Sreal->Real|Sbool->Bool|_->m.m_typeoftsletis_coloring_lfun=function|ACSL_|CTOR_->false|FUN{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->sortinlsymbol{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.debuglinkinlsymbol{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_calllinkinlsymbol{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=lsymbol{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|FUN({m_source=Generated(_,n)})->n|FUN({m_source=Externe})->e.ext_debuglethash=function|ACSLf->Logic_info.hashf|CTORc->Logic_ctor_info.hashc|FUN({m_source=Generated(_,n)})->Datatype.String.hashn|FUN({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|FUN{m_source=mf},FUN{m_source=mg}->compare_sourcemfmg|FUN_,_->(-1)|_,FUN_->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|FUNm->m.m_category|ACSL_->Logic.Function|CTOR_->Logic.Constructorletsort=function|FUNm->m.m_result|ACSL{l_type=None}->Logic.Sprop|ACSL{l_type=Somet}->sort_of_ltypet|CTOR_->Logic.Sdataletparameters=ref(fun_->[])letparams=function|FUNm->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))|FUN({m_source=Generated(_,n)})->Engine.F_call(self#sanitize_funn)|FUN({m_source=Externe})->e.ext_linkendletname_of_lfun=function|ACSLf->logic_idf|CTORc->ctor_idc|FUN({m_source=Generated(_,f)})->f|FUN({m_source=Externe})->e.ext_debugletcontext_of_lfun=function|ACSL_|CTOR_|FUN({m_source=Extern_})->None|FUN({m_source=Generated(ctxt,_)})->ctxtletname_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_getfletset_builtin_fieldf=QZERO.set_builtin_fieldf(* -------------------------------------------------------------------------- *)(* --- 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(* -------------------------------------------------------------------------- *)