12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031(* SPDX-License-Identifier: MIT *)(* Copyright (C) 2023-2024 formalsec *)(* Written by the Smtml programmers *)includeMappings_intfmoduleMake(M_with_make:M_with_make):S_with_fresh=structmoduleMappings:M_with_make=M_with_makemoduleMake_(M:M):S=structopenTymoduleSmap=Symbol.Maptypesymbol_ctx=M.termSmap.ttypemodel={model:M.model;ctx:symbol_ctx}typesolver={solver:M.solver;ctx:symbol_ctxStack.t;mutablelast_ctx:symbol_ctxoption(* Used to save last check-sat ctx *);mutableassumptions:Expr.tlist(* Assumptions added before the last `check_sat` *);mutableunchecked_assumptions:Expr.tlist(* Assumptions added after the last `check_sat` *);mutablelast_assumptions:Expr.tlist(* Assumptions from the last `check_sat` *)}typehandle=M.handletypeoptimize={opt:M.optimizer;ctx:symbol_ctxStack.t}leti8=M.Types.bitv8leti32=M.Types.bitv32leti64=M.Types.bitv64letf32=M.Types.float824letf64=M.Types.float1153letreal2str=M.Func.make"real_to_string "[M.Types.real]M.Types.stringletstr2real=M.Func.make"string_to_real"[M.Types.string]M.Types.realletstr_trim=M.Func.make"string_trim"[M.Types.string]M.Types.stringletf32_to_i32=M.Func.make"f32_to_i32"[f32]i32letf64_to_i64=M.Func.make"f64_to_i64"[f64]i64letget_type=function|Ty_int->M.Types.int|Ty_real->M.Types.real|Ty_bool->M.Types.bool|Ty_str->M.Types.string|Ty_bitv8->i8|Ty_bitv32->i32|Ty_bitv64->i64|Ty_bitvn->M.Types.bitvn|Ty_fp32->f32|Ty_fp64->f64|Ty_roundingMode->M.Types.roundingMode|Ty_regexp->M.Types.regexp|(Ty_fp_|Ty_list|Ty_app|Ty_unit|Ty_none)asty->Fmt.failwith"Trying to use unsupported theory: %a@."Ty.pptyletmake_symbol(ctx:symbol_ctx)(s:Symbol.t):symbol_ctx*M.term=letname=matchs.namewithSimplename->name|_->assertfalseinifM.Internals.caches_conststhenletsym=M.constname(get_types.ty)in(Smap.addssymctx,sym)elsematchSmap.find_optsctxwith|Somesym->(ctx,sym)|None->letsym=M.constname(get_types.ty)in(Smap.addssymctx,sym)moduleBool_impl=structlettrue_=M.true_letfalse_=M.false_letunop=function|Unop.Not->M.not_|op->Fmt.failwith{|Bool: Unsupported unary operator "%a"|}Unop.ppopletbinop=function|Binop.And->M.and_|Or->M.or_|Xor->M.xor|Implies->M.implies|op->Fmt.failwith{|Bool: Unsupported binary operator "%a"|}Binop.ppoplettriop=function|Triop.Ite->M.ite|op->Fmt.failwith{|Bool: Unsupported ternary operator "%a"|}Triop.ppopletrelopope1e2=matchopwith|Relop.Eq->M.eqe1e2|Ne->M.distinct[e1;e2]|_->Fmt.failwith{|Bool: Unsupported relational operator "%a"|}Relop.ppopletnaryopopl=matchopwith|Naryop.Logand->M.logandl|Logor->M.logorl|_->Fmt.failwith{|Bool: Unsupported n-ary operator "%a"|}Naryop.ppopletcvtopop_e=Fmt.failwith{|Bool: Unsupported convert operator "%a"|}Cvtop.ppopendmoduleInt_impl=structletvi=M.inti[@@inline]letunop=function|Unop.Neg->M.Int.neg|op->Fmt.failwith{|Int: Unsupported unop operator "%a"|}Unop.ppopletbinop=function|Binop.Add->M.Int.add|Sub->M.Int.sub|Mul->M.Int.mul|Div->M.Int.div|Rem->M.Int.rem|Pow->M.Int.pow|op->Fmt.failwith{|Int: Unsupported binop operator "%a"|}Binop.ppopletrelop=function|Relop.Eq->M.eq|Ne->funab->M.distinct[a;b]|Lt->M.Int.lt|Gt->M.Int.gt|Le->M.Int.le|Ge->M.Int.ge|op->Fmt.failwith{|Int: Unsupported relop operator "%a"|}Relop.ppopletcvtopope=matchopwith|Cvtop.Reinterpret_float->M.Real.to_inte|op->Fmt.failwith{|Int: Unsupported cvtop operator "%a"|}Cvtop.ppopendmoduleReal_impl=structletvf=M.realf[@@inline]letunopope=letopenMinmatchopwith|Unop.Neg->Real.nege|Abs->ite(Real.gte(real0.))e(Real.nege)|Sqrt->Real.powe(v0.5)|Ceil->letx_int=M.Real.to_inteinite(eq(Int.to_realx_int)e)x_int(Int.addx_int(int1))|Floor->Real.to_inte|Nearest|Is_nan|_->Fmt.failwith{|Real: Unsupported unop operator "%a"|}Unop.ppopletbinopope1e2=matchopwith|Binop.Add->M.Real.adde1e2|Sub->M.Real.sube1e2|Mul->M.Real.mule1e2|Div->M.Real.dive1e2|Pow->M.Real.powe1e2|Min->M.ite(M.Real.lee1e2)e1e2|Max->M.ite(M.Real.gee1e2)e1e2|_->Fmt.failwith{|Real: Unsupported binop operator "%a"|}Binop.ppopletrelopope1e2=matchopwith|Relop.Eq->M.eqe1e2|Ne->M.distinct[e1;e2]|Lt->M.Real.lte1e2|Gt->M.Real.gte1e2|Le->M.Real.lee1e2|Ge->M.Real.gee1e2|_->Fmt.failwith{|Real: Unsupported relop operator "%a"|}Relop.ppopletcvtopope=matchopwith|Cvtop.ToString->M.Func.applyreal2str[e]|OfString->M.Func.applystr2real[e]|Reinterpret_int->M.Int.to_reale|op->Fmt.failwith{|Real: Unsupported cvtop operator "%a"|}Cvtop.ppopendmoduleString_impl=structletvs=M.String.vs[@@inline]letunopope=matchopwith|Unop.Length->M.String.lengthe|Trim->M.Func.applystr_trim[e]|op->Fmt.failwith{|String: Unsupported unop operator "%a"|}Unop.ppopletbinopope1e2=matchopwith|Binop.At->M.String.ate1~pos:e2|String_contains->M.String.containse1~sub:e2|String_prefix->M.String.is_prefixe1~prefix:e2|String_suffix->M.String.is_suffixe1~suffix:e2|String_in_re->M.String.in_ree1e2|_->Fmt.failwith{|String: Unsupported binop operator "%a"|}Binop.ppoplettriopope1e2e3=matchopwith|Triop.String_extract->M.String.sube1~pos:e2~len:e3|String_index->M.String.index_ofe1~sub:e2~pos:e3|String_replace->M.String.replacee1~pattern:e2~with_:e3|String_replace_all->M.String.replace_alle1~pattern:e2~with_:e3|String_replace_re->M.String.replace_ree1~pattern:e2~with_:e3|String_replace_re_all->M.String.replace_re_alle1~pattern:e2~with_:e3|_->Fmt.failwith{|String: Unsupported triop operator "%a"|}Triop.ppopletrelopope1e2=matchopwith|Relop.Eq->M.eqe1e2|Ne->M.distinct[e1;e2]|Lt->M.String.lte1e2|Le->M.String.lee1e2|_->Fmt.failwith{|String: Unsupported relop operator "%a"|}Relop.ppopletcvtop=function|Cvtop.String_to_code->M.String.to_code|String_from_code->M.String.of_code|String_to_int->M.String.to_int|String_from_int->M.String.of_int|String_to_re->M.String.to_re|op->Fmt.failwith{|String: Unsupported cvtop operator "%a"|}Cvtop.ppopletnaryopopes=matchopwith|Naryop.Concat->M.String.concates|_->Fmt.failwith{|String: Unsupported naryop operator "%a"|}Naryop.ppopendmoduleRegexp_impl=structletunopope=matchopwith|Unop.Regexp_star->M.Re.stare|Regexp_plus->M.Re.pluse|Regexp_opt->M.Re.opte|Regexp_comp->M.Re.compe|Regexp_loop(i1,i2)->M.Re.loopei1i2|op->Fmt.failwith{|Regexp: Unsupported unop operator "%a"|}Unop.ppopletbinopope1e2=matchopwith|Binop.Regexp_range->M.Re.rangee1e2|Regexp_inter->M.Re.intere1e2|Regexp_diff->M.Re.diffe1e2|op->Fmt.failwith{|Regexp: Unsupported binop operator "%a"|}Binop.ppoplet_triop_=function|op->Fmt.failwith{|Regexp: Unsupported triop operator "%a"|}Triop.ppoplet_relop__=function|op->Fmt.failwith{|Regexp: Unsupported relop operator "%a"|}Relop.ppoplet_cvtop=function|op->Fmt.failwith{|Regexp: Unsupported cvtop operator "%a"|}Cvtop.ppopletnaryopopes=matchopwith|Naryop.Concat->M.Re.concates|Regexp_union->M.Re.uniones|op->Fmt.failwith{|Regexp: Unsupported naryop operator "%a"|}Naryop.ppopendmoduletypeBitv_sig=sigtypeeltvalv:elt->M.termvalbitwidth:intvalto_ieee_bv:M.term->M.termmoduleIxx:sigvalof_int:int->eltvalshift_left:elt->int->eltendendmoduleBitv_impl(B:Bitv_sig)=structopenMincludeB(* Stolen from @krtab in OCamlPro/owi#195 *)letclzn=letrecloop(lb:int)(ub:int)=ifub=lb+1thenv@@Ixx.of_int(bitwidth-ub)elseletmid=(lb+ub)/2inletpow_two_mid=vIxx.(shift_left(of_int1)mid)inite(Bitv.lt_unpow_two_mid)(looplbmid)(loopmidub)inite(eqn(v@@Ixx.of_int0))(v@@Ixx.of_intbitwidth)(loop0bitwidth)(* Stolen from @krtab in OCamlPro/owi #195 *)letctzn=letzero=v(Ixx.of_int0)inletrecloop(lb:int)(ub:int)=ifub=lb+1thenv(Ixx.of_intlb)elseletmid=(lb+ub)/2inletpow_two_mid=vIxx.(shift_left(of_int1)mid)inM.ite(eq(Bitv.remnpow_two_mid)zero)(loopmidub)(looplbmid)inite(eqnzero)(v@@Ixx.of_intbitwidth)(loop0bitwidth)letpopcntn=letrecloop(next:int)count=ifPrelude.Int.equalnextbitwidththencountelse(* We shift the original number so that the current bit to test is on the right. *)letshifted=Bitv.lshrn(v@@Ixx.of_intnext)in(* We compute the remainder of the shifted number *)letremainder=Bitv.rem_ushifted(v@@Ixx.of_int2)in(* The remainder is either 0 or 1, we add it directly to the count *)letcount=Bitv.addcountremainderinletnext=succnextinloopnextcountinloop0(v@@Ixx.of_int0)letunop=function|Unop.Clz->clz|Ctz->ctz|Popcnt->popcnt|Neg->Bitv.neg|Not->Bitv.lognot|op->Fmt.failwith{|Bitv: Unsupported unary operator "%a"|}Unop.ppopletbinop=function|Binop.Add->Bitv.add|Sub->Bitv.sub|Mul->Bitv.mul|Div->Bitv.div|DivU->Bitv.div_u|And->Bitv.logand|Xor->Bitv.logxor|Or->Bitv.logor|Shl->Bitv.shl|ShrA->Bitv.ashr|ShrL->Bitv.lshr|Rem->Bitv.rem|RemU->Bitv.rem_u|Rotl->Bitv.rotate_left|Rotr->Bitv.rotate_right|op->Fmt.failwith{|Bitv: Unsupported binary operator "%a"|}Binop.ppoplettriopop_=Fmt.failwith{|Bitv: Unsupported triop operator "%a"|}Triop.ppopletrelopope1e2=matchopwith|Relop.Eq->M.eqe1e2|Ne->M.distinct[e1;e2]|Lt->Bitv.lte1e2|LtU->Bitv.lt_ue1e2|Le->Bitv.lee1e2|LeU->Bitv.le_ue1e2|Gt->Bitv.gte1e2|GtU->Bitv.gt_ue1e2|Ge->Bitv.gee1e2|GeU->Bitv.ge_ue1e2letcvtopope=matchopwith|Cvtop.WrapI64->Bitv.extracte~high:(bitwidth-1)~low:0|Sign_extendn->Bitv.sign_extendne|Zero_extendn->Bitv.zero_extendne|TruncSF32|TruncSF64|Trunc_sat_f32_s|Trunc_sat_f64_s->Float.to_sbvbitwidth~rm:Float.Rounding_mode.rtze|TruncUF32|TruncUF64|Trunc_sat_f32_u|Trunc_sat_f64_u->Float.to_ubvbitwidth~rm:Float.Rounding_mode.rtze|Reinterpret_float->to_ieee_bve|ToBool->M.distinct[e;v@@Ixx.of_int0]|OfBool->itee(v@@Ixx.of_int1)(v@@Ixx.of_int0)|_->Fmt.failwith{|Bitv: Unsupported convert operator "%a"|}Cvtop.ppopendmoduleI8=Bitv_impl(structtypeelt=intletvi=M.Bitv.v(string_of_inti)8letbitwidth=8letto_ieee_bv_=Fmt.failwith{|Bitv: Unsupported operator "to_ieee_bv" for Float8|}moduleIxx=structletof_inti=i[@@inline]letshift_leftvi=vlsli[@@inline]endend)letto_ieee_bv=matchM.Float.to_ieee_bvwith|Someto_ieee_bv->fun_e->to_ieee_bve|None->funfe->M.Func.applyf[e]moduleI32=Bitv_impl(structtypeelt=int32letvi=M.Bitv.v(Int32.to_stringi)32letbitwidth=32letto_ieee_bv=to_ieee_bvf32_to_i32moduleIxx=Int32end)moduleI64=Bitv_impl(structtypeelt=int64letvi=M.Bitv.v(Int64.to_stringi)64letto_ieee_bv=to_ieee_bvf64_to_i64letbitwidth=64moduleIxx=Int64end)moduletypeFloat_sig=sigtypeeltvaleb:intvalsb:intvalzero:unit->M.termvalv:elt->M.term(* TODO: *)(* val to_string : Z3.FuncDecl.func_decl *)(* val of_string : Z3.FuncDecl.func_decl *)endmoduleFloat_impl(F:Float_sig)=structopenMincludeFletunopope=matchopwith|Unop.Neg->Float.nege|Abs->Float.abse|Sqrt->Float.sqrt~rm:Float.Rounding_mode.rnee|Is_normal->Float.is_normale|Is_subnormal->Float.is_subnormale|Is_negative->Float.is_negativee|Is_positive->Float.is_positivee|Is_infinite->Float.is_infinitee|Is_nan->Float.is_nane|Is_zero->Float.is_zeroe|Ceil->Float.round_to_integral~rm:Float.Rounding_mode.rtpe|Floor->Float.round_to_integral~rm:Float.Rounding_mode.rtne|Trunc->Float.round_to_integral~rm:Float.Rounding_mode.rtze|Nearest->Float.round_to_integral~rm:Float.Rounding_mode.rnee|_->Fmt.failwith{|FPA: Unsupported unary operator "%a"|}Unop.ppopletbinopope1e2=matchopwith|Binop.Add->Float.add~rm:Float.Rounding_mode.rnee1e2|Sub->Float.sub~rm:Float.Rounding_mode.rnee1e2|Mul->Float.mul~rm:Float.Rounding_mode.rnee1e2|Div->Float.div~rm:Float.Rounding_mode.rnee1e2|Min->Float.mine1e2|Max->Float.maxe1e2|Rem->Float.reme1e2|Copysign->letabs_float=Float.abse1inM.ite(Float.gee2(F.zero()))abs_float(Float.negabs_float)|_->Fmt.failwith{|FPA: Unsupported binop operator "%a"|}Binop.ppoplettriopop_=Fmt.failwith{|FPA: Unsupported triop operator "%a"|}Triop.ppopletrelopope1e2=matchopwith|Relop.Eq->Float.eqe1e2|Ne->not_@@Float.eqe1e2|Lt->Float.lte1e2|Le->Float.lee1e2|Gt->Float.gte1e2|Ge->Float.gee1e2|_->Fmt.failwith{|FPA: Unsupported relop operator "%a"|}Relop.ppopletcvtopope=matchopwith|Cvtop.PromoteF32|DemoteF64->Float.to_fpebsb~rm:Float.Rounding_mode.rnee|ConvertSI32|ConvertSI64->Float.sbv_to_fpebsb~rm:Float.Rounding_mode.rnee|ConvertUI32|ConvertUI64->Float.ubv_to_fpebsb~rm:Float.Rounding_mode.rnee|Reinterpret_int->Float.of_ieee_bvebsbe|ToString->(* TODO: FuncDecl.apply to_string [ e ] *)Fmt.failwith"FPA: TODO(ToString)"|OfString->(* TODO: FuncDecl.apply of_string [ e ] *)Fmt.failwith"FPA: TODO(OfString)"|_->Fmt.failwith{|FPA: Unsupported cvtop operator "%a"|}Cvtop.ppopendmoduleFloat32_impl=Float_impl(structtypeelt=int32leteb=8letsb=24letvf=M.Float.v(Int32.float_of_bitsf)ebsbletzero()=v(Int32.bits_of_float0.0)(* TODO: *)(* let to_string = *)(* Z3.FuncDecl.mk_func_decl_s ctx "F32ToString" [ fp32_sort ] str_sort *)(* let of_string = *)(* Z3.FuncDecl.mk_func_decl_s ctx "StringToF32" [ str_sort ] fp32_sort *)end)moduleFloat64_impl=Float_impl(structtypeelt=int64leteb=11letsb=53letvf=M.Float.v(Int64.float_of_bitsf)ebsbletzero()=v(Int64.bits_of_float0.0)(* TODO: *)(* let to_string = *)(* Z3.FuncDecl.mk_func_decl_s ctx "F64ToString" [ fp64_sort ] str_sort *)(* let of_string = *)(* Z3.FuncDecl.mk_func_decl_s ctx "StringToF64" [ str_sort ] fp64_sort *)end)letv:Value.t->M.term=function|True->Bool_impl.true_|False->Bool_impl.false_|Intv->Int_impl.vv|Realv->Real_impl.vv|Strv->String_impl.vv|Num(F32x)->Float32_impl.vx|Num(F64x)->Float64_impl.vx|Bitvbv->M.Bitv.v(Bitvector.to_stringbv)(Bitvector.numbitsbv)|(List_|App_|Unit|Nothing)asv->Fmt.failwith"Unsupported encoding of value '%a'"Value.ppvletunop=function|Ty.Ty_int->Int_impl.unop|Ty_real->Real_impl.unop|Ty_bool->Bool_impl.unop|Ty_str->String_impl.unop|Ty_regexp->Regexp_impl.unop|Ty_bitv8->I8.unop|Ty_bitv32->I32.unop|Ty_bitv64->I64.unop|Ty_fp32->Float32_impl.unop|Ty_fp64->Float64_impl.unop|(Ty_bitv_|Ty_fp_|Ty_list|Ty_app|Ty_unit|Ty_none|Ty_roundingMode)asty->Fmt.failwith"Unsupported encoding of unary operators for theory '%a'"Ty.pptyletbinop=function|Ty.Ty_int->Int_impl.binop|Ty_real->Real_impl.binop|Ty_bool->Bool_impl.binop|Ty_str->String_impl.binop|Ty_regexp->Regexp_impl.binop|Ty_bitv8->I8.binop|Ty_bitv32->I32.binop|Ty_bitv64->I64.binop|Ty_fp32->Float32_impl.binop|Ty_fp64->Float64_impl.binop|(Ty_bitv_|Ty_fp_|Ty_list|Ty_app|Ty_unit|Ty_none|Ty_roundingMode)asty->Fmt.failwith"Unsupported encoding of binary operators for theory '%a'"Ty.pptylettriop=function|Ty.Ty_bool->Bool_impl.triop|Ty_str->String_impl.triop|Ty_bitv8->I8.triop|Ty_bitv32->I32.triop|Ty_bitv64->I64.triop|Ty_fp32->Float32_impl.triop|Ty_fp64->Float64_impl.triop|(Ty_int|Ty_real|Ty_bitv_|Ty_fp_|Ty_list|Ty_app|Ty_unit|Ty_none|Ty_regexp|Ty_roundingMode)asty->Fmt.failwith"Unsupported encoding of ternary operators for theory '%a'"Ty.pptyletrelop=function|Ty.Ty_int->Int_impl.relop|Ty_real->Real_impl.relop|Ty_bool->Bool_impl.relop|Ty_str->String_impl.relop|Ty_bitv8->I8.relop|Ty_bitv32->I32.relop|Ty_bitv64->I64.relop|Ty_fp32->Float32_impl.relop|Ty_fp64->Float64_impl.relop|(Ty_bitv_|Ty_fp_|Ty_list|Ty_app|Ty_unit|Ty_none|Ty_regexp|Ty_roundingMode)asty->Fmt.failwith"Unsupported encoding of relop operators for theory '%a'"Ty.pptyletcvtop=function|Ty.Ty_int->Int_impl.cvtop|Ty_real->Real_impl.cvtop|Ty_bool->Bool_impl.cvtop|Ty_str->String_impl.cvtop|Ty_bitv8->I8.cvtop|Ty_bitv32->I32.cvtop|Ty_bitv64->I64.cvtop|Ty_fp32->Float32_impl.cvtop|Ty_fp64->Float64_impl.cvtop|(Ty_bitv_|Ty_fp_|Ty_list|Ty_app|Ty_unit|Ty_none|Ty_regexp|Ty_roundingMode)asty->Fmt.failwith"Unsupported encoding of convert operators for theory '%a'"Ty.pptyletnaryop=function|Ty.Ty_str->String_impl.naryop|Ty_bool->Bool_impl.naryop|Ty_regexp->Regexp_impl.naryop|ty->Fmt.failwith"Unsupported encoding of n-ary operators for theory '%a'"Ty.pptytyletget_rounding_modectxrm=matchExpr.viewrmwith|Symbol{name=Simple("roundNearestTiesToEven"|"RNE");_}->(ctx,M.Float.Rounding_mode.rne)|Symbol{name=Simple("roundNearestTiesToAway"|"RNA");_}->(ctx,M.Float.Rounding_mode.rna)|Symbol{name=Simple("roundTowardPositive"|"RTP");_}->(ctx,M.Float.Rounding_mode.rtp)|Symbol{name=Simple("roundTowardNegative"|"RTN");_}->(ctx,M.Float.Rounding_mode.rtn)|Symbol{name=Simple("roundTowardZero"|"RTZ");_}->(ctx,M.Float.Rounding_mode.rtz)|Symbolrm->make_symbolctxrm|_->Fmt.failwith"unknown rouding mode: %a"Expr.pprmletrecencode_exprctx(hte:Expr.t):symbol_ctx*M.term=matchExpr.viewhtewith|Valvalue->(ctx,vvalue)|Ptr{base;offset}->letbase=v(Bitvbase)inletctx,offset=encode_exprctxoffsetin(ctx,I32.binopAddbaseoffset)|Symbol{name=Simple"re.all";_}->(ctx,M.Re.all())|Symbol{name=Simple"re.none";_}->(ctx,M.Re.none())|Symbol{name=Simple"re.allchar";_}->(ctx,M.Re.allchar())|Symbolsym->make_symbolctxsym(* FIXME: add a way to support building these expressions without apps *)|App({name=Simple"fp.add";_},[rm;a;b])->letctx,a=encode_exprctxainletctx,b=encode_exprctxbinletctx,rm=get_rounding_modectxrmin(ctx,M.Float.add~rmab)|App({name=Simple"fp.sub";_},[rm;a;b])->letctx,a=encode_exprctxainletctx,b=encode_exprctxbinletctx,rm=get_rounding_modectxrmin(ctx,M.Float.sub~rmab)|App({name=Simple"fp.mul";_},[rm;a;b])->letctx,a=encode_exprctxainletctx,b=encode_exprctxbinletctx,rm=get_rounding_modectxrmin(ctx,M.Float.mul~rmab)|App({name=Simple"fp.div";_},[rm;a;b])->letctx,a=encode_exprctxainletctx,b=encode_exprctxbinletctx,rm=get_rounding_modectxrmin(ctx,M.Float.div~rmab)|App({name=Simple"fp.fma";_},[rm;a;b;c])->letctx,a=encode_exprctxainletctx,b=encode_exprctxbinletctx,c=encode_exprctxcinletctx,rm=get_rounding_modectxrmin(ctx,M.Float.fma~rmabc)|App({name=Simple"fp.sqrt";_},[rm;a])->letctx,a=encode_exprctxainletctx,rm=get_rounding_modectxrmin(ctx,M.Float.sqrt~rma)|App({name=Simple"fp.roundToIntegral";_},[rm;a])->letctx,a=encode_exprctxainletctx,rm=get_rounding_modectxrmin(ctx,M.Float.round_to_integral~rma)|App(sym,args)->letname=matchSymbol.namesymwith|Simplename->name|Indexed_->Fmt.failwith"Unsupported uninterpreted application of: %a"Symbol.ppsyminletty=get_type@@Symbol.type_ofsyminlettys=List.map(fune->get_type@@Expr.tye)argsinletctx,arguments=encode_exprsctxargsinletsym=M.Func.makenametystyin(ctx,M.Func.applysymarguments)|Unop(ty,op,e)->letctx,e=encode_exprctxein(ctx,unoptyope)|Binop(ty,op,e1,e2)->letctx,e1=encode_exprctxe1inletctx,e2=encode_exprctxe2in(ctx,binoptyope1e2)|Triop(ty,op,e1,e2,e3)->letctx,e1=encode_exprctxe1inletctx,e2=encode_exprctxe2inletctx,e3=encode_exprctxe3in(ctx,trioptyope1e2e3)|Relop(ty,op,e1,e2)->letctx,e1=encode_exprctxe1inletctx,e2=encode_exprctxe2in(ctx,reloptyope1e2)|Cvtop(ty,op,e)->letctx,e=encode_exprctxein(ctx,cvtoptyope)|Naryop(ty,op,es)->letctx,es=List.fold_left(fun(ctx,es)e->letctx,e=encode_exprctxein(ctx,e::es))(ctx,[])esin(* This is needed so arguments don't end up out of order in the operator *)letes=List.revesin(ctx,naryoptyopes)|Extract(e,h,l)->letctx,e=encode_exprctxein(ctx,M.Bitv.extracte~high:((h*8)-1)~low:(l*8))|Concat(e1,e2)->letctx,e1=encode_exprctxe1inletctx,e2=encode_exprctxe2in(ctx,M.Bitv.concate1e2)|Binder(Forall,vars,body)->letctx,vars=encode_exprsctxvarsinletctx,body=encode_exprctxbodyin(ctx,M.forallvarsbody)|Binder(Exists,vars,body)->letctx,vars=encode_exprsctxvarsinletctx,body=encode_exprctxbodyin(ctx,M.existsvarsbody)|List_|Binder_|Loc_->Fmt.failwith"Cannot encode expression: %a"Expr.pphteandencode_exprsctx(es:Expr.tlist):symbol_ctx*M.termlist=letctx,exprs=List.fold_left(fun(ctx,es)e->letctx,e=encode_exprctxein(ctx,e::es))(ctx,[])esin(ctx,List.revexprs)letvalue_of_term?ctxmodeltyterm=letv=matchM.Model.eval?ctx~completion:truemodeltermwith|Somev->v|None->Fmt.failwith"value_of_term: unable to fetch solver value"inmatchtywith|Ty_int->Value.Int(M.Interp.to_intv)|Ty_real->Value.Real(M.Interp.to_realv)|Ty_bool->ifM.Interp.to_boolvthenValue.TrueelseValue.False|Ty_str->letstr=M.Interp.to_stringvinValue.Strstr|Ty_bitv1->letb=M.Interp.to_bitvv1inifZ.equalbZ.onethenValue.Trueelse(assert(Z.equalbZ.zero);Value.False)|Ty_bitvm->Value.Bitv(Bitvector.make(M.Interp.to_bitvvm)m)|Ty_fp32->letfloat=M.Interp.to_floatv824inValue.Num(F32(Int32.bits_of_floatfloat))|Ty_fp64->letfloat=M.Interp.to_floatv1153inValue.Num(F64(Int64.bits_of_floatfloat))|Ty_fp_|Ty_list|Ty_app|Ty_unit|Ty_none|Ty_regexp|Ty_roundingMode->Fmt.failwith"value_of_term: unsupported model completion for theory '%a'"Ty.pptyletvalue({model=m;ctx}:model)(c:Expr.t):Value.t=letctx,e=encode_exprctxcinvalue_of_term~ctxm(Expr.tyc)eletvalues_of_model?symbols({model;ctx}asmodel0)=letm=Hashtbl.create512in(matchsymbolswith|Somesymbols->List.iter(funsym->letv=valuemodel0(Expr.symbolsym)inHashtbl.replacemsymv)symbols|None->Smap.iter(fun(sym:Symbol.t)term->letv=value_of_term~ctxmodelsym.tyterminHashtbl.replacemsymv)ctx);mletset_debug_=()moduleSmtlib=structletpp?name?logic?statusfmthtes=(* FIXME: I don't know if encoding with the empty map is ok :\ *)let_,terms=encode_exprsSmap.emptyhtesinM.Smtlib.pp?name?logic?statusfmttermsendmoduleSolver=structletmake?params?logic()=letctx=Stack.create()inStack.pushSmap.emptyctx;{solver=M.Solver.make?params?logic();ctx;last_ctx=None;assumptions=[];unchecked_assumptions=[];last_assumptions=[]}letclone{solver;ctx;last_ctx;assumptions;unchecked_assumptions;last_assumptions}={solver=M.Solver.clonesolver;ctx=Stack.copyctx;last_ctx;assumptions;unchecked_assumptions;last_assumptions}letpush{solver;ctx;_}=matchStack.top_optctxwith|None->Fmt.failwith"Solver.push: invalid solver stack state"|Sometop->Stack.pushtopctx;M.Solver.pushsolverletpop{solver;ctx;_}n=matchStack.pop_optctxwith|None->Fmt.failwith"Solver.pop: stack is empty"|Some_->M.Solver.popsolvernletreset(s:solver)=Stack.clears.ctx;Stack.pushSmap.emptys.ctx;s.last_ctx<-None;s.assumptions<-[];s.unchecked_assumptions<-[];s.last_assumptions<-[];M.Solver.resets.solverletadd(s:solver)(exprs:Expr.tlist)=matchStack.pop_opts.ctxwith|None->Fmt.failwith"Solver.add: current solver context not found"|Somectx->ifOption.is_someUtils.query_log_paththens.unchecked_assumptions<-List.rev_appendexprss.unchecked_assumptions;letctx,exprs=encode_exprsctxexprsinStack.pushctxs.ctx;M.Solver.adds.solver~ctxexprsletcheck(s:solver)~assumptions=matchStack.top_opts.ctxwith|None->Fmt.failwith"Solver.check: invalid solver stack state"|Somectx->ifOption.is_someUtils.query_log_paththen(s.assumptions<-s.unchecked_assumptions@s.assumptions;s.unchecked_assumptions<-[];s.last_assumptions<-assumptions);letctx,encoded_assuptions=encode_exprsctxassumptionsins.last_ctx<-Somectx;Utils.run_and_log_query~model:false(fun()->M.Solver.checks.solver~ctx~assumptions:encoded_assuptions)M.Internals.name(List.revassumptions)letmodel{solver;last_ctx;assumptions;last_assumptions;_}=matchlast_ctxwith|Somectx->Utils.run_and_log_query~model:true(fun()->M.Solver.modelsolver|>Option.map(funm->{model=m;ctx}))M.Internals.name(List.rev_appendassumptions(List.revlast_assumptions))|None->Fmt.failwith"model: Trying to fetch model before check-sat call"letadd_simplifiers={swithsolver=M.Solver.add_simplifiers.solver}letinterrupt_=M.Solver.interrupt()letget_statistics{solver;_}=M.Solver.get_statisticssolverendmoduleOptimizer=structletmake()=letctx=Stack.create()inStack.pushSmap.emptyctx;{opt=M.Optimizer.make();ctx}letpush{opt;_}=M.Optimizer.pushoptletpop{opt;_}=M.Optimizer.popoptletadd(o:optimize)exprs=matchStack.pop_opto.ctxwith|None->Fmt.failwith"Solver.add: current solver context not found"|Somectx->letctx,exprs=encode_exprsctxexprsinStack.pushctxo.ctx;M.Optimizer.addo.optexprsletcheck{opt;_}=M.Optimizer.checkoptletmodel{opt;ctx}=matchStack.top_optctxwith|None->Fmt.failwith"Solver.add: current solver context not found"|Somectx->M.Optimizer.modelopt|>Option.map(funm->{model=m;ctx})letmaximize(o:optimize)(expr:Expr.t)=matchStack.pop_opto.ctxwith|None->Fmt.failwith"Solver.add: current solver context not found"|Somectx->letctx,expr=encode_exprctxexprinStack.pushctxo.ctx;M.Optimizer.maximizeo.optexprletminimize(o:optimize)(expr:Expr.t)=matchStack.pop_opto.ctxwith|None->Fmt.failwith"Solver.add: current solver context not found"|Somectx->letctx,expr=encode_exprctxexprinStack.pushctxo.ctx;M.Optimizer.minimizeo.optexprletinterrupt_=M.Optimizer.interrupt()letget_statistics{opt;_}=M.Optimizer.get_statisticsoptendendmoduleFresh=structmoduleMake()=Make_(M_with_make.Make())endletis_available=M_with_make.is_availableincludeMake_(M_with_make)end