【问题标题】:Why is this formula in Z3 not correct?为什么Z3中的这个公式不正确?
【发布时间】:2021-07-30 16:32:48
【问题描述】:

这段代码有以下问题

p_y = [Int("p_y_%s" % str(i+1)) for i in range(n)]
length = Int("length")
objective = length == max([p_y[i] + y[i] for i in range(n)])

n 是一个整数参数, 错误如下:

File "C:/Users/boezi/PycharmProjects/VLSI/SMT/src/model.py", line 29, in solve_instance
    objective = length == max([p_y[i] + y[i] for i in range(n)])
  File "C:\Users\boezi\AppData\Local\Programs\Python\Python37\lib\site-packages\z3\z3.py", line 380, in __bool__
    raise Z3Exception("Symbolic expressions cannot be cast to concrete Boolean values.")
z3.z3types.Z3Exception: Symbolic expressions cannot be cast to concrete Boolean values.

我该如何解决?

【问题讨论】:

标签: python z3py


【解决方案1】:

我猜这是来自此人正在处理的同一任务:z3py: Symbolic expressions cannot be cast to concrete Boolean values

无论如何,这是您要使用的功能:

# 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

长话短说,Python 的max 不处理符号值。您必须拥有自己的符号 max 版本并使用它。太糟糕了 z3py 除了你得到的这个神秘的错误消息之外,没有办法告诉你。

【讨论】:

    【解决方案2】:

    max 不是公式,但您可以将此 max 函数用于您的用例:

    def z3_max(x, *elts):
        if not elts:
            return x
        y = z3_max(*elts)
        return If(x > y, x, y)
    

    然后您可以将它与z3_max(x, y, z) 一起使用。
    如果你有一个变量列表u = [x, y, z],你可以使用z3_max(*u)

    不过可能还有其他更优雅的解决方案。

    【讨论】:

    • 这个定义似乎不正确。递归调用不引用elts[0] 并传递将作为结果返回的列表的其余部分;这不可能是正确的。请不要在没有先尝试的情况下发布答案! (或提供示例运行以展示其使用方式。)
    • 感谢您指出,有一个不应该存在的 [1:],它已修复
    • 恐怕还是不行。请注意,您正在递归调用z3_max,并且在递归调用中,您只传递一个参数,而您的函数需要两个参数。作为指导,请不要发布解决方案,除非您先对其进行测试以确保它们按预期工作。 (如果我将您当前的定义称为z3_max(1, [2, 3, 4]),我会收到一条很长的运行时错误消息。
    • elts 上缺少 * 运算符...无论如何,您发布的解决方案也是如此,并避免使用较慢的星号运算符,所以一切都很好
    • 让我们看看你的“最新”修复如何表现:如果我运行z3_max(1, [2,3,4]),我会收到一条很长的错误消息。如果我运行z3_max(1, []),我会收到一条错误消息。同样,您的定义只是正确。递归调用使用第一个参数作为基中的元素,但作为第二个中的列表。关键是,不要发布解决方案,除非它们实际运行并产生正确的值。这不是竞赛,只是确保此论坛包含对寻求 z3/z3py 信息的人们有用的答案。
    猜你喜欢
    • 1970-01-01
    • 2014-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-21
    • 2014-10-21
    • 2018-06-08
    • 1970-01-01
    相关资源
    最近更新 更多