1+ package viper .silver .ast .utility
2+
3+ import viper .silver .ast .{Bool , Int , LocalVarDecl , SMTFunc , SMTType }
4+
5+ /**
6+ * A factory for fixed-size bitvectors that offers convenient access to bitvector types, as well as
7+ * function definitions for unary and binary functions on bitvectors, as well as conversions from and
8+ * to integers.
9+ */
10+ case class BVFactory (size : Int ) {
11+ lazy val typ = SMTType (s " bv ${size}" , s " (_ BitVec ${size}) " )
12+
13+ def xor (name : String ) = SMTFunc (name, " bvxor" , typ, Seq (LocalVarDecl (" x" , typ)(), LocalVarDecl (" y" , typ)()))
14+ def and (name : String ) = SMTFunc (name, " bvand" , typ, Seq (LocalVarDecl (" x" , typ)(), LocalVarDecl (" y" , typ)()))
15+ def or (name : String ) = SMTFunc (name, " bvor" , typ, Seq (LocalVarDecl (" x" , typ)(), LocalVarDecl (" y" , typ)()))
16+ def add (name : String ) = SMTFunc (name, " bvadd" , typ, Seq (LocalVarDecl (" x" , typ)(), LocalVarDecl (" y" , typ)()))
17+ def mul (name : String ) = SMTFunc (name, " bvmul" , typ, Seq (LocalVarDecl (" x" , typ)(), LocalVarDecl (" y" , typ)()))
18+ def shl (name : String ) = SMTFunc (name, " bvshl" , typ, Seq (LocalVarDecl (" x" , typ)(), LocalVarDecl (" y" , typ)()))
19+ def shr (name : String ) = SMTFunc (name, " bvshr" , typ, Seq (LocalVarDecl (" x" , typ)(), LocalVarDecl (" y" , typ)()))
20+
21+ def not (name : String ) = SMTFunc (name, " bvnot" , typ, Seq (LocalVarDecl (" x" , typ)()))
22+ def neg (name : String ) = SMTFunc (name, " bvneg" , typ, Seq (LocalVarDecl (" x" , typ)()))
23+
24+ def from_int (name : String ) = SMTFunc (name, s " (_ int2bv ${size}) " , typ, Seq (LocalVarDecl (" x" , Int )()))
25+ def to_int (name : String ) = SMTFunc (name, s " (_ bv2int ${size}) " , Int , Seq (LocalVarDecl (" x" , typ)()))
26+ def from_nat (name : String ) = SMTFunc (name, s " (_ nat2bv ${size}) " , typ, Seq (LocalVarDecl (" x" , Int )()))
27+ def to_nat (name : String ) = SMTFunc (name, s " (_ bv2nat ${size}) " , Int , Seq (LocalVarDecl (" x" , typ)()))
28+ }
29+
30+ /**
31+ * Rounding modes for floating point operations.
32+ */
33+ object RoundingMode extends Enumeration {
34+ type RoundingMode = Value
35+ val RNE, RNA, RTP, RTN, RTZ = Value
36+ }
37+ import RoundingMode ._
38+
39+ /**
40+ * A factory for IEEE floating point numbers with "exp" bits for the exponent, "mant" bits for the significant,
41+ * including the hidden bit, and a given rounding mode for all operations that use one.
42+ * Offers access to types, unary and binary operations, comparisons, and conversions from and to
43+ * bitvectors of size exp + mant.
44+ */
45+ case class FloatFactory (mant : Int , exp : Int , roundingMode : RoundingMode ) {
46+
47+ lazy val typ = SMTType (s " float ${mant}e ${exp}" , s " (_ FloatingPoint ${exp} ${mant}) " )
48+
49+ def neg (name : String ) = SMTFunc (name, " fp.neg" , typ, Seq (LocalVarDecl (" x" , typ)()))
50+ def abs (name : String ) = SMTFunc (name, " fp.abs" , typ, Seq (LocalVarDecl (" x" , typ)()))
51+
52+ def add (name : String ) = SMTFunc (name, s " fp.add ${roundingMode}" , typ, Seq (LocalVarDecl (" x" , typ)(), LocalVarDecl (" y" , typ)()))
53+ def sub (name : String ) = SMTFunc (name, s " fp.sub ${roundingMode}" , typ, Seq (LocalVarDecl (" x" , typ)(), LocalVarDecl (" y" , typ)()))
54+ def mul (name : String ) = SMTFunc (name, s " fp.mul ${roundingMode}" , typ, Seq (LocalVarDecl (" x" , typ)(), LocalVarDecl (" y" , typ)()))
55+ def div (name : String ) = SMTFunc (name, s " fp.div ${roundingMode}" , typ, Seq (LocalVarDecl (" x" , typ)(), LocalVarDecl (" y" , typ)()))
56+ def min (name : String ) = SMTFunc (name, s " fp.min ${roundingMode}" , typ, Seq (LocalVarDecl (" x" , typ)(), LocalVarDecl (" y" , typ)()))
57+ def max (name : String ) = SMTFunc (name, s " fp.max ${roundingMode}" , typ, Seq (LocalVarDecl (" x" , typ)(), LocalVarDecl (" y" , typ)()))
58+
59+ def eq (name : String ) = SMTFunc (name, s " fp.eq " , Bool , Seq (LocalVarDecl (" x" , typ)(), LocalVarDecl (" y" , typ)()))
60+ def leq (name : String ) = SMTFunc (name, s " fp.leq " , Bool , Seq (LocalVarDecl (" x" , typ)(), LocalVarDecl (" y" , typ)()))
61+ def geq (name : String ) = SMTFunc (name, s " fp.geq " , Bool , Seq (LocalVarDecl (" x" , typ)(), LocalVarDecl (" y" , typ)()))
62+ def lt (name : String ) = SMTFunc (name, s " fp.lt " , Bool , Seq (LocalVarDecl (" x" , typ)(), LocalVarDecl (" y" , typ)()))
63+ def gt (name : String ) = SMTFunc (name, s " fp.gt " , Bool , Seq (LocalVarDecl (" x" , typ)(), LocalVarDecl (" y" , typ)()))
64+
65+ def isZero (name : String ) = SMTFunc (name, s " fp.isZero " , Bool , Seq (LocalVarDecl (" x" , typ)()))
66+ def isInfinite (name : String ) = SMTFunc (name, s " fp.isInfinite " , Bool , Seq (LocalVarDecl (" x" , typ)()))
67+ def isNaN (name : String ) = SMTFunc (name, s " fp.isNaN " , Bool , Seq (LocalVarDecl (" x" , typ)()))
68+ def isNegative (name : String ) = SMTFunc (name, s " fp.isNegative " , Bool , Seq (LocalVarDecl (" x" , typ)()))
69+ def isPositive (name : String ) = SMTFunc (name, s " fp.isPositive " , Bool , Seq (LocalVarDecl (" x" , typ)()))
70+
71+ def from_bv (name : String ) = SMTFunc (name, s " (_ to_fp ${exp} ${mant}) " , typ, Seq (LocalVarDecl (" x" , BVFactory (mant+ exp).typ)()))
72+ def to_bv (name : String ) = SMTFunc (name, s " (_ fp.to_sbv ${exp+ mant}) ${roundingMode} " , BVFactory (mant+ exp).typ, Seq (LocalVarDecl (" x" , typ)()))
73+ }
0 commit comments