如何获得所有模型或所有凸评估?
How to get all models or all convex evaluation?
我是 C++ 中使用 API 的 Z3 求解器的新手,想求解一组不等式并找到结果。
我读过 the answer which written in Python 并尝试用 C++ 编写它,但它重复打印一个模型。
5 <= x + y + z <= 16
AND -4 <= x - y <= 6
AND 1 <= y - z <= 3
AND -1 <= x - z <= 7
AND x >= 0 AND y >= 0 AND z >= 0
不等式被添加到求解器中,并且有很多评价。
c 是上下文,s 是求解器。
vector<const char*> variables {"x", "y", "z"};
// ...
// till here, s was added into several constraints
while(s.check() == sat){
model m = s.get_model();
cout << m << "\n######\n";
expr tmp = c.bool_val(false);
for(int i = 0; i < variables.size(); ++ i){
tmp = tmp || (m[c.int_const(variables[i])] != c.int_const(variables[i]));
}
s.add(tmp);
}
结果:
(define-fun z () Int
0)
(define-fun y () Int
2)
(define-fun x () Int
3)
######
(define-fun z () Int
0)
(define-fun y () Int
2)
(define-fun x () Int
3)
######
(define-fun z () Int
0)
...
而且它只打印一个模型。我不确定哪里错了。
如何获取所有模型或获取一个或多个凸集(如{l1 <= x <= u1 and l2 <= x - y <= u2 and ...}),但不遍历所有评价。
顺便说一句,python有很多教程(比如this), where I can learn z3 in c++ as the example and api doc.上手并不容易
您的 "model refutation" 循环不太正确。由于您没有 post 整个代码,因此很难判断是否还有其他问题,但这就是我的处理方式:
#include<vector>
#include"z3++.h"
using namespace std;
using namespace z3;
int main(void) {
context c;
expr_vector variables(c);
variables.push_back(c.int_const("x"));
variables.push_back(c.int_const("y"));
variables.push_back(c.int_const("z"));
expr x = variables[0];
expr y = variables[1];
expr z = variables[2];
solver s(c);
s.add(5 <= x+y+z);
s.add(x+y+z <= 16);
s.add(-4 <= x-y);
s.add(x-y <= 6);
s.add(-1 <= x-z);
s.add(x-z <= 7);
s.add(x >= 0);
s.add(y >= 0);
s.add(z >= 0);
while (s.check() == sat) {
model m = s.get_model();
cout << m << endl;
cout << "#######" << endl;
expr tmp = c.bool_val(false);
for(int i = 0; i < variables.size(); ++i) {
tmp = tmp || (variables[i] != m.eval(variables[i]));
}
s.add(tmp);
}
return 0;
}
此代码运行并枚举所有 "concrete" 模型。从你的问题来看,我猜你也想知道你是否可以获得 "symbolic" 模型:这对于 SMT 求解器是不可能的。 SMT 求解器只生成具体的(即所有基本项)模型,因此如果您需要从它们进行概括,则必须在 z3 边界之外进行。
我是 C++ 中使用 API 的 Z3 求解器的新手,想求解一组不等式并找到结果。
我读过 the answer which written in Python 并尝试用 C++ 编写它,但它重复打印一个模型。
5 <= x + y + z <= 16
AND -4 <= x - y <= 6
AND 1 <= y - z <= 3
AND -1 <= x - z <= 7
AND x >= 0 AND y >= 0 AND z >= 0
不等式被添加到求解器中,并且有很多评价。
c 是上下文,s 是求解器。
vector<const char*> variables {"x", "y", "z"};
// ...
// till here, s was added into several constraints
while(s.check() == sat){
model m = s.get_model();
cout << m << "\n######\n";
expr tmp = c.bool_val(false);
for(int i = 0; i < variables.size(); ++ i){
tmp = tmp || (m[c.int_const(variables[i])] != c.int_const(variables[i]));
}
s.add(tmp);
}
结果:
(define-fun z () Int
0)
(define-fun y () Int
2)
(define-fun x () Int
3)
######
(define-fun z () Int
0)
(define-fun y () Int
2)
(define-fun x () Int
3)
######
(define-fun z () Int
0)
...
而且它只打印一个模型。我不确定哪里错了。
如何获取所有模型或获取一个或多个凸集(如{l1 <= x <= u1 and l2 <= x - y <= u2 and ...}),但不遍历所有评价。
顺便说一句,python有很多教程(比如this), where I can learn z3 in c++ as the example and api doc.上手并不容易
您的 "model refutation" 循环不太正确。由于您没有 post 整个代码,因此很难判断是否还有其他问题,但这就是我的处理方式:
#include<vector>
#include"z3++.h"
using namespace std;
using namespace z3;
int main(void) {
context c;
expr_vector variables(c);
variables.push_back(c.int_const("x"));
variables.push_back(c.int_const("y"));
variables.push_back(c.int_const("z"));
expr x = variables[0];
expr y = variables[1];
expr z = variables[2];
solver s(c);
s.add(5 <= x+y+z);
s.add(x+y+z <= 16);
s.add(-4 <= x-y);
s.add(x-y <= 6);
s.add(-1 <= x-z);
s.add(x-z <= 7);
s.add(x >= 0);
s.add(y >= 0);
s.add(z >= 0);
while (s.check() == sat) {
model m = s.get_model();
cout << m << endl;
cout << "#######" << endl;
expr tmp = c.bool_val(false);
for(int i = 0; i < variables.size(); ++i) {
tmp = tmp || (variables[i] != m.eval(variables[i]));
}
s.add(tmp);
}
return 0;
}
此代码运行并枚举所有 "concrete" 模型。从你的问题来看,我猜你也想知道你是否可以获得 "symbolic" 模型:这对于 SMT 求解器是不可能的。 SMT 求解器只生成具体的(即所有基本项)模型,因此如果您需要从它们进行概括,则必须在 z3 边界之外进行。