I'm trying to solve a problem using the Array type in z3. Because I need to use BitVec type I declared the array as :
numbers = [BitVec(chr(i), 8) for i in range(0, 4)]
And then :
s = Solver()
s.add(numbers[0] == 100)
s.add(numbers[1] == numbers[0] + 2)
s.add(numbers[3] == numbers[1] + numbers[0])
s.add(numbers[2] == numbers[1] - 4)
print(s.check())
print(s.model())
Output :
sat
[ = 98, = 202, = 102, = 100]
However it doesn't print in order the results, Is there a way to print them in order?
Example:
[ = 100, = 102, = 98, = 202 ]
I have another doubt too. Is there a way to set a limit to the frequencies of a number:
numbers = [BitVec(chr(i), 8) for i in range(0, 4)]
s = Solver()
s.add(numbers[0] == 100)
s.add(numbers[0] + numbers[1] + numbers[2] == 200)
s.add(collections.Counter(numbers)[100] == 1) # something like that
print(s.check())
print(s.model())
To set that number 100 must be present only in numbers[0].
For your first question, I first propose to give some readable names to the variables. chr(i) for i in range(0, 4)
are 4 unprintable characters. Better use chr(i+48)
for digits 0..9 or chr(i+65)
for letters A..Z
The simplest way to print your result in the same order as the array is just: print ([s.model[n].as_long() for n in numbers])
.
For your second question, I propose to use Z3's Sum
function. For example:
numbers = [BitVec('N'+chr(i+48), 8) for i in range(0, 4)]
s = Solver()
s.add(numbers[0] == 100)
s.add(numbers[0] + numbers[1] + numbers[2] == 200)
s.add(Sum([If(n == 100, 1, 0) for n in numbers]) == 1)
print(s.check())
m = s.model()
print (m)
print ([m[n].as_long() for n in numbers])
Which outputs (in my test case):
sat
[N3 = 116, N1 = 106, N0 = 100, N2 = 250]
[100, 106, 250, 116]
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.