【问题标题】:How to retrieve the obtained solution in array order when using arrays of BitVec in z3py?在z3py中使用BitVec数组时如何按数组顺序检索得到的解?
【发布时间】:2019-09-01 17:21:25
【问题描述】:

我正在尝试使用 z3 中的 Array 类型来解决问题。 因为我需要使用 BitVec 类型,所以我将数组声明为:

numbers = [BitVec(chr(i), 8) for i in range(0, 4)]

然后:

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())

输出:

sat
[ = 98,  = 202,  = 102,  = 100]

但是它没有按顺序打印结果,有没有办法按顺序打印它们?

例子:

[ = 100, = 102, = 98, = 202 ]

我还有一个疑问。有没有办法限制一个数字的频率:

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())

要设置数字 100 必须只出现在 numbers[0] 中。

【问题讨论】:

标签: python z3 z3py


【解决方案1】:

对于你的第一个问题,我首先建议给变量一些可读的名称。 chr(i) for i in range(0, 4) 是 4 个不可打印的字符。最好将chr(i+48) 用于数字0..9 或chr(i+65) 用于字母A..Z

以与数组相同的顺序打印结果的最简单方法是:print ([s.model[n].as_long() for n in numbers])

对于第二个问题,我建议使用Z3的Sum函数。例如:

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])

哪些输出(在我的测试用例中):

sat
[N3 = 116, N1 = 106, N0 = 100, N2 = 250]
[100, 106, 250, 116]

【讨论】:

  • 感谢回复,我最后用numbers = [BitVec('{:2}'.format(i), 8) for i in range(32)],结束我在模型准备好的时候对值进行排序:`m = s.model(); model = sorted([(d, m[d]) for d in m], key = lambda x: str(x[0])) `
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多