z3 - Z3 中的后果
问题描述
Z3 能够推导出该理论的布尔结果,如https://theory.stanford.edu/~nikolaj/programmingz3.html#sec-consequences中所述
现在我想知道是否也可以对数值执行此操作。例如给出以下理论:
(declare-const x Int)
(declare-const y Int)
(declare-const z Int)
(assert (= (+ x y) 10))
(assert (and (>= y 20) (>= x -20)))
(check-sat)
(get-model)
我想知道是否有可能得出“y”必须介于 20 和 30 之间,而 x 必须介于 -20 和 -10 之间。
我能想出的一种解决方法是最大化和最小化这些变量,然后我会得到可能性的范围,但在我看来,可以有更好的方法来做到这一点。
解决方案
这与之前的堆栈溢出问题非常相似:Using SMT-LIB to count the number of modules using a formula
底线:如果涉及多个变量,那么这个问题通常很难解决;除非您使用该问题的特定知识。如果恰好只有一个变量,那么您确实可以使用优化和其他技巧来为您提供“范围”,但通常这样的算法不一定是高效的。(尽管在实践中它可以轻松处理最简单的事情。)
如果您不关心不连续性而只想找出最大/最小值,则可以使用 z3 的优化器。请注意,这不是标准 SMTLib 的一部分,而是 z3 扩展。这是一个例子:
(declare-const x Int)
(declare-const y Int)
(declare-const z Int)
(assert (= (+ x y) 10))
(assert (and (>= y 20) (>= x -20)))
(assert (distinct x (- 15)))
(assert (distinct y 25))
(push) (minimize y) (check-sat) (get-objectives) (pop)
(push) (maximize y) (check-sat) (get-objectives) (pop)
(push) (minimize x) (check-sat) (get-objectives) (pop)
(push) (maximize x) (check-sat) (get-objectives) (pop)
这打印:
sat
(objectives
(y 20)
)
sat
(objectives
(y 30)
)
sat
(objectives
(x (- 20))
)
sat
(objectives
(x (- 10))
)
因此,您可以获得界限,但请注意我添加的要求如何x != -15
超出y != 25
您获得的范围。
请注意,如果您的类型是无界的(例如Int
),您还可以将 +/- infinity 作为边界:
(declare-const x Int)
(assert (< x 10))
(push) (minimize x) (check-sat) (get-objectives) (pop)
(push) (maximize x) (check-sat) (get-objectives) (pop)
这打印:
sat
(objectives
(x (* (- 1) oo))
)
sat
(objectives
(x 9)
)
优化通常是一个难题,z3 中的优化求解器与常规求解器相比肯定要慢一些。但它可能只是为您的问题域解决问题!
推荐阅读
- python - 将文件附加到 rarfile
- r - 如何创建一个新列,其中值来自一个数字减去一列?
- c++ - C ++按向量中的值推回字符串
- r - qplot:仅绘制低于阈值的节点
- python - 使用 Python,我如何根据匹配的部分替换部分路径?
- r - 在R中组合2个数据框
- ruby-on-rails - 返回已保存 Active Storage 对象的 ID
- javascript - react 渲染中的箭头函数和绑定是否会导致问题和性能瓶颈?
- grep - 如何grep一个只有一个大写字母的单词?
- python - XCode 还是 Visual Studio?使用 iPhone 摄像头构建人体运动检测 iOS 应用