如何添加一个要求整数变量属于数组的约束?

时间:2018-06-23 14:48:06

标签: python z3 smt z3py

假设我有一个z3py整数变量x = Int('x')和一个整数数组a = [1, 2, 3]。然后,我通过s.add(a中的x)添加约束。

我认为这是可以满足的,因为x可以是1 or 2 or 3。但这实际上是不敏感的。谁能告诉我如何添加约束以确保x in a

谢谢!

这是我使用的python代码。我认为输出答案将是s,因为x可以等于1或2或3,所以满足约束x in a。但是答案实际上是不满意的。也许这不是指定此约束的正确方法。因此,我的问题是如何指定这样的约束条件,以确保只能使用特定数组中的值实例化变量。

from z3 import *
x = Int('x')

a = [1, 2, 3]

s = Solver()

s.add(x in a)

print(s.check())

3 个答案:

答案 0 :(得分:2)

这应该做:

from z3 import *

a = [1,2,3]

s = Solver()
x = Int('x')
s.add(Or([x == i for i in a]))

# Enumerate all possible solutions:
while True:
    r = s.check()
    if r == sat:
        m = s.model()
        print m
        s.add(x != m[x])
    else:
        print r
        break

运行此命令时,我得到:

[x = 1]
[x = 2]
[x = 3]
unsat

答案 1 :(得分:0)

“ a中的x”是一个python表达式,在声明约束之前,该变量的值为False,因为变量x不属于数组。

答案 2 :(得分:0)

一种方法是使用循环建立z3.Andz3.Or约束

# Finds all numbers in the domain, for which it's square is also in the domain

import z3
exclude = [1,2]
domain  = list(range(128))
number  = z3.Int('number')
squared = number * number
solver  = z3.Solver()
solver.add(z3.Or([  number  == value for value in domain  ]))
solver.add(z3.Or([  squared == value for value in domain  ]))
solver.add(z3.And([ number  != value for value in exclude ]))
solver.add(z3.And([ squared != value for value in exclude ]))
solver.push()  # create stack savepoint

output = []
while solver.check() == z3.sat:
  value = solver.model()[number].as_long()
  solver.add( number != value )
  output.append(value)

solver.pop()  # reset stack to last solver.push()

print(output)
# [10, 0, 4, 6, 5, 11, 9, 8, 3, 7]

print(sorted(output))
# [0, 3, 4, 5, 6, 7, 8, 9, 10, 11]