【问题标题】:How to get all models or all convex evaluation?如何获得所有模型或所有凸评估?
【发布时间】:2019-09-29 03:16:33
【问题描述】:

我是使用 C++ API 的 Z3-Solver 的新手,我想解决一组不等式并找到结果。

我已阅读 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

顺便说一句,有很多关于python的教程(例如this),我可以在那里学习c++中的z3,因为exampleapi doc.不容易上手。

【问题讨论】:

    标签: c++ z3 smt


    【解决方案1】:

    您的“模型反驳”循环不太正确。由于您没有发布整个代码,因此很难判断是否可能存在其他问题,但我会这样做:

    #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;
    }
    

    此代码运行并枚举所有“具体”模型。根据您的问题,我猜您还想知道是否可以获得“符号”模型:这对于 SMT 求解器是不可能的。 SMT 求解器仅生成具体(即所有基本项)模型,因此如果您需要从它们中进行泛化,则必须在 z3 边界之外进行。

    【讨论】:

    • 我将 m[] 替换为 m.eval() 并且它可以工作。非常感谢!如果求解器无法获得符号模型,我可以使用求解器做一些集合代数吗?由于我有两个求解器 s1、s2,它们共享相同的变量,我需要知道来自(和 s1(不是 s2))的模型。 Z3可以吗?
    • 我不太确定你在问什么。但是 z3 确实有设置操作,请参见此处:github.com/Z3Prover/z3/blob/master/src/api/c%2B%2B/…
    猜你喜欢
    • 2018-05-08
    • 2020-10-24
    • 1970-01-01
    • 2023-04-05
    • 1970-01-01
    • 2012-06-04
    • 2012-11-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多