【问题标题】:How to use arg() function from z3?如何使用 z3 中的 arg() 函数?
【发布时间】:2019-06-05 06:52:53
【问题描述】:

我最近开始使用带有 c++ 绑定的 z3 API。我的任务是获取 表达式中的单个元素

示例:(x || !z) && (y || !z) && (!x || !y || z)

如何通过使用函数 arg(i) 对每个位置进行索引来获取单个变量?

在给定示例的情况下,arg(1) 应返回变量“X”。 z3 中是否还有其他功能可以提供我想要的输出?

这是我尝试过的代码,但输出不是单个变量:

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

int main()
{
    context c;
    expr x = c.bool_const("x");
    expr y = c.bool_const("y");
    expr z = c.bool_const("z");
    expr prove = (x || !z) && (y || !z) && (!x || !y || z);
    solver s(c);
    expr argument = prove.arg(1);
    std::cout<<argument;  
}

输出:

(or (not x) (not y) z)(base)

我基本上需要创建一个自动化系统来索引表达式中的每个位置,并检查它是运算符还是操作数,然后插入到数据结构中。所以我想我会创建一个循环并索引表达式中的每个位置。但是 arg(i) 并没有给我我想要的输出。

【问题讨论】:

    标签: c++ z3


    【解决方案1】:

    您必须遍历 AST 并挑选出节点。 Z3 AST 可能相当棘手,因此在不确切知道您的目标是什么的情况下,很难判断这是否是最佳方法。但是,假设您真的想通过 AST,您可以这样做:

    #include<iostream>
    #include<string>
    #include "z3++.h"
    using namespace z3;
    using namespace std;
    
    void walk(int tab, expr e)
    {
        string blanks(tab, ' ');
    
        if(e.is_const())
        {
            cout << blanks << "ARGUMENT: " << e << endl;
        }
        else
        {
            cout << blanks << "APP: " << e.decl().name() << endl;
            for(int i = 0; i < e.num_args(); i++)
            {
                walk(tab + 5, e.arg(i));
            }
        }
    }
    
    int main()
    {
        context c;
        expr x = c.bool_const("x");
        expr y = c.bool_const("y");
        expr z = c.bool_const("z");
        expr e = (x || !z) && (y || !z) && (!x || !y || z);
    
        walk(0, e);
    }
    

    运行时,此程序会打印:

    APP: and
         APP: and
              APP: or
                   ARGUMENT: x
                   APP: not
                        ARGUMENT: z
              APP: or
                   ARGUMENT: y
                   APP: not
                        ARGUMENT: z
         APP: or
              APP: or
                   APP: not
                        ARGUMENT: x
                   APP: not
                        ARGUMENT: y
              ARGUMENT: z
    

    因此,您可以准确地看到应用程序 (APP) 和参数 (ARGUMENT) 的位置。您可以从这里获取并构建您所说的数据结构。

    但是,请注意 z3 AST 可以有许多不同类型的对象:量词、数字、位向量、浮点数。因此,如果您想让它适用于任意 z3 表达式,那么在开始编码之前详细研究实际的 AST 将是一个好主意,了解所有复杂性。

    【讨论】:

    • 非常感谢。我真的很感谢你的帮助。这给了我一个新的线索来解决我的问题。
    • 先生,如果我必须将这些参数和应用程序存储在它们相应的数据类型变量中怎么办?例子。我试图将常量参数存储在“ bool variable[x] = e ”中,但这没有成功。在 z3 中是否有任何功能可以帮助保存各种类似类型的变量,例如和 ARRAY?
    • 请注意,表达式不是布尔值。所以你不能把它放在一个布尔数组中。用于这种情况的最佳数据类型实际上是表达式向量,请参见此处:z3prover.github.io/api/html/z3_09_09_8h_source.html#l00071
    • .name() 函数返回符号类型。 z3中是否有可以将其转换为表达式的函数?
    猜你喜欢
    • 1970-01-01
    • 2017-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-20
    • 1970-01-01
    相关资源
    最近更新 更多