9// Bit-vector operations
11// MkBVConst creates a bit-vector constant with the given name and size.
12func (c *Context) MkBVConst(name string, size uint) *Expr {
13 sym := c.MkStringSymbol(name)
14 return c.MkConst(sym, c.MkBvSort(size))
17// MkBV creates a bit-vector numeral from an integer.
18func (c *Context) MkBV(value int, size uint) *Expr {
19 return newExpr(c, C.Z3_mk_int(c.ptr, C.int(value), c.MkBvSort(size).ptr))
22// MkBVFromInt64 creates a bit-vector from an int64.
23func (c *Context) MkBVFromInt64(value int64, size uint) *Expr {
24 return newExpr(c, C.Z3_mk_int64(c.ptr, C.int64_t(value), c.MkBvSort(size).ptr))
27// MkBVAdd creates a bit-vector addition.
28func (c *Context) MkBVAdd(lhs, rhs *Expr) *Expr {
29 return newExpr(c, C.Z3_mk_bvadd(c.ptr, lhs.ptr, rhs.ptr))
32// MkBVSub creates a bit-vector subtraction.
33func (c *Context) MkBVSub(lhs, rhs *Expr) *Expr {
34 return newExpr(c, C.Z3_mk_bvsub(c.ptr, lhs.ptr, rhs.ptr))
37// MkBVMul creates a bit-vector multiplication.
38func (c *Context) MkBVMul(lhs, rhs *Expr) *Expr {
39 return newExpr(c, C.Z3_mk_bvmul(c.ptr, lhs.ptr, rhs.ptr))
42// MkBVUDiv creates an unsigned bit-vector division.
43func (c *Context) MkBVUDiv(lhs, rhs *Expr) *Expr {
44 return newExpr(c, C.Z3_mk_bvudiv(c.ptr, lhs.ptr, rhs.ptr))
47// MkBVSDiv creates a signed bit-vector division.
48func (c *Context) MkBVSDiv(lhs, rhs *Expr) *Expr {
49 return newExpr(c, C.Z3_mk_bvsdiv(c.ptr, lhs.ptr, rhs.ptr))
52// MkBVURem creates an unsigned bit-vector remainder.
53func (c *Context) MkBVURem(lhs, rhs *Expr) *Expr {
54 return newExpr(c, C.Z3_mk_bvurem(c.ptr, lhs.ptr, rhs.ptr))
57// MkBVSRem creates a signed bit-vector remainder.
58func (c *Context) MkBVSRem(lhs, rhs *Expr) *Expr {
59 return newExpr(c, C.Z3_mk_bvsrem(c.ptr, lhs.ptr, rhs.ptr))
62// MkBVNeg creates a bit-vector negation.
63func (c *Context) MkBVNeg(expr *Expr) *Expr {
64 return newExpr(c, C.Z3_mk_bvneg(c.ptr, expr.ptr))
67// MkBVAnd creates a bit-vector bitwise AND.
68func (c *Context) MkBVAnd(lhs, rhs *Expr) *Expr {
69 return newExpr(c, C.Z3_mk_bvand(c.ptr, lhs.ptr, rhs.ptr))
72// MkBVOr creates a bit-vector bitwise OR.
73func (c *Context) MkBVOr(lhs, rhs *Expr) *Expr {
74 return newExpr(c, C.Z3_mk_bvor(c.ptr, lhs.ptr, rhs.ptr))
77// MkBVXor creates a bit-vector bitwise XOR.
78func (c *Context) MkBVXor(lhs, rhs *Expr) *Expr {
79 return newExpr(c, C.Z3_mk_bvxor(c.ptr, lhs.ptr, rhs.ptr))
82// MkBVNot creates a bit-vector bitwise NOT.
83func (c *Context) MkBVNot(expr *Expr) *Expr {
84 return newExpr(c, C.Z3_mk_bvnot(c.ptr, expr.ptr))
87// MkBVShl creates a bit-vector shift left.
88func (c *Context) MkBVShl(lhs, rhs *Expr) *Expr {
89 return newExpr(c, C.Z3_mk_bvshl(c.ptr, lhs.ptr, rhs.ptr))
92// MkBVLShr creates a bit-vector logical shift right.
93func (c *Context) MkBVLShr(lhs, rhs *Expr) *Expr {
94 return newExpr(c, C.Z3_mk_bvlshr(c.ptr, lhs.ptr, rhs.ptr))
97// MkBVAShr creates a bit-vector arithmetic shift right.
98func (c *Context) MkBVAShr(lhs, rhs *Expr) *Expr {
99 return newExpr(c, C.Z3_mk_bvashr(c.ptr, lhs.ptr, rhs.ptr))
102// MkBVULT creates an unsigned bit-vector less-than.
103func (c *Context) MkBVULT(lhs, rhs *Expr) *Expr {
104 return newExpr(c, C.Z3_mk_bvult(c.ptr, lhs.ptr, rhs.ptr))
107// MkBVSLT creates a signed bit-vector less-than.
108func (c *Context) MkBVSLT(lhs, rhs *Expr) *Expr {
109 return newExpr(c, C.Z3_mk_bvslt(c.ptr, lhs.ptr, rhs.ptr))
112// MkBVULE creates an unsigned bit-vector less-than-or-equal.
113func (c *Context) MkBVULE(lhs, rhs *Expr) *Expr {
114 return newExpr(c, C.Z3_mk_bvule(c.ptr, lhs.ptr, rhs.ptr))
117// MkBVSLE creates a signed bit-vector less-than-or-equal.
118func (c *Context) MkBVSLE(lhs, rhs *Expr) *Expr {
119 return newExpr(c, C.Z3_mk_bvsle(c.ptr, lhs.ptr, rhs.ptr))
122// MkBVUGE creates an unsigned bit-vector greater-than-or-equal.
123func (c *Context) MkBVUGE(lhs, rhs *Expr) *Expr {
124 return newExpr(c, C.Z3_mk_bvuge(c.ptr, lhs.ptr, rhs.ptr))
127// MkBVSGE creates a signed bit-vector greater-than-or-equal.
128func (c *Context) MkBVSGE(lhs, rhs *Expr) *Expr {
129 return newExpr(c, C.Z3_mk_bvsge(c.ptr, lhs.ptr, rhs.ptr))
132// MkBVUGT creates an unsigned bit-vector greater-than.
133func (c *Context) MkBVUGT(lhs, rhs *Expr) *Expr {
134 return newExpr(c, C.Z3_mk_bvugt(c.ptr, lhs.ptr, rhs.ptr))
137// MkBVSGT creates a signed bit-vector greater-than.
138func (c *Context) MkBVSGT(lhs, rhs *Expr) *Expr {
139 return newExpr(c, C.Z3_mk_bvsgt(c.ptr, lhs.ptr, rhs.ptr))
142// MkConcat creates a bit-vector concatenation.
143func (c *Context) MkConcat(lhs, rhs *Expr) *Expr {
144 return newExpr(c, C.Z3_mk_concat(c.ptr, lhs.ptr, rhs.ptr))
147// MkExtract creates a bit-vector extraction.
148func (c *Context) MkExtract(high, low uint, expr *Expr) *Expr {
149 return newExpr(c, C.Z3_mk_extract(c.ptr, C.uint(high), C.uint(low), expr.ptr))
152// MkSignExt creates a bit-vector sign extension.
153func (c *Context) MkSignExt(i uint, expr *Expr) *Expr {
154 return newExpr(c, C.Z3_mk_sign_ext(c.ptr, C.uint(i), expr.ptr))
157// MkZeroExt creates a bit-vector zero extension.
158func (c *Context) MkZeroExt(i uint, expr *Expr) *Expr {
159 return newExpr(c, C.Z3_mk_zero_ext(c.ptr, C.uint(i), expr.ptr))
162// MkBVRotateLeft rotates the bits of t to the left by i positions.
163func (c *Context) MkBVRotateLeft(i uint, t *Expr) *Expr {
164 return newExpr(c, C.Z3_mk_rotate_left(c.ptr, C.uint(i), t.ptr))
167// MkBVRotateRight rotates the bits of t to the right by i positions.
168func (c *Context) MkBVRotateRight(i uint, t *Expr) *Expr {
169 return newExpr(c, C.Z3_mk_rotate_right(c.ptr, C.uint(i), t.ptr))
172// MkRepeat repeats the given bit-vector t a total of i times.
173func (c *Context) MkRepeat(i uint, t *Expr) *Expr {
174 return newExpr(c, C.Z3_mk_repeat(c.ptr, C.uint(i), t.ptr))
177// MkBVAddNoOverflow creates a predicate that checks that the bit-wise addition
178// of t1 and t2 does not overflow. If isSigned is true, checks for signed overflow.
179func (c *Context) MkBVAddNoOverflow(t1, t2 *Expr, isSigned bool) *Expr {
180 return newExpr(c, C.Z3_mk_bvadd_no_overflow(c.ptr, t1.ptr, t2.ptr, C.bool(isSigned)))
183// MkBVAddNoUnderflow creates a predicate that checks that the bit-wise signed addition
184// of t1 and t2 does not underflow.
185func (c *Context) MkBVAddNoUnderflow(t1, t2 *Expr) *Expr {
186 return newExpr(c, C.Z3_mk_bvadd_no_underflow(c.ptr, t1.ptr, t2.ptr))
189// MkBVSubNoOverflow creates a predicate that checks that the bit-wise signed subtraction
190// of t1 and t2 does not overflow.
191func (c *Context) MkBVSubNoOverflow(t1, t2 *Expr) *Expr {
192 return newExpr(c, C.Z3_mk_bvsub_no_overflow(c.ptr, t1.ptr, t2.ptr))
195// MkBVSubNoUnderflow creates a predicate that checks that the bit-wise subtraction
196// of t1 and t2 does not underflow. If isSigned is true, checks for signed underflow.
197func (c *Context) MkBVSubNoUnderflow(t1, t2 *Expr, isSigned bool) *Expr {
198 return newExpr(c, C.Z3_mk_bvsub_no_underflow(c.ptr, t1.ptr, t2.ptr, C.bool(isSigned)))
201// MkBVSdivNoOverflow creates a predicate that checks that the bit-wise signed division
202// of t1 and t2 does not overflow.
203func (c *Context) MkBVSdivNoOverflow(t1, t2 *Expr) *Expr {
204 return newExpr(c, C.Z3_mk_bvsdiv_no_overflow(c.ptr, t1.ptr, t2.ptr))
207// MkBVNegNoOverflow creates a predicate that checks that bit-wise negation does not overflow
208// when t1 is interpreted as a signed bit-vector.
209func (c *Context) MkBVNegNoOverflow(t1 *Expr) *Expr {
210 return newExpr(c, C.Z3_mk_bvneg_no_overflow(c.ptr, t1.ptr))
213// MkBVMulNoOverflow creates a predicate that checks that the bit-wise multiplication
214// of t1 and t2 does not overflow. If isSigned is true, checks for signed overflow.
215func (c *Context) MkBVMulNoOverflow(t1, t2 *Expr, isSigned bool) *Expr {
216 return newExpr(c, C.Z3_mk_bvmul_no_overflow(c.ptr, t1.ptr, t2.ptr, C.bool(isSigned)))
219// MkBVMulNoUnderflow creates a predicate that checks that the bit-wise signed multiplication
220// of t1 and t2 does not underflow.
221func (c *Context) MkBVMulNoUnderflow(t1, t2 *Expr) *Expr {
222 return newExpr(c, C.Z3_mk_bvmul_no_underflow(c.ptr, t1.ptr, t2.ptr))
225// MkBVRedAnd computes the bitwise AND reduction of a bit-vector, returning a 1-bit vector.
226func (c *Context) MkBVRedAnd(t *Expr) *Expr {
227 return newExpr(c, C.Z3_mk_bvredand(c.ptr, t.ptr))
230// MkBVRedOr computes the bitwise OR reduction of a bit-vector, returning a 1-bit vector.
231func (c *Context) MkBVRedOr(t *Expr) *Expr {
232 return newExpr(c, C.Z3_mk_bvredor(c.ptr, t.ptr))
235// MkBVExtRotateLeft rotates the bits of t1 to the left by the number of bits given by t2.
236// Both t1 and t2 must be bit-vectors of the same width.
237func (c *Context) MkBVExtRotateLeft(t1, t2 *Expr) *Expr {
238 return newExpr(c, C.Z3_mk_ext_rotate_left(c.ptr, t1.ptr, t2.ptr))
241// MkBVExtRotateRight rotates the bits of t1 to the right by the number of bits given by t2.
242// Both t1 and t2 must be bit-vectors of the same width.
243func (c *Context) MkBVExtRotateRight(t1, t2 *Expr) *Expr {
244 return newExpr(c, C.Z3_mk_ext_rotate_right(c.ptr, t1.ptr, t2.ptr))