123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687(* This file is free software, part of dolmen. See file "LICENSE" for more information *)(* Value definition *)(* ************************************************************************* *)(* Rationals, represented using zarith. *)typet=Q.tletcompare=Q.compareletprintfmtq=Format.fprintffmt"Q:%a "Q.pp_printqletops=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~opsiletfun1f~cst=Fun.fun_1~cst(funx->f(Value.extract_exn~opsx))letfun2f~cst=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))letbuiltins_(cst:Dolmen.Std.Expr.Term.Const.t)=matchcst.builtinwith|B.Rationali->Some(mk(Q.of_stringi))|B.Lt`Rat->cmp~cstQ.lt|B.Gt`Rat->cmp~cstQ.gt|B.Geq`Rat->cmp~cstQ.geq|B.Leq`Rat->cmp~cstQ.leq|B.Minus`Rat->op1~cst(funx->Q.negx)|B.Add`Rat->op2~cstQ.add|B.Sub`Rat->op2~cstQ.sub|B.Mul`Rat->op2~cstQ.mul|B.Div`Rat->op2~cstQ.div|B.Div_e`Rat->op2~cstdiv_e|B.Div_t`Rat->op2~cstdiv_t|B.Div_f`Rat->op2~cstdiv_f|B.Modulo_e`Rat->op2~cstmod_e|B.Modulo_t`Rat->op2~cstmod_t|B.Modulo_f`Rat->op2~cstmod_f|B.Is_rat`Rat->Some(Bool.mktrue)|B.Floor`Rat->op1~cstfloor|B.Ceiling`Rat->op1~cstceil|B.Truncate`Rat->op1~csttruncate|B.Round`Rat->op1~cstround|B.Is_int`Rat->Some(fun1~cst(funx->Bool.mk(Z.equalZ.onex.Q.den)))|_->None