We also have to adjust the constant occurring in the example: #b111111
, #b000000
, (_ bv1 6)
, etc. That being said, SMT-LIB 2.0 format is not very convenient for writing parametric problems. I think the programmatic API is easier to use to encode parametric problems.
Here is the same example encoded using the Z3 Python API. It is also available online here. We can change the size of the bit-vectors by replacing SZ = 6
with SZ = 8
or SZ = 16
.
def All(sz):
return BitVecVal(2**sz - 1, sz)
def Empty(sz):
return BitVecVal(0, sz)
def LT_l(S, l):
sz = S.size()
return (All(sz) << l) & S == Empty(sz)
def GT_l(l, S):
sz = S.size()
return (~(All(sz) << l)) & S == Empty(sz)
def is_in(e, S):
sz = S.size()
one = BitVecVal(1, sz)
return (1 << e) & S != Empty(sz)
def is_minimal(e, S):
sz = S.size()
return And(is_in(e, S), ((1 << e) - 1) & S == Empty(sz))
def LT(L0, L1):
sz = L0.size()
min = BitVec('min', sz)
return Or(L0 == Empty(sz), L1 == Empty(sz), Exists([min], And(is_minimal(min, L1), LT_l(L0, min))))
SZ=6
consoleLock = BitVec('consoleLock', SZ)
l1 = BitVec('l1', SZ)
l2 = BitVec('l2', SZ)
s = Solver()
s.add(Distinct(consoleLock, l1, l2))
s.add(Or(l1 == 0, l1 == 1, l1 == 2, l1 == 4))
s.add(Or(l2 == 0, l2 == 1, l2 == 2, l2 == 4))
s.add(Or(consoleLock == 0, consoleLock == 1, consoleLock == 2, consoleLock == 4))
L4 = BitVec('L4', SZ)
L1 = BitVec('L1', SZ)
L0 = BitVec('L0', SZ)
L5 = BitVec('L5', SZ)
s.add(LT_l(L0, l1))
s.add(LT(L0, L1))
s.add(GT_l(L1, l1))
s.add(LT_l(L4, l2))
s.add(LT(L4, L5))
s.add(GT_l(L5, l2))
T1 = BitVec('T1', SZ)
s.add(T1 == l1)
s.add(LT_l(T1, l2))
T2 = BitVec('T2', SZ)
s.add(T2 == l2)
s.add(LT_l(T2, l1))
print s.check()