z3py:符号表达式不能转换为具体的布尔值

z3py: Symbolic expressions cannot be cast to concrete Boolean values

我在用 z3py 定义 SMT 问题中的 objective 函数时遇到问题。

长话短说,我必须优化宽度固定但高度可变的板内较小块的放置。

我有一个坐标数组(由一个长度为 2 的整数数组表示)和一个整数列表(表示要放置的块的高度)。

    # [x,y] list of integer variables
    P = [[Int("x_%s" % (i + 1)), Int("y_%s" % (i + 1))]
         for i in range(blocks)]
    
    y = [int(b) for a, b in data[2:]]

我这样定义 objective 函数:

    obj= Int(max([P[i][1] + y[i] for i in range(blocks)]))

它根据块的起始坐标及其高度计算板的最大高度。 我知道它可能会更好,但我认为即使定义不同,问题也会相同。

无论如何,如果我 运行 我的代码,objective 函数行会出现以下错误:

" raise Z3Exception("符号表达式不能转换为具体的布尔值。") "

在调试时我看到 P[i][1] 给出了一个错误,我认为这是因为程序读取“y_i + 3”(例如)并且他们不能相加。

要点是:很明显objective函数依赖于问题的变量,那么我怎样才能摆脱这个错误呢?是否还有另一个地方我应该定义 objective 函数,以便它在执行任何操作之前等待实例化 P 数组?

完整代码:

    from z3 import *
    from math import ceil
    
    
    width = 8
    blocks = 4
    x = [3,3,5,5]
    y = [3,5,3,5]
    
    height = ceil(sum([x[i] * y[i] for i in range(blocks)]) / width) + 1
    
    # [blocks x 2] list of integer variables
    P = [[Int("x_%s" % (i + 1)), Int("y_%s" % (i + 1))]
         for i in range(blocks)]
    
    # value/ domain constraint
    values = [And(0 <= P[i][0], P[i][0] <= width - 1, 0 <= P[i][1], P[i][1] <= height - 1)
              for i in range(blocks)]
    
    
    obj = Int(max([P[i][1] + y[i] for i in range(blocks)]))
    
    board_problem = values # other constraints I've not included for brevity
    
    o = Optimize()
    o.add(board_problem)
    o.minimize(obj)
    
    if (o.check == 'unsat'):
        print("The problem is unsatisfiable")
    else:
        print("Solved")

这里的问题是您在符号值上调用 Python 的 max,这不适用于符号表达式。相反,定义 max 的符号版本并使用它:

# Return maximum of a vector; error if empty
def symMax(vs):
  m = vs[0]
  for v in vs[1:]:
    m = If(v > m, v, m)
  return m

obj = symMax([P[i][1] + y[i] for i in range(blocks)])

通过此更改,您的程序将在 运行 时执行并打印 Solved