繁体   English   中英

使用C ++在Z3中使用Z3_parse_smtlib2_string获取Unsat Core

[英]Getting Unsat Core in Z3 using C++, with Z3_parse_smtlib2_string

我需要使用Z3_parse_smtlib2_string使用C ++ API来将一些SMTLIB字符串解析为Z3,并使用Z3 C ++ API来找到它的unsat核心。

我知道,还有其他一些方法可以找到此处此处所述的unsat内核,这些方法更容易且不那么麻烦,但是我确实希望能够仅使用从字符串解析为Z3的数据结构来做到这一点。 原因是我正在尝试使用Z3自动执行某些操作。

显然,如果我将此SMTLIB程序传递到Z3中,那就是UNSAT。

(declare-const p0 Bool)
(assert(= p0 true)) (assert(= p0 false))
(assert (exists ((x Int)) (= 3 x)))

我要做的是能够使用Z3以编程方式获取unsat核心。 我要做的是将每行分别读入Z3,并使用下面的程序使用solver.add(expr, name)给它们命名。

void my_test() {
    context c1;
    solver s(c1);

    std::string declare = "(declare-const p0 Bool)";
    std::string testing = "(assert(= p0 true)) (assert(= p0 false))";
    std::string obvious = "(assert (exists ((x Int)) (= 3 x)))";

    Z3_ast parsed1 = Z3_parse_smtlib2_string(c1, declare.c_str(), 0,0,0,0,0,0);
    expr e1(c1, parsed1);

    Z3_ast parsed2 = Z3_parse_smtlib2_string(c1, testing.c_str(), 0,0,0,0,0,0);
    expr e2(c1, parsed2);
    std::cout << "what: " << e2 << std::endl;

    Z3_ast parsed3 = Z3_parse_smtlib2_string(c1, obvious.c_str(), 0,0,0,0,0,0);
    expr e3(c1, parsed3);

    s.add(e1, "declare");
    s.add(e2, "testing");
    s.add(e3, "obvious");

    if (s.check() == z3::sat) {
        std::cout << "SAT!\n";
        model m = s.get_model();
        std::cout << m << std::endl;
    } else {
        std::cout << "UNSAT!\n";
        expr_vector core = s.unsat_core();
        std::cout << core << "\n";
        std::cout << "size: " << core.size() << "\n";
        for (unsigned i = 0; i < core.size(); i++) {
            std::cout << core[i] << "\n";
        }
    }
}

我希望使unsat核心可以只是declare ,因为这显然是错误的,而其他表达式显然是有效的。 但是,Z3给了我这个响应:

(error "line 1 column 11: unknown constant p0")
(error "line 1 column 31: unknown constant p0")
what: true
SAT!
(define-fun testing () Bool
  true)
(define-fun declare () Bool
  true)
(define-fun obvious () Bool
  true)

这显然是错误的,因为declare (assert(= p0 true)) (assert(= p0 false))的SAT是SAT! 显然,这应该是UNSAT。 另外,实际上我确实声明了p0 ,但是Z3似乎不知道我已经声明了它。

有什么想法我做错了吗?

Z3_parse_smtlib2_string的第二次调用不知道第一次调用中的声明:

Z3_ast parsed2 = Z3_parse_smtlib2_string(c1, testing.c_str(), 0,0,0,0,0,0);

最后的一串零表示“不要假设其他任何东西”,因此它不知道p0存在。 有关更多详细信息,请参见API文档中Z3_parse_smtlib2_string 在您的情况下,您想传递非空的decls

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM