123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920(* SPDX-License-Identifier: MIT *)(* Copyright (C) 2023-2024 formalsec *)(* Written by Hichem Rami Ait El Hara *)moduleDExpr=Dolmen_std.ExprmoduleDTy=DExpr.TymoduleDTerm=DExpr.TermmoduleDBuiltin=Dolmen_std.BuiltinmoduleBuiltin=struct(* additional builtins *)letstring_ty_cst:DExpr.Term.ty_const=DExpr.Id.mk~builtin:DBuiltin.Base(Dolmen_std.Path.global"StringTy")DExpr.{arity=0;alias=No_alias}letstring_ty=DTy.applystring_ty_cst[]letfloat32_ty=DTy.float824letfloat64_ty=DTy.float1153letint_to_string:DExpr.term_cst=DExpr.Id.mk~name:"IntToString"~builtin:DBuiltin.Base(Dolmen_std.Path.global"IntToString")(DTy.arrow[DTy.int]string_ty)letstring_to_int:DExpr.term_cst=DExpr.Id.mk~name:"StringToInt"~builtin:DBuiltin.Base(Dolmen_std.Path.global"StringToInt")(DTy.arrow[string_ty]DTy.int)letreal_to_string:DExpr.term_cst=DExpr.Id.mk~name:"RealToString"~builtin:DBuiltin.Base(Dolmen_std.Path.global"RealToString")(DTy.arrow[DTy.real]string_ty)letstring_to_real:DExpr.term_cst=DExpr.Id.mk~name:"StringToReal"~builtin:DBuiltin.Base(Dolmen_std.Path.global"StringToReal")(DTy.arrow[string_ty]DTy.real)letreal_to_uint32:DExpr.term_cst=DExpr.Id.mk~name:"RealToUInt32"~builtin:DBuiltin.Base(Dolmen_std.Path.global"RealToUInt32")(DTy.arrow[DTy.real]DTy.real)lettrim_string:DExpr.term_cst=DExpr.Id.mk~name:"TrimString"~builtin:DBuiltin.Base(Dolmen_std.Path.global"TrimString")(DTy.arrow[string_ty]string_ty)letf32_to_string:DExpr.term_cst=DExpr.Id.mk~name:"F32ToString"~builtin:DBuiltin.Base(Dolmen_std.Path.global"F32ToString")(DTy.arrow[float32_ty]string_ty)letstring_to_f32:DExpr.term_cst=DExpr.Id.mk~name:"StringToF32"~builtin:DBuiltin.Base(Dolmen_std.Path.global"StringToF32")(DTy.arrow[string_ty]float32_ty)letf64_to_string:DExpr.term_cst=DExpr.Id.mk~name:"F64ToString"~builtin:DBuiltin.Base(Dolmen_std.Path.global"F64ToString")(DTy.arrow[float64_ty]string_ty)letstring_to_f64:DExpr.term_cst=DExpr.Id.mk~name:"StringToF64"~builtin:DBuiltin.Base(Dolmen_std.Path.global"StringToF64")(DTy.arrow[string_ty]float64_ty)endmoduleDolmenIntf=structincludeDTermtypety=DTy.ttypeterm=DTerm.ttypefunc_decl=DTerm.Const.tletcaches_consts=falselettrue_=DTerm._trueletfalse_=DTerm._falseletinti=DTerm.Int.mk(string_of_inti)letrealr=DTerm.Real.mk(string_of_floatr)letconststy=DTerm.of_cst(DTerm.Const.mk(Dolmen_std.Path.globals)ty)letnot_=DTerm.negletand_ab=DTerm._and[a;b]letor_ab=DTerm._or[a;b]letlogand=DTerm._andletlogor=DTerm._orletget_vars_from_termstl=List.map(fun(t:DTerm.t)->matcht.term_descrwith|Varv->v|_->Fmt.failwith{|Can't quantify non-variable term "%a"|}DTerm.printt)tlletforalltlt=lettvl=get_vars_from_termstlinDTerm.all([],tvl)tletexists(tl:termlist)t=lettvl=get_vars_from_termstlinDTerm.ex([],tvl)tletnary_to_binaryftl=letrecauxacc=function|[]->acc|h::t->aux(DTerm.apply_cstf[][acc;h])tinmatchtlwith|h1::h2::t->aux(DTerm.apply_cstf[][h1;h2])t|_->Fmt.failwith{|%a applied to less than two terms|}DTerm.Const.printfletint_of_term(t:DTerm.t)=matcht.term_descrwith|Cst{builtin=DBuiltin.Integeri;_}->(* There may be a proper alternative to int_of_string somewhere,
since its hidden by prelude. *)Z.to_int(Z.of_stringi)|_->Fmt.failwith{|int_of_term: expected a term that is an integer constant, instead got: %a|}DTerm.printtmoduleTypes=structincludeDTyletty=DTerm.tyletto_ety(ty:DTy.t):Ty.t=matchtywith|{ty_descr=TyApp({builtin=DBuiltin.Int;_},_);_}->Ty_int|{ty_descr=TyApp({builtin=DBuiltin.Real;_},_);_}->Ty_real|{ty_descr=TyApp({builtin=DBuiltin.Prop;_},_);_}->Ty_bool|{ty_descr=TyApp({builtin=DBuiltin.Base;path=Absolute{name="StringTy";_};_},_);_}->Ty_str|{ty_descr=TyApp({builtin=DBuiltin.Bitvn;_},_);_}->Ty_bitvn|{ty_descr=TyApp({builtin=DBuiltin.Float(8,24);_},_);_}->Ty_fp32|{ty_descr=TyApp({builtin=DBuiltin.Float(11,53);_},_);_}->Ty_fp64|_->Fmt.failwith{|Unsupported dolmen type "%a"|}DTy.printtyendmoduleInt=structincludeDTerm.Intletneg=DTerm.Int.minusendmoduleReal=structincludeDTerm.Realletneg=DTerm.Real.minusendmoduleString=structincludeDTerm.Stringletv=DTerm.String.of_ustringletto_re=DTerm.String.RegLan.of_stringletatt~pos=DTerm.String.attposletconcat=nary_to_binaryDTerm.Const.String.concatletcontainst~sub=DTerm.String.containstsubletis_prefixt~prefix=DTerm.String.is_prefixtprefixletis_suffixt~suffix=DTerm.String.is_suffixtsuffixletle=DTerm.String.leqletsubt~pos~len=DTerm.String.subtposlenletindex_oft~sub~pos=DTerm.String.index_oftsubposletreplacet~pattern~with_=DTerm.String.replacetpatternwith_endmoduleRe=structletstar=DTerm.String.RegLan.starletplus=DTerm.String.RegLan.crossletopt=DTerm.String.RegLan.optionletcomp=DTerm.String.RegLan.complementletrange=DTerm.String.RegLan.rangeletloopti1i2=DTerm.String.RegLan.loopi1i2tletunion=nary_to_binaryDTerm.Const.String.Reg_Lang.unionletconcat=nary_to_binaryDTerm.Const.String.Reg_Lang.concatendmoduleBitv=structincludeDTerm.Bitvletvbvn=letbv=Z.format(Fmt.str"%c0%db"'%'n)(Z.of_stringbv)inDTerm.Bitv.mkbvletlognot=DTerm.Bitv.notletdiv=DTerm.Bitv.sdivletdiv_u=DTerm.Bitv.udivletlogor=DTerm.Bitv.or_letlogand=DTerm.Bitv.and_letlogxor=DTerm.Bitv.xorletshl=DTerm.Bitv.shlletashr=DTerm.Bitv.ashrletlshr=DTerm.Bitv.lshrletrem=DTerm.Bitv.sremletrem_u=DTerm.Bitv.uremletrotate_leftt1t2=DTerm.Bitv.rotate_left(int_of_termt1)t2letrotate_rightt1t2=DTerm.Bitv.rotate_right(int_of_termt1)t2letltt1t2=DTerm.Bitv.sltt1t2letlt_ut1t2=DTerm.Bitv.ultt1t2letle=DTerm.Bitv.sleletle_u=DTerm.Bitv.uleletgtt1t2=DTerm.Bitv.sgtt1t2letgt_ut1t2=DTerm.Bitv.ugtt1t2letge=DTerm.Bitv.sgeletge_u=DTerm.Bitv.ugeletextractt~high~low=DTerm.Bitv.extracthighlowtendmoduleFloat=structincludeDTerm.FloatmoduleRounding_mode=structletrne=DTerm.Float.roundNearestTiesToEvenletrna=DTerm.Float.roundNearestTiesToAwayletrtp=DTerm.Float.roundTowardPositiveletrtn=DTerm.Float.roundTowardNegativeletrtz=DTerm.Float.roundTowardZeroendletvfes=DTerm.Float.real_to_fpesDTerm.Float.roundTowardZero(DTerm.Real.mk(Prelude.Float.to_stringf))letsqrt~rmt=DTerm.Float.sqrtrmtletis_nan=DTerm.Float.isNaNletround_to_integral~rmt=DTerm.Float.roundToIntegralrmtletadd~rmt1t2=DTerm.Float.addrmt1t2letsub~rmt1t2=DTerm.Float.subrmt1t2letmul~rmt1t2=DTerm.Float.mulrmt1t2letdiv~rmt1t2=DTerm.Float.divrmt1t2letle=DTerm.Float.leqletge=DTerm.Float.geqletto_fpes~rmfp=DTerm.Float.to_fpesrmfpletsbv_to_fpes~rmbv=DTerm.Float.sbv_to_fpesrmbvletubv_to_fpes~rmbv=DTerm.Float.ubv_to_fpesrmbvletto_ubvn~rmfp=DTerm.Float.to_ubvnrmfpletto_sbvn~rmfp=DTerm.Float.to_sbvnrmfpletof_ieee_bv_eb_sb_bv=assertfalseletto_ieee_bv_fp=assertfalseendmoduleFunc=structletmakenametylty=DTerm.Const.mk(Dolmen_std.Path.globalname)(DTy.arrowtylty)letapplyftl=DTerm.apply_cstf[]tlendmoduleSmtlib=structletpp?name:_?logic:_?status:_=Fmt.listDTerm.printendendlettty_of_etype(e:Ty.t):DTy.t=matchewith|Ty_int->DTy.int|Ty_real->DTy.real|Ty_bool->DTy.bool|Ty_str->Builtin.string_ty|Ty_bitv8->DTy.bitv8|Ty_bitv32->DTy.bitv32|Ty_bitv64->DTy.bitv64|Ty_fp32->Builtin.float32_ty|Ty_fp64->Builtin.float64_ty|Ty_fp_|Ty_bitv_|Ty_list|Ty_app|Ty_unit|Ty_none|Ty_regexp->Fmt.failwith{|Unsupported type "%a"|}Ty.ppelettty_to_etype(ty:DTy.t):Ty.t=matchtywith|{ty_descr=TyApp({builtin=DBuiltin.Int;_},_);_}->Ty_int|{ty_descr=TyApp({builtin=DBuiltin.Real;_},_);_}->Ty_real|{ty_descr=TyApp({builtin=DBuiltin.Prop;_},_);_}->Ty_bool|{ty_descr=TyApp({builtin=DBuiltin.Base;path=Absolute{name="StringTy";_};_},_);_}->Ty_str|{ty_descr=TyApp({builtin=DBuiltin.Bitvn;_},_);_}->Ty_bitvn|{ty_descr=TyApp({builtin=DBuiltin.Float(8,24);_},_);_}->Ty_fp32|{ty_descr=TyApp({builtin=DBuiltin.Float(11,53);_},_);_}->Ty_fp64|_->Fmt.failwith{|Unsupported dolmen type "%a"|}DTy.printtymoduleSHT=Hashtbl.Make(structincludeSymbollethash=Hashtbl.hashend)letsym_cache=SHT.create17lettcst_of_symbol(s:Symbol.t)=matchSHT.find_optsym_cacheswith|None->letx=Symbol.to_stringsandt=Symbol.type_ofsinletcst=DTerm.Const.mk(Dolmen_std.Path.globalx)(tty_of_etypet)inSHT.addsym_cachescst;cst|Somec->clettcst_to_symbol(c:DExpr.term_cst):Symbol.t=matchcwith|{builtin=DBuiltin.Base;path=Local{name}|Absolute{name;_};id_ty;_}->Symbol.make(tty_to_etypeid_ty)name|_->Fmt.failwith{|Unsupported constant term "%a"|}DExpr.Print.term_cstctypeexpr=DTerm.tmoduleI=structopenTyletencode_vali=DTerm.Int.mk(Int.to_stringi)letencode_unopope=letop'=matchopwith|Unop.Neg->DTerm.Int.minus|_->Fmt.failwith{|Int: Unsupported unop operator "%a"|}Unop.ppopinop'eletencode_binopope1e2=letop'=matchopwith|Binop.Add->DTerm.Int.add|Sub->DTerm.Int.sub|Mul->DTerm.Int.mul|Div->DTerm.Int.div|Rem->DTerm.Int.rem|Pow->fun_e1_e2->assertfalse(* DTerm.apply_cst
Colibri2_theories_LRA.RealValue.Builtin.colibri_pow_int_int []
[ e1; e2 ] *)|_->Fmt.failwith"{|Unsupported binop operation %a|}"Binop.ppopinop'e1e2letencode_relopope1e2=letop'=matchopwith|Relop.Eq->DTerm.eq|Ne->DTerm.neq|Lt->DTerm.Int.lt|Gt->DTerm.Int.gt|Le->DTerm.Int.le|Ge->DTerm.Int.ge|_->Fmt.failwith{|Arith: Unsupported relop operator "%a"|}Relop.ppopinop'e1e2letencode_cvtopope=letop'=matchopwith|Cvtop.ToString->funv->DTerm.apply_cstBuiltin.int_to_string[][v]|OfString->funv->DTerm.apply_cstBuiltin.string_to_int[][v]|_->Fmt.failwith{|Int: Unsupported cvtop operator "%a"|}Cvtop.ppopinop'eletencode_triopop___=Fmt.failwith{|Arith: Unsupported triop operator "%a"|}Triop.ppopendmoduleReal=structopenTyletencode_valf=DTerm.Real.mk(Float.to_stringf)letencode_unopope=letop'=matchopwith|Unop.Neg->DTerm.Real.minus|Abs->assertfalse|Sqrt->assertfalse|Ceil->fun_e->assertfalse(* DTerm.apply_cst Colibri2_theories_LRA.RealValue.Builtin.colibri_ceil
[] [ e ] *)|Floor->DTerm.Real.floor|Nearest|Is_nan|_->Fmt.failwith{|Real: Unsupported cvtop operator "%a"|}Unop.ppopinop'eletencode_binopope1e2=letop'=matchopwith|Binop.Add->DTerm.Real.add|Sub->DTerm.Real.sub|Mul->DTerm.Real.mul|Div->DTerm.Real.div|Min->fune1e2->DTerm.ite(DTerm.Real.lee1e2)e1e2|Max->fune1e2->DTerm.ite(DTerm.Real.lee1e2)e2e1|_->Fmt.failwith{|Real: Unsupported binop operator "%a"|}Binop.ppopinop'e1e2letencode_relopope1e2=letop'=matchopwith|Relop.Eq->DTerm.eq|Ne->DTerm.neq|Lt->DTerm.Real.lt|Gt->DTerm.Real.gt|Le->DTerm.Real.le|Ge->DTerm.Real.ge|_->Fmt.failwith{|Arith: Unsupported relop operator "%a"|}Relop.ppopinop'e1e2letencode_cvtopope=letop'=matchopwith|Cvtop.ToString->funv->DTerm.apply_cstBuiltin.real_to_string[][v]|OfString->funv->DTerm.apply_cstBuiltin.string_to_real[][v]|ConvertUI32->funt->DTerm.apply_cstBuiltin.real_to_uint32[][t]|Reinterpret_int->DTerm.Int.to_real|_->Fmt.failwith{|Real: Unsupported cvtop operator "%a"|}Cvtop.ppopinop'eletencode_triopop___=Fmt.failwith{|Arith: Unsupported triop operator "%a"|}Triop.ppopendmoduleBoolean=structopenTyletencode_unopope=letop'=matchopwith|Unop.Not->DTerm.neg|_->Fmt.failwith{|Bool: Unsupported unop operator "%a"|}Unop.ppopinop'eletencode_binopope1e2=letop'=matchopwith|Binop.And->funab->DTerm._and[a;b]|Or->funab->DTerm._or[a;b]|Xor->DTerm.xor|_->Fmt.failwith{|Bool: Unsupported binop operator "%a"|}Binop.ppopinop'e1e2letencode_relopope1e2=letop'=matchopwith|Relop.Eq->DTerm.eq|Ne->DTerm.neq|_->Fmt.failwith{|Bool: Unsupported relop operator "%a"|}Relop.ppopinop'e1e2letencode_cvtopop_=Fmt.failwith{|Bool: Unsupported cvtop operator "%a"|}Cvtop.ppopletencode_triopope1e2e3=letop'=matchopwith|Triop.Ite->DTerm.ite|_->Fmt.failwith{|Bool: Unsupported triop operator "%a"|}Triop.ppopinop'e1e2e3endmoduleStr=structopenTyletencode_unopop_=Fmt.failwith{|Str: Unsupported unop operator "%a"|}Unop.ppopletencode_binopop__=Fmt.failwith{|Str: Unsupported binop operator "%a"|}Binop.ppopletencode_relopop=letop'=matchopwith|Relop.Eq->DTerm.eq|Ne->DTerm.neq|_->Fmt.failwith{|Str: Unsupported relop operator "%a"|}Relop.ppopinop'letencode_triopop___=Fmt.failwith{|Str: Unsupported triop operator "%a"|}Triop.ppopletencode_cvtopop_=Fmt.failwith{|Str: Unsupported cvtop operator "%a"|}Cvtop.ppopendmoduleBv=structopenTyletencode_val(typea)(cast:aTy.cast)(i:a)=matchcastwith|C8->letn=ifi>=0thenielseiland((1lsl8)-1)in(* necessary to have the same behaviour as Z3 *)DTerm.Bitv.mk(Dolmen_type.Misc.Bitv.parse_decimal(String.cat"bv"(Int.to_stringn))8)|C32->letiint=Int32.to_intiinletn=ifiint>=0theniintelseiintland((1lsl32)-1)in(* necessary to have the same behaviour as Z3 *)DTerm.Bitv.mk(Dolmen_type.Misc.Bitv.parse_decimal(String.cat"bv"(Int.to_stringn))32)|C64->letn=ifInt64.compareiInt64.zero>=0thenZ.of_int64ielseZ.logand(Z.of_int64i)(Z.sub(Z.(lsl)Z.one64)Z.one)in(* necessary to have the same behaviour as Z3 *)DTerm.Bitv.mk(Dolmen_type.Misc.Bitv.parse_decimal(String.cat"bv"(Z.to_stringn))64)letencode_unopope=letop'=matchopwith|Unop.Not->DTerm.Bitv.not|Neg->DTerm.Bitv.neg|_->Fmt.failwith{|Bv: UNsupported unary operator "%a"|}Unop.ppopinop'eletencode_binopope1e2=letop'=matchopwith|Binop.Add->DTerm.Bitv.add|Sub->DTerm.Bitv.sub|Mul->DTerm.Bitv.mul|Div->DTerm.Bitv.sdiv|DivU->DTerm.Bitv.udiv|And->DTerm.Bitv.and_|Xor->DTerm.Bitv.xor|Or->DTerm.Bitv.or_|ShrA->DTerm.Bitv.ashr|ShrL->DTerm.Bitv.lshr|Shl->DTerm.Bitv.shl|Rem->DTerm.Bitv.srem|RemU->DTerm.Bitv.urem|_->Fmt.failwith{|Bv: Unsupported binary operator "%a"|}Binop.ppopinop'e1e2letencode_triopop_=Fmt.failwith{|Bv: Unsupported triop operator "%a"|}Triop.ppopletencode_relopope1e2=letop'=matchopwith|Relop.Eq->DTerm.eq|Ne->DTerm.neq|Lt->DTerm.Bitv.slt|LtU->DTerm.Bitv.ult|Le->DTerm.Bitv.sle|LeU->DTerm.Bitv.ule|Gt->DTerm.Bitv.sgt|GtU->DTerm.Bitv.ugt|Ge->DTerm.Bitv.sge|GeU->DTerm.Bitv.ugeinop'e1e2letencode_cvtopszope=letop'=matchopwith|Cvtop.Sign_extendn->DTerm.Bitv.sign_extendn|Zero_extendn->DTerm.Bitv.zero_extendn|(TruncSF32|TruncSF64)whensz=32->DTerm.Float.to_sbv32DTerm.Float.roundTowardZero|(TruncSF32|TruncSF64)whensz=64->DTerm.Float.to_sbv64DTerm.Float.roundTowardZero|(TruncUF32|TruncUF64)whensz=32->DTerm.Float.to_ubv32DTerm.Float.roundTowardZero|(TruncUF32|TruncUF64)whensz=64->DTerm.Float.to_ubv64DTerm.Float.roundTowardZero|Reinterpret_floatwhensz=32->DTerm.Float.ieee_format_to_fp824|Reinterpret_floatwhensz=64->DTerm.Float.ieee_format_to_fp1153|ToBoolwhensz=32->encode_relopNe(encode_valC320l)|ToBoolwhensz=64->encode_relopNe(encode_valC640L)|OfBoolwhensz=32->fune->DTerm.itee(encode_valC321l)(encode_valC320l)|OfBoolwhensz=64->fune->DTerm.itee(encode_valC641L)(encode_valC640L)|_->Fmt.failwith{|Bv: Unsupported bv(32) operator "%a"|}Cvtop.ppopinop'eendmoduleFp=structopenTyletencode_val(typea)(sz:aTy.cast)(f:a)=matchszwith|C8->Fmt.failwith"Unable to create FP numeral using 8 bits"|C32->DTerm.Float.ieee_format_to_fp824(Bv.encode_valC32f)|C64->DTerm.Float.ieee_format_to_fp1153(Bv.encode_valC64f)letencode_unopope=letop'=matchopwith|Unop.Neg->DTerm.Float.neg|Abs->DTerm.Float.abs|Sqrt->DTerm.Float.sqrtDTerm.Float.roundNearestTiesToEven|Is_nan->DTerm.Float.isNaN|Ceil->DTerm.Float.roundToIntegralDTerm.Float.roundTowardPositive|Floor->DTerm.Float.roundToIntegralDTerm.Float.roundTowardNegative|Trunc->DTerm.Float.roundToIntegralDTerm.Float.roundTowardZero|Nearest->DTerm.Float.roundToIntegralDTerm.Float.roundNearestTiesToEven|_->Fmt.failwith{|Fp: Unsupported unary operator "%a"|}Unop.ppopinop'eletencode_binopope1e2=letop'=matchopwith|Binop.Add->DTerm.Float.addDTerm.Float.roundNearestTiesToEven|Sub->DTerm.Float.subDTerm.Float.roundNearestTiesToEven|Mul->DTerm.Float.mulDTerm.Float.roundNearestTiesToEven|Div->DTerm.Float.divDTerm.Float.roundNearestTiesToEven|Min->DTerm.Float.min|Max->DTerm.Float.max|Rem->DTerm.Float.rem|Copysign->fune1e2->letabs_float=DTerm.Float.abse1inletzero=matchDTerm.tye1with|{ty_descr=TyApp({builtin=DBuiltin.Float(e,s);_},_);_}->DTerm.Float.plus_zeroes|_->assertfalseinDTerm.ite(DTerm.Float.geqe2zero)abs_float(DTerm.Float.negabs_float)|_->Fmt.failwith{|Fp: Unsupported binop operator "%a"|}Binop.ppopinop'e1e2letencode_triopop_=Fmt.failwith{|Fp: Unsupported triop operator "%a"|}Triop.ppopletencode_relopope1e2=letop'=matchopwith|Relop.Eq->DTerm.Float.eq|Ne->fune1e2->DTerm.Float.eqe1e2|>DTerm.neg|Lt->DTerm.Float.lt|Le->DTerm.Float.leq|Gt->DTerm.Float.gt|Ge->DTerm.Float.geq|_->Fmt.failwith{|Fp: Unsupported relop operator "%a"|}Relop.ppopinop'e1e2letencode_cvtopszope=letop'=matchszwith|32->(matchopwith|Cvtop.DemoteF64->DTerm.Float.to_fp824DTerm.Float.roundNearestTiesToEven|ConvertSI32|ConvertSI64->DTerm.Float.sbv_to_fp824DTerm.Float.roundNearestTiesToEven|ConvertUI32|ConvertUI64->DTerm.Float.ubv_to_fp824DTerm.Float.roundNearestTiesToEven|Reinterpret_int->DTerm.Float.ieee_format_to_fp824|ToString->funv->DTerm.apply_cstBuiltin.f32_to_string[][v]|OfString->funv->DTerm.apply_cstBuiltin.string_to_f32[][v]|_->Fmt.failwith{|Fp: Unsupported fp(32) operator "%a"|}Cvtop.ppop)|64->(matchopwith|PromoteF32->DTerm.Float.to_fp1153DTerm.Float.roundNearestTiesToEven|ConvertSI32|ConvertSI64->DTerm.Float.sbv_to_fp1153DTerm.Float.roundNearestTiesToEven|ConvertUI32|ConvertUI64->DTerm.Float.ubv_to_fp1153DTerm.Float.roundNearestTiesToEven|Reinterpret_int->DTerm.Float.ieee_format_to_fp1153|ToString->funv->DTerm.apply_cstBuiltin.f64_to_string[][v]|OfString->funv->DTerm.apply_cstBuiltin.string_to_f64[][v]|_->Fmt.failwith{|Fp: Unsupported fp(64) operator "%a"|}Cvtop.ppop)|_->Fmt.failwith{|Fp: Unsupported operator "%a"|}Cvtop.ppopinop'eendletencode_val:Value.t->expr=function|True->DTerm.of_cstDTerm.Const._true|False->DTerm.of_cstDTerm.Const._false|Intv->I.encode_valv|Realv->Real.encode_valv|Str_->assertfalse|BitvbvwhenBitvector.numbitsbv=8->Bv.encode_valC8(Z.to_int(Bitvector.viewbv))|BitvbvwhenBitvector.numbitsbv=32->Bv.encode_valC32(Bitvector.to_int32bv)|BitvbvwhenBitvector.numbitsbv=64->Bv.encode_valC64(Bitvector.to_int64bv)|Num(F32x)->Fp.encode_valC32x|Num(F64x)->Fp.encode_valC64x|v->Fmt.failwith{|Unsupported value "%a"|}Value.ppvletencode_unop(ty:Ty.t)=matchtywith|Ty_int->I.encode_unop|Ty_real->Real.encode_unop|Ty_bool->Boolean.encode_unop|Ty_str->Str.encode_unop|Ty_bitv_->Bv.encode_unop|Ty_fp_->Fp.encode_unop|(Ty_list|Ty_app|Ty_unit|Ty_none|Ty_regexp)asop->Fmt.failwith{|Trying to encode unsupported op of type %a|}Ty.ppopletencode_binop(ty:Ty.t)=matchtywith|Ty_int->I.encode_binop|Ty_real->Real.encode_binop|Ty_bool->Boolean.encode_binop|Ty_str->Str.encode_binop|Ty_bitv_->Bv.encode_binop|Ty_fp_->Fp.encode_binop|(Ty_list|Ty_app|Ty_unit|Ty_none|Ty_regexp)asop->Fmt.failwith"Trying to encode unsupported op of type %a"Ty.ppopletencode_triop(ty:Ty.t)=matchtywith|Ty_int->I.encode_triop|Ty_real->Real.encode_triop|Ty_bool->Boolean.encode_triop|Ty_str->Str.encode_triop|Ty_bitv_->Bv.encode_triop|Ty_fp_->Fp.encode_triop|(Ty_list|Ty_app|Ty_unit|Ty_none|Ty_regexp)asop->Fmt.failwith"Trying to encode unsupported op of type %a"Ty.ppopletencode_relop(ty:Ty.t)=matchtywith|Ty_int->I.encode_relop|Ty_real->Real.encode_relop|Ty_bool->Boolean.encode_relop|Ty_str->Str.encode_relop|Ty_bitv_->Bv.encode_relop|Ty_fp_->Fp.encode_relop|(Ty_list|Ty_app|Ty_unit|Ty_none|Ty_regexp)asop->Fmt.failwith"Trying to encode unsupported op of type %a"Ty.ppopletencode_cvtop(ty:Ty.t)=matchtywith|Ty_int->I.encode_cvtop|Ty_real->Real.encode_cvtop|Ty_bool->Boolean.encode_cvtop|Ty_str->Str.encode_cvtop|Ty_bitvsz->Bv.encode_cvtopsz|Ty_fpsz->Fp.encode_cvtopsz|(Ty_list|Ty_app|Ty_unit|Ty_none|Ty_regexp)asop->Fmt.failwith"Trying to encode unsupported op of type %a"Ty.ppopletencode_expr_acc?(record_sym=funacc_->acc)acce=letrecauxacc(e:Expr.t)=matchExpr.viewewith|Valv->(acc,encode_valv)|Ptr{base;offset}->letbase'=encode_val(Bitv(Bitvector.of_int32base))inletacc,offset'=auxaccoffsetin(acc,DTerm.Bitv.addbase'offset')|Symbols->letcst=tcst_of_symbolsinletacc=record_symacccstin(acc,DTerm.of_cstcst)|Unop(ty,op,e)->letacc,e'=auxaccein(acc,encode_unoptyope')|Binop(ty,op,e1,e2)->letacc,e1'=auxacce1inletacc,e2'=auxacce2in(acc,encode_binoptyope1'e2')|Triop(ty,op,e1,e2,e3)->letacc,e1'=auxacce1inletacc,e2'=auxacce2inletacc,e3'=auxacce3in(acc,encode_trioptyope1'e2'e3')|Relop(ty,op,e1,e2)->letacc,e1'=auxacce1inletacc,e2'=auxacce2in(acc,encode_reloptyope1'e2')|Cvtop(ty,op,e)->letacc,e'=auxaccein(acc,encode_cvtoptyope')|Extract(e,h,l)->letacc,e'=auxaccein(acc,DTerm.Bitv.extract((h*8)-1)(l*8)e')|Concat(e1,e2)->letacc,e1'=auxacce1inletacc,e2'=auxacce2in(acc,DTerm.Bitv.concate1'e2')|Naryop_|List_|App_|Binder_->Fmt.failwith{|Unsupported expr %a|}Expr.ppeinauxacceletencode_expr?(record_sym=fun_->())e=snd(encode_expr_acc~record_sym:(fun()->record_sym)()e)