- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试使用 Z3 解决非线性实数问题。我需要 Z3 来生成多个解决方案。在问题域中,精度不是关键问题;我只需要小数点后一位或两位小数。因此,我需要将 Z3 设置为不探索实数的所有搜索空间,以最大限度地减少寻找多个解决方案的时间。
我正在尝试用 float 替换实数。我阅读了 c_api.c 文件中的 fpa 示例,但发现它让我有点困惑。
例如,假设我想在以下代码中转换实数:
config cfg;
cfg.set("auto_config", true);
context con(cfg);
expr x = con.real_const("x");
expr y = con.real_const("y");
solver sol(con);
sol.add(x*y > 10);
std::cout << sol.check() << "\n";
std::cout << sol.get_model() << "\n";
我试过下面的代码,但是没有用
config cfg;
cfg.set("auto_config", true);
context con(cfg);
expr sign = con.bv_const("sig", 1);
expr exp = con.bv_const("exp", 10);
expr sig = con.bv_const("sig", 10);
expr x = to_expr(con, Z3_mk_fpa_fp(con, sign, exp, sig));
expr y = to_expr(con, Z3_mk_fpa_fp(con, sign, exp, sig));
solver sol(con);
sol.add(x*y > 10);
std::cout << sol.check() << "\n";
输出是:
Assertion failed: false, file c:\users\rehab\downloads\z3-master\z3-master\src\a
pi\c++\z3++.h, line 1199
我的问题是:
最佳答案
我不确定使用 float 是否是解决问题的最佳方法。但听起来你尝试了所有其他选项,非线性正在阻碍你。请注意,即使您使用 float 对问题建模,浮点运算也非常棘手,求解器可能很难找到令人满意的模型。此外,由于数值不稳定,解决方案可能与实际结果相去甚远。
抛开所有这些,使用 C api 编写查询代码的正确方法是(假设我们使用 32 位单精度 float ):
#include <z3.h>
int main(void) {
Z3_config cfg = Z3_mk_config();
Z3_context ctx = Z3_mk_context(cfg);
Z3_solver s = Z3_mk_solver(ctx);
Z3_solver_inc_ref(ctx, s);
Z3_del_config(cfg);
Z3_sort float_sort = Z3_mk_fpa_sort(ctx, 8, 24);
Z3_symbol s_x = Z3_mk_string_symbol(ctx, "x");
Z3_symbol s_y = Z3_mk_string_symbol(ctx, "y");
Z3_ast x = Z3_mk_const(ctx, s_x, float_sort);
Z3_ast y = Z3_mk_const(ctx, s_y, float_sort);
Z3_symbol s_x_times_y = Z3_mk_string_symbol(ctx, "x_times_y");
Z3_ast x_times_y = Z3_mk_const(ctx, s_x_times_y, float_sort);
Z3_ast c1 = Z3_mk_eq(ctx, x_times_y, Z3_mk_fpa_mul(ctx, Z3_mk_fpa_rne(ctx), x, y));
Z3_ast c2 = Z3_mk_fpa_gt(ctx, x_times_y, Z3_mk_fpa_numeral_float(ctx, 10, float_sort));
Z3_solver_assert(ctx, s, c1);
Z3_solver_assert(ctx, s, c2);
Z3_lbool result = Z3_solver_check(ctx, s);
switch(result) {
case Z3_L_FALSE: printf("unsat\n");
break;
case Z3_L_UNDEF: printf("undef\n");
break;
case Z3_L_TRUE: { Z3_model m = Z3_solver_get_model(ctx, s);
if(m) Z3_model_inc_ref(ctx, m);
printf("sat\n%s\n", Z3_model_to_string(ctx, m));
break;
}
}
return 0;
}
运行时,打印:
sat
x_times_y -> (fp #b0 #xbe #b10110110110101010000010)
y -> (fp #b0 #xb5 #b00000000000000000000000)
x -> (fp #b0 #x88 #b10110110110101010000010)
这些是单精度 float ;例如,您可以在维基百科中阅读有关它们的信息。在更传统的表示法中,它们是:
x_times_y -> 1.5810592e19
y -> 1.8014399e16
x -> 877.6642
这使用起来很棘手,但是你问的是什么。
我衷心推荐使用 Python API,至少在投入到如此复杂的 C 代码之前,先了解求解器的功能。这是它在 Python 中的样子:
from z3 import *
x = FP('x', FPSort(8, 24))
y = FP('y', FPSort(8, 24))
s = Solver()
s.add(x*y > 10);
s.check()
print s.model()
运行时,打印:
[y = 1.32167303562164306640625,
x = 1.513233661651611328125*(2**121)]
也许不是您所期望的,但它确实是一个有效的模型。
只是为了让您尝尝简单的滋味,下面是如何使用 Haskell 绑定(bind)来表达相同的问题(这只是一行代码!)
Prelude Data.SBV> sat $ \x y -> fpIsPoint x &&& fpIsPoint y &&& x * y .> (10::SFloat)
Satisfiable. Model:
s0 = 5.1129496e28 :: Float
s1 = 6.6554557e9 :: Float
请注意, float 在 NaN
/Infinity
值方面也存在问题,因此您可能必须明确避免这些问题。 (这就是 Haskell 表达式通过使用 isFPPoint
谓词所做的事情。用 Python 或 C 编写它需要更多代码,但肯定是可行的。)
应该强调的是,从字面上看,与 Z3 的任何其他绑定(bind)(Python、Haskell、Scala 等)都会给您带来比使用 C/C++/Java 更好的体验。 (即使在 SMTLib 中直接编码也会更好。)
因此,我衷心推荐使用一些更高级别的接口(interface)(Python 是一个很好的接口(interface):它很容易学习),一旦您对模型及其工作方式有信心,您就可以开始用 C 编写相同的代码如有必要。
关于c++ - 在 Z3 C++ API 中使用浮点运算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50575967/
为什么 (defun boolimplies (a b) (or (not a) b)) if called as(boolimplies 'a 'b) 返回 B? 即使我不使用任何 boolean
这个问题已经有答案了: Are there builtin functions for elementwise boolean operators over boolean lists? (5 个回答
我正在寻求帮助以使以下功能看起来更清晰。我觉得我可以通过使用更少的代码行来实现同样的目标。 标题看起来一定很困惑,所以让我详细说明一下。我创建了一个函数,它接受用户输入(即 72+5),将字符串拆分为
我正在学习 C++ 并尝试为矩阵编写一个 C++ 类,我在其中将矩阵存储为一维 C 数组。为此,我定义了一个 element成员函数根据矩阵元素在数组中的位置访问矩阵元素。然后我重载了 class
我正在学习 C++ 并尝试为矩阵编写一个 C++ 类,我在其中将矩阵存储为一维 C 数组。为此,我定义了一个 element成员函数根据矩阵元素在数组中的位置访问矩阵元素。然后我重载了 class
伙计们,以下内容不起作用 函数返回 true,变量返回 false,但它不会进入 when 子句。我尝试像这样放大括号 但是当我将变量的值设置为 true 并将上面的代码更改为 它进入w
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 9 年前。 Improve th
我是原生 C 语言的新手,但我没有看到错误。 我尝试在这种情况下使用 if 操作: #define PAGE_A 0 #define PAGE_B 1 int pageID = 0; if (page
我正在从事一个项目,让用户鼠标滚轮移动并知道它向上或向下滚动。在我的代码中,我可以上下移动。但我想将 Action 保存到一个字符串中。例如,如果用户向上向上向下滚动'mhmh' 显示返回“UUD”但
我有一个 MySQL 表 payment我在其中存储客户的所有付款相关数据。表字段为:fileNo , clientName , billNo , billAmount , status 。我想构建一
我的表架构如下: +------+-------+-------+
我有这个(顺便说一句,我刚刚开始学习): #include #include using namespace std; int main() { string mystr; cout << "We
我正在用 bash 构建一个用于 Linux (SLES 11SP3) 的脚本。我想通过使用以下语法查找它的 pid 来检查某个进程是否存在: pid="$(ps -ef | grep -v grep
我有一个包含两列的表格; CREATE TABLE IF NOT EXISTS `QUESTION_CATEGORY_RELATION` ( `question_id` int(16) NOT N
我对 Python 如何计算 bool 语句感到困惑。 例如 False and 2 or 3 返回 3 这是如何评估的?我认为 Python 首先会查看“False and 2”,甚至不查看“or
这个问题在这里已经有了答案: 12 年前关闭。 这可能是非常基本的......但我似乎不明白: 如何 (2 & 1) = 0 (3 & 1) = 1 (4 & 1) = 0 等等.. 上面的这种模式似
无论如何在Haskell中定义如下函数? or True True = True or True undefined = True or True False
如您所知,TCL 有一些数学函数,例如 罪 , 因 , 和 假设 在 中调用的expr 带有 的命令() 大括号如下: puts [expr sin(1.57)] 现在如何使用 TCL 添加功能 li
让我们考虑两个数组列表。 ArrayList list1 = new ArrayList(); list1.add(1); list1.add(2); list1.add(3); ArrayList
我想包含和排除使用AND和OR的专业知识,包括与AND和OR操作正常工作。但是,当将排除专家与AND和OR一起使用时,返回与3相同的结果计数。我使用的是1.4版 Elasticsearch 。帮助我解
我是一名优秀的程序员,十分优秀!