c++ - 如何在z3中定义分段函数
问题描述
我正在尝试使用以下 C++ 代码在 Z3 中定义一个非常简单的分段线性函数:
context c;
sort I = c.int_sort();
expr x = c.int_const("x");
func_decl f = function("f", I, I);
solver s(c);
s.add(forall(x, f(x) == ite(x <= 2, x, x + 1)));
s.add(f(x) == 2);
std::cout << s.check() << std::endl;
这会生成以下 SMTLib 格式的代码:
(declare-fun f (Int) Int)
(declare-fun x () Int)
(assert (forall ((x Int)) (! (= (f x) (ite (<= x 2) x (+ x 1))) :weight 0)))
(assert (= (f x) 2))
(check-sat)
显而易见的答案是 x=2。然而,在执行过程中,Z3 似乎进入了无限循环,完全停止响应。
为什么会发生这种情况,我应该如何在 Z3 中正确定义分段函数?
解决方案
由于 SMT 问题通常是无法确定的(取决于问题涉及的理论),因此通常可以预期 Z3 不会因某些问题而终止(在合理的时间内)。量词和非线性整数算术是常见的原因。
默认情况下,Z3 分析它给出的问题并相应地配置(例如选择子求解器)。如果您想禁用它,例如因为您想自己配置 Z3。使用(set-option :auto_config false)
.
转向你的例子:
推荐阅读
- liferay - 如何使用 Liferay 服务构建器创建一对多关系
- json - 我可以将 JSON 存储在 Azure Key Vault 中吗
- sql-server - SQL Server:在字符串中查找值
- php - 如何在 symfony 中对对象进行排序?
- c - 向 child->child LINKED LIST 添加信息
- c# - 将表单发布到 api 端点并在 javascript 回调中获取响应
- bash - 反转文件中行顺序的Shell脚本
- hadoop-streaming - 提交 Google Dataproc Hadoop 作业时找不到 Hadoop Streaming jar?
- odoo - 基于条件的动态字符串
- angular - 我必须将货币符号(来自角货币管道)和价值分成两个不同的跨度,这样我才能达到设计要求