123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101(* This file is free software, part of dolmen. See file "LICENSE" for more information *)(* Value definition *)(* ************************************************************************* *)(* Real are currently represented as rationals.
This is correct for quantifier free logic, since without non-rational
contants, we do not have a way to create non-rational values.
However, we may need to upgrade this representation to a more complete
one when we add quantifiers and/or new constants/operators on real
values. *)typet=Q.tletcompare=Q.compareletprintfmtr=Format.fprintffmt"%a"Q.pp_printrletops=Value.ops~compare~print()(* Value helpers *)(* ************************************************************************* *)letceilx=Q.of_bigint@@Int.ceilxletfloorx=Q.of_bigint@@Int.floorxlettruncatex=Q.of_bigint@@Int.truncatexlethalf={Q.num=Z.one;Q.den=Z.of_int2}letroundx=ifQ.ltQ.zeroxthenceil(Q.subxhalf)elsefloor(Q.addxhalf)letdiv_eab=lets=Q.signbinletd=Q.divabinifs>0thenfloordelseceildletdiv_tab=truncate(Q.divab)letdiv_fab=floor(Q.divab)letmod_eab=Q.suba(Q.mul(div_eab)b)letmod_tab=Q.suba(Q.mul(div_tab)b)letmod_fab=Q.suba(Q.mul(div_fab)b)(* Builtins *)(* ************************************************************************* *)moduleE=Dolmen.Std.ExprmoduleB=Dolmen.Std.Builtinletmki=Value.mk~opsiletgetv=Value.extract_exn~opsvletfun1f~cst=Fun.mk_clos@@Fun.fun_1~cst(funx->f(Value.extract_exn~opsx))letfun2f~cst=Fun.mk_clos@@Fun.fun_2~cst(funxy->f(Value.extract_exn~opsx)(Value.extract_exn~opsy))letop1~cstf=Some(fun1~cst(funx->mk@@fx))letop2~cstf=Some(fun2~cst(funxy->mk@@fxy))letcmp~cstp=Some(fun2~cst(funxy->Bool.mk@@pxy))letop2_zero~eval~env~cstf=Some(Fun.mk_clos@@Fun.fun_2~cst(funxy->letv_x=Value.extract_exn~opsxinletv_y=Value.extract_exn~opsyinifQ.equalQ.zerov_ythenFun.corner_case~evalenvcst[][x;y]elsemk@@fv_xv_y))letbuiltins~evalenv(cst:Dolmen.Std.Expr.Term.Const.t)=matchcst.builtinwith|B.Decimali->Some(mk(Q.of_stringi))|B.Lt`Real->cmp~cstQ.lt|B.Gt`Real->cmp~cstQ.gt|B.Geq`Real->cmp~cstQ.geq|B.Leq`Real->cmp~cstQ.leq|B.Minus`Real->op1~cst(funx->Q.negx)|B.Add`Real->op2~cstQ.add|B.Sub`Real->op2~cstQ.sub|B.Mul`Real->op2~cstQ.mul|B.Div`Real->op2_zeroQ.div~cst~env~eval|B.Div_e`Real->op2~cstdiv_e|B.Div_t`Real->op2~cstdiv_t|B.Div_f`Real->op2~cstdiv_f|B.Modulo_e`Real->op2~cstmod_e|B.Modulo_t`Real->op2~cstmod_t|B.Modulo_f`Real->op2~cstmod_f|B.Is_rat`Real->Some(Bool.mktrue)|B.Floor`Real->op1~cstfloor|B.Ceiling`Real->op1~cstceil|B.Truncate`Real->op1~csttruncate|B.Round`Real->op1~cstround|B.Is_int`Real->Some(fun1~cst(funx->Bool.mk(Z.equalZ.onex.Q.den)))|_->None