z3py:变量的下限和上限?

时间:2018-02-12 18:44:39

标签: z3 z3py

序言:我正在玩z3py并试图实现一些全局约束的分解,例如: nvalue(n, x)确保向量/数组n中有不同数量的x个不同值。约束编程系统往往有可能提取决策变量的下限和上限 - 我碰巧非常喜欢这些全局约束。

我现在的问题是,是否可以获得变量的下限和上限,定义为IntIntVectorArray("x", IntSort(), IntSort())

(我已经对全局约束进行了一些分解 - 请参阅http://hakank.org/z3/ - 但只要分解需要上限/下限,我就必须在方法调用中添加这些限制。)

这是一个例子。请注意,它使用http://hakank.org/z3/z3_utils_hakank.py中定义的一些方便方法,简化了约束编程模型的端口;抱歉,如果这令人困惑。

关键是必须将min_valuemax_value两个值明确添加到方法nvalue

from z3_utils_hakank import *

# 
# ensure that there are exactly m distinct values in x
#
def nvalue(sol, m, x, min_val,max_val):
   n = len(x)
   sol.add(m == Sum([ If(Sum([ If(x[j] == i,1,0) for j in range(n)]) > 0,1,0) for i in range(min_val, max_val+1)]))

sol = Solver()

n = 5
min_val = 1 # <-- 
max_val = n # <-- 

# variables

m = makeIntVar(sol,"m",0,n)  # number of distinct values
x = makeIntVector(sol,"x",n, 1,n)

# constraints
nvalue(sol,m,x,min_val, max_val)

# solutions
num_solutions = 0
while sol.check() == sat:
  num_solutions += 1
  mod = sol.model()
  print "m:", mod.eval(m)
  print "x:", [mod.eval(x[i]) for i in range(n)]
  print
  getDifferentSolution(sol,mod,x)

print "num_solutions:", num_solutions  

如果它很棒,nvalue的方法定义可以写成这样的东西:

def nvalue(sol, m, x):
   n = len(x)
   min_val = sol.min_val(x)
   max_val = sol.max_val(x)
   sol.add(m == Sum([ If(Sum([ If(x[j] == i,1,0) for j in range(n)]) > 0,1,0) for i in range(min_val, max_val+1)]))

即。使用某些z3py函数,例如sol.min_value(x)sol.max_val(x)

0 个答案:

没有答案