如何使用“位爆炸”方法以命题逻辑形式打印给定公式?

时间:2019-06-29 17:20:40

标签: c++ z3 smt

我正在创建一个将位向量公式转换为命题逻辑形式的函数。 一种称为“位冲击”的战术将此类位向量表达式处理为PL形式。

我一直在尝试创建一个接受位向量表达式并在其上应用位冲击策略的程序。但是由于我是本主题的新手,所以我无法弄清楚在对表达式进行位冲击处理后如何打印输出。

#include<z3++.h>  
#include<iostream>
using namespace std;
using namespace z3;

int main()
{   context c;
    tactic t = tactic(c, "bit-blast");
    expr x = c.bv_const("x", 16);
    expr y = c.bv_const("y", 16);
    expr z = c.bv_const("z", 16);
    goal g(c);
    g.add(z == x + y);
    std::cout<<g;


}

这是我尝试过的代码,但不接受表达式“ z = x + y” 但是我正在做的过程是正确的吗? 如果不是这样,在对它应用位冲击后,我应该如何打印出该表达式??

谢谢。

1 个答案:

答案 0 :(得分:1)

使用==,而不是=。即z == x + y。然后,您当然必须应用该策略:

#include<z3++.h>
#include<iostream>
using namespace std;
using namespace z3;

int main()
{   context c;
    tactic t = tactic(c, "bit-blast");
    expr x = c.bv_const("x", 16);
    expr y = c.bv_const("y", 16);
    expr z = c.bv_const("z", 16);
    goal g(c);
    g.add(z == x + y);
    apply_result r = t(g);
    std::cout << r << endl;
    return 0;
}

这将打印出被炸的目标;这相当长,所以我不会放在这里。

如果要提取实际表达式,则需要多做一些编程。 (顺便说一句:您确实需要先研究API https://z3prover.github.io/api/html/z3_09_09_8h_source.html。)

这是一个示例(我正在更改原始表达式,因此输出足够小以至于无法理解。):

#include<z3++.h>
#include<iostream>
using namespace std;
using namespace z3;

int main()
{   context c;
    tactic t = tactic(c, "bit-blast");
    expr x = c.bv_const("x", 2);
    expr y = c.bv_const("y", 2);
    goal g(c);
    g.add(y == ~x);
    apply_result r = t(g);
    if(r.size() > 0)
    {
       expr res = r[0].as_expr();
       cout << res << endl;
    }
    else
    {
        cout << "tactic failed" << endl;
    }
    return 0;
}

此打印:

$ c++ a.cpp -lz3; ./a.out
(and (not (= k!0 k!2)) (not (= k!1 k!3)))

是的,您将获得k!0等作为索引,这将使您很难回溯到xy;但这是不可避免的:bit-blaster将引入新的变量,并且API具有所有零碎的内容来重构您需要的内容:https://z3prover.github.io/api/html/z3_09_09_8h_source.html