123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313(**************************************************************************)(* *)(* 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). *)(* *)(**************************************************************************)(* -------------------------------------------------------------------------- *)(* --- Exportation Engine for Why-3 --- *)(* -------------------------------------------------------------------------- *)openLogicopenFormatopenExportopenEnginemoduleMake(T:Term)=structmoduleT=TmoduleE=Export_whycore.Make(T)moduleEnv=E.EnvopenTtypetau=(Field.t,ADT.t)datatypetypetrigger=(var,Fun.t)ftriggertypetypedef=(tau,Field.t,Fun.t)ftypedefclassvirtualengine=object(self)inheritE.engineassupermethod!sanitize=Export.sanitize~to_lowercase:true(* -------------------------------------------------------------------------- *)(* --- Types --- *)(* -------------------------------------------------------------------------- *)method!pp_taufmt=function|Prop->assertfalse(* prop should never be printed *)|x->super#pp_taufmtxmethodt_atomic=function|Int|Real|Bool|Prop|Tvar_->true|Array_->false|Data(_,[])->true|Data_->false|Record_->truemethodpp_farrayfmtab=fprintffmt"map %a %a"self#pp_subtauaself#pp_subtaubmethodpp_arrayfmtb=fprintffmt"map int %a"self#pp_subtaubmethodpp_datatypeadtfmt=function|[]->pp_print_stringfmt(self#datatypeadt)|ts->Plib.pp_call_apply~f:(self#datatypeadt)self#pp_subtaufmtts(* -------------------------------------------------------------------------- *)(* --- Primitives --- *)(* -------------------------------------------------------------------------- *)methodcallstyle=CallApplymethodop_spaced(_:string)=truemethodpp_array_cstfmt(key:tau)v=tryletelt=T.typeofvinlettau=Array(key,elt)infprintffmt"@[<hov 2>(const@ %a@ : %a)@]"self#pp_atomvself#pp_tautauwithNot_found->fprintffmt"@[<hov 2>(const@ %a)@]"self#pp_atomv(* -------------------------------------------------------------------------- *)(* --- Arithmetics --- *)(* -------------------------------------------------------------------------- *)methodpp_intamodefmtk=matchamodewith|Aint->pp_print_stringfmt(Z.to_stringk)|Areal->ifZ.ltkZ.zerothen(* unary minus is -. instead of - in Why3... *)fprintffmt"-.%s.0"(Z.to_string(Z.negk))elsefprintffmt"%s.0"(Z.to_stringk)methodpp_realfmtr=ifZ.equalr.Q.denZ.onethenself#pp_intArealfmtr.Q.numelsefprintffmt"(%a@ /. %a)"(self#pp_intAreal)r.Q.num(self#pp_intAreal)r.Q.denmethodop_real_of_int=Call"real_of_int"methodop_add=functionAint->Assoc"+"|Areal->Assoc"+."methodop_sub=functionAint->Assoc"-"|Areal->Assoc"-."methodop_mul=functionAint->Assoc"*"|Areal->Assoc"*."methodop_div=functionAint->Call"div"|Areal->Op"/."methodop_mod=functionAint->Call"mod"|Areal->Call"rmod"methodop_minus=functionAint->Op"-"|Areal->Op"-."methodop_eqcmode(_:amode)=matchcmodewith|Cprop->Op"="|Cterm->Call"eqb"methodop_neqcmode(_:amode)=matchcmodewith|Cprop->Op"<>"|Cterm->Call"neqb"methodop_ltcmodeamode=matchcmode,amodewith|Cprop,Aint->Op"<"|Cprop,Areal->Op"<."|Cterm,Aint->Call"zlt"|Cterm,Areal->Call"rlt"methodop_leqcmodeamode=matchcmode,amodewith|Cprop,Aint->Op"<="|Cprop,Areal->Op"<=."|Cterm,Aint->Call"zleq"|Cterm,Areal->Call"rleq"(* -------------------------------------------------------------------------- *)(* --- Logical Connectives --- *)(* -------------------------------------------------------------------------- *)methode_true=functionCterm->"True"|Cprop->"true"methode_false=functionCterm->"False"|Cprop->"false"methodop_equal=functionCterm->Call"eqb"|Cprop->Op"="methodop_noteq=functionCterm->Call"neqb"|Cprop->Op"<>"methodop_not=functionCprop->Op"not"|Cterm->Call"notb"methodop_and=functionCprop->Assoc"/\\"|Cterm->Call"andb"methodop_or=functionCprop->Assoc"\\/"|Cterm->Call"orb"methodop_imply=functionCprop->Assoc"->"|Cterm->Call"implb"methodop_equiv=functionCprop->Op"<->"|Cterm->Op"="(* -------------------------------------------------------------------------- *)(* --- Conditional --- *)(* -------------------------------------------------------------------------- *)methodpp_conditionalfmtabc=beginfprintffmt"@[<hov 0>if ";self#with_modeMpositive(fun_->self#pp_atomfmta);fprintffmt"@ then %a"self#pp_atomb;fprintffmt"@ else %a"self#pp_atomc;fprintffmt"@]";end(* -------------------------------------------------------------------------- *)(* --- Atomicity --- *)(* -------------------------------------------------------------------------- *)methodis_atomice=matchT.reprewith|Kintz->Z.leqZ.zeroz|Apply(_,[])->false|Apply_->true|Acst_|Aset_|Aget_->true|_->T.is_simplee(* -------------------------------------------------------------------------- *)(* --- Records --- *)(* -------------------------------------------------------------------------- *)methodop_record="{","}"(* -------------------------------------------------------------------------- *)(* --- Binders --- *)(* -------------------------------------------------------------------------- *)methodpp_letfmt(_:pmode)xe=fprintffmt"@[<hov 4>let %s = %a in@]@ "xself#pp_flowemethodpp_foralltaufmt=function|[]->()|x::xs->fprintffmt"@[<hov 2>forall %a"self#pp_varx;List.iter(funx->fprintffmt"@ %a"self#pp_varx)xs;fprintffmt"@ : %a.@]"self#pp_tautau;methodpp_introstaufmt=function|[]->()|x::xs->fprintffmt"@[<hov 2>forall %a"self#pp_varx;List.iter(funx->fprintffmt"@ %a"self#pp_varx)xs;fprintffmt"@ : %a@]"self#pp_tautau;methodpp_existstaufmt=function|[]->()|x::xs->fprintffmt"@[<hov 2>exists %a"self#pp_varx;List.iter(funx->fprintffmt"@ %a"self#pp_varx)xs;fprintffmt"@ : %a.@]"self#pp_tautau;methodpp_triggerfmtt=letrecprettyfmt=function|TgAny->assertfalse|TgVarx->self#pp_varfmt(self#findx)|TgGet(t,k)->fprintffmt"@[<hov 2>%a[%a]@]"prettytprettyk|TgSet(t,k,v)->fprintffmt"@[<hov 2>%a[%a@ <- %a]@]"prettytprettykprettyv|TgFun(f,ts)->callCtermffmtts|TgProp(f,ts)->callCpropffmttsandcallmodeffmtts=matchself#linkf,modewith|F_callf,_|F_bool_prop(f,_),Cterm|F_bool_prop(_,f),Cprop->Plib.pp_call_apply~fprettyfmtts|F_leftf,_->Plib.pp_fold_apply~fprettyfmtts|F_rightf,_->Plib.pp_fold_apply_rev~fprettyfmt(List.revts)|F_assocop,_->Plib.pp_assoc~opprettyfmtts|F_subst(_,s),_->Plib.substitute_listprettysfmtts|F_list(fc,fn),_->letrecplistfcfnfmt=function|[]->pp_print_stringfmtfn|x::xs->fprintffmt"[<hov 2>(%s@ %a@ %a)@]"fcprettyx(plistfcfn)xsinplistfcfnfmttsinfprintffmt"@[<hov 2>%a@]"prettyt(* -------------------------------------------------------------------------- *)(* --- Declarations --- *)(* -------------------------------------------------------------------------- *)methodpp_declare_adtfmtadtn=beginfprintffmt"type %s"(self#datatypeadt);fori=1tondoself#pp_tvarfmtidone;endmethodpp_declare_deffmtadtndef=beginfprintffmt"@[<hov 4>";self#pp_declare_adtfmtadtn;fprintffmt"@ = %a@]"self#pp_taudef;endmethodpp_declare_sumfmtadtncases=beginfprintffmt"@[<hv 1>";self#pp_declare_adtfmtadtn;List.iter(fun(c,ts)->fprintffmt"@ @[<hov 4>| %s@]"(link_name(self#linkc));List.iter(funt->fprintffmt"@ %a"self#pp_taut)ts;)cases;fprintffmt"@]"endmethoddeclare_signaturefmtftst=beginletcmode=Export.ctautinfprintffmt"@[<hov 4>%a"(self#pp_declare_symbolcmode)f;List.iter(funt->fprintffmt"@ %a"self#pp_subtaut)ts;matchtwith|Prop->fprintffmt"@]@\n"|_->fprintffmt"@ : %a@]@\n"self#pp_taut;endmethoddeclare_definitionfmtfxste=self#globalbeginfun()->letcmode=Export.ctautinfprintffmt"@[<hov 4>%a"(self#pp_declare_symbolcmode)f;List.iter(funx->leta=self#bindxinlett=T.tau_of_varxinfprintffmt"@ (%a : %a)"self#pp_varaself#pp_taut)xs;matchcmodewith|Cprop->fprintffmt" =@ @[<hov 0>%a@]@]@\n"self#pp_prope|Cterm->fprintffmt" : %a =@ @[<hov 0>%a@]@]@\n"self#pp_taut(self#pp_exprt)eendmethoddeclare_fixpoint~prefixfmtfxste=beginself#declare_signaturefmtf(List.maptau_of_varxs)t;letfix=prefix^(link_name(self#linkf))inself#declare_axiomfmtfixxs[](e_eq(e_fun~result:tf(List.mape_varxs))e);endendend