forked from regb/scala-smtlib
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathFixedSizeBitVectors.scala
220 lines (195 loc) · 7.06 KB
/
FixedSizeBitVectors.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
package smtlib
package theories
import trees.Terms._
import common._
import Operations._
object FixedSizeBitVectors {
object BitVectorSort {
def apply(length: BigInt): Sort = {
require(length > 0)
Sort(Identifier(SSymbol("BitVec"), Seq(SNumeral(length))))
}
def unapply(sort: Sort): Option[BigInt] = sort match {
case Sort(Identifier(SSymbol("BitVec"), Seq(SNumeral(n))), Seq()) if n > 0 => Some(n)
case _ => None
}
}
object BitVectorLit {
def apply(content: List[Boolean]): Term = SBinary(content)
/** Construct a bit-vector literal from an hexadecimal
*
* The bitvector theory interprets the hexadecimal literals
* as a bit vector of size 4 times the length of the hexadecimal
* representation
*/
def apply(content: Hexadecimal): Term = SHexadecimal(content)
def unapply(term: Term): Option[List[Boolean]] = term match {
case SBinary(content) => Some(content)
case SHexadecimal(hexa) => Some(hexa.toBinary)
case _ => None
}
}
/**
* shorthand notation (_ bv13 32) for the number 13 with 32 bits
*/
object BitVectorConstant {
def apply(x: BigInt, n: BigInt): Term =
QualifiedIdentifier(Identifier(SSymbol("bv" + x), Seq(SNumeral(n))))
//TODO: BigInt is not the best data representation for a bitvector, we should probably use a list of boolean kind of representation
def unapply(term: Term): Option[(BigInt, BigInt)] = term match {
case QualifiedIdentifier(
Identifier(SSymbol(cst), Seq(SNumeral(size))),
None
) if cst startsWith "bv" =>
Some(BigInt(cst drop 2) -> size)
case _ => None
}
}
object Concat extends OperationN1 { override val name = "concat" }
object Not extends Operation1 { override val name = "bvnot" }
object Neg extends Operation1 { override val name = "bvneg" }
object And extends Operation2 { override val name = "bvand" }
object Or extends Operation2 { override val name = "bvor" }
object NAnd extends Operation2 { override val name = "bvnand" }
object NOr extends Operation2 { override val name = "bvnor" }
object XOr extends Operation2 { override val name = "bvxor" }
object XNOr extends Operation2 { override val name = "bvxnor" }
object Comp extends Operation2 { override val name = "bvcomp" }
object Add extends OperationN1 { override val name = "bvadd" }
object Sub extends Operation2 { override val name = "bvsub" }
object Mul extends OperationN1 { override val name = "bvmul" }
object UDiv extends Operation2 { override val name = "bvudiv" }
object SDiv extends Operation2 { override val name = "bvsdiv" }
object URem extends Operation2 { override val name = "bvurem" }
object SRem extends Operation2 { override val name = "bvsrem" }
object SMod extends Operation2 { override val name = "bvsmod" }
object ULessThan extends Operation2 { override val name = "bvult" }
object ULessEquals extends Operation2 { override val name = "bvule" }
object UGreaterThan extends Operation2 { override val name = "bvugt" }
object UGreaterEquals extends Operation2 { override val name = "bvuge" }
object SLessThan extends Operation2 { override val name = "bvslt" }
object SLessEquals extends Operation2 { override val name = "bvsle" }
object SGreaterThan extends Operation2 { override val name = "bvsgt" }
object SGreaterEquals extends Operation2 { override val name = "bvsge" }
object ShiftLeft extends Operation2 { override val name = "bvshl" }
object LShiftRight extends Operation2 { override val name = "bvlshr" }
object AShiftRight extends Operation2 { override val name = "bvashr" }
object BV2Nat extends Operation1 { override val name = "bv2nat" }
object Extract {
def apply(i: BigInt, j: BigInt, t: Term): Term = {
require(i >= j)
FunctionApplication(
QualifiedIdentifier(Identifier(SSymbol("extract"), Seq(SNumeral(i), SNumeral(j)))),
Seq(t)
)
}
def unapply(term: Term): Option[(BigInt, BigInt, Term)] = term match {
case FunctionApplication(
QualifiedIdentifier(
Identifier(SSymbol("extract"), Seq(SNumeral(i), SNumeral(j))),
None
), Seq(t)) => Some((i, j, t))
case _ => None
}
}
object Repeat {
def apply(i: BigInt, t: Term): Term = {
require(i >= 1)
FunctionApplication(
QualifiedIdentifier(Identifier(SSymbol("repeat"), Seq(SNumeral(i)))),
Seq(t)
)
}
def unapply(term: Term): Option[(BigInt, Term)] = term match {
case FunctionApplication(
QualifiedIdentifier(
Identifier(SSymbol("repeat"), Seq(SNumeral(i))),
None
), Seq(t)) => Some((i, t))
case _ => None
}
}
object ZeroExtend {
def apply(i: BigInt, t: Term): Term = {
require(i >= 0)
FunctionApplication(
QualifiedIdentifier(Identifier(SSymbol("zero_extend"), Seq(SNumeral(i)))),
Seq(t)
)
}
def unapply(term: Term): Option[(BigInt, Term)] = term match {
case FunctionApplication(
QualifiedIdentifier(
Identifier(SSymbol("zero_extend"), Seq(SNumeral(i))),
None
), Seq(t)) => Some((i, t))
case _ => None
}
}
object SignExtend {
def apply(i: BigInt, t: Term): Term = {
require(i >= 0)
FunctionApplication(
QualifiedIdentifier(Identifier(SSymbol("sign_extend"), Seq(SNumeral(i)))),
Seq(t)
)
}
def unapply(term: Term): Option[(BigInt, Term)] = term match {
case FunctionApplication(
QualifiedIdentifier(
Identifier(SSymbol("sign_extend"), Seq(SNumeral(i))),
None
), Seq(t)) => Some((i, t))
case _ => None
}
}
object RotateLeft {
def apply(i: BigInt, t: Term): Term = {
require(i >= 0)
FunctionApplication(
QualifiedIdentifier(Identifier(SSymbol("rotate_left"), Seq(SNumeral(i)))),
Seq(t)
)
}
def unapply(term: Term): Option[(BigInt, Term)] = term match {
case FunctionApplication(
QualifiedIdentifier(
Identifier(SSymbol("rotate_left"), Seq(SNumeral(i))),
None
), Seq(t)) => Some((i, t))
case _ => None
}
}
object RotateRight {
def apply(i: BigInt, t: Term): Term = {
require(i >= 0)
FunctionApplication(
QualifiedIdentifier(Identifier(SSymbol("rotate_right"), Seq(SNumeral(i)))),
Seq(t)
)
}
def unapply(term: Term): Option[(BigInt, Term)] = term match {
case FunctionApplication(
QualifiedIdentifier(
Identifier(SSymbol("rotate_right"), Seq(SNumeral(i))),
None
), Seq(t)) => Some((i, t))
case _ => None
}
}
object Int2BV {
def apply(m: BigInt, t: Term): Term =
FunctionApplication(
QualifiedIdentifier(Identifier(SSymbol("int2bv"), Seq(SNumeral(m)))),
Seq(t)
)
def unapply(term: Term): Option[(BigInt, Term)] = term match {
case FunctionApplication(
QualifiedIdentifier(
Identifier(SSymbol("int2bv"), Seq(SNumeral(m))),
None
), Seq(t)) => Some((m, t))
case _ => None
}
}
}