首页 > 解决方案 > Z3如何将expr转换为SMT?

问题描述

在尝试了解 Z3 工具时,我对 Z3 如何构造表达式感到困惑。另外,我是新手,我已经解决了相关的问题,但他们没有回答我的问题。

使用 Z3,(比如 cpp 实现),假设有一个表达式

expr e1=((x[0]=tru && y[0]!=tru)||(x[0]!=tru &&y[0]=tru));

tru 是重言式。

在打印此表达式时,该工具会显示以下树:

 (let ((a!1 (and (or x0 (not x0)) (distinct y0 (or x0 (not x0))))))
      (or a!1 (or x0 (not x0))))

这不是我希望我的 e1 代表的。这似乎是我所写内容的有效/漂亮/简写。

首先,我能否以某种方式自己将 expr 转换为 SMT,以便检查它是否被正确翻译?

a!1其次,有没有办法以我表示它的简单方式打印表达式,而不是在 SMT 语言中以有效的结构(使用子树等)?也许我可以关闭一个开关?这可能需要对该工具有深入的了解,因此我已经相应地标记了这个问题。

标签: c++z3smt

解决方案


有些“翻译”是不可避免的。当 Z3 为您的表达式构建解析树时,它会将它们重写为内部形式。这不仅仅是为了“效率”。某些表面形式也没有内部表示,而是被重写了。

当然,漂亮的印刷是另一回事。有很多方法可以控制漂亮的打印效果。如果您运行z3 -p并查看漂亮打印部分的输出,您会看到:

[module] pp, description: pretty printer
    bounded (bool) (default: false)
    bv_literals (bool) (default: true)
    bv_neg (bool) (default: false)
    decimal (bool) (default: false)
    decimal_precision (unsigned int) (default: 10)
    fixed_indent (bool) (default: false)
    flat_assoc (bool) (default: true)
    fp_real_literals (bool) (default: false)
    max_depth (unsigned int) (default: 5)
    max_indent (unsigned int) (default: 4294967295)
    max_num_lines (unsigned int) (default: 4294967295)
    max_ribbon (unsigned int) (default: 80)
    max_width (unsigned int) (default: 80)
    min_alias_size (unsigned int) (default: 10)
    pretty_proof (bool) (default: false)
    simplify_implies (bool) (default: true)
    single_line (bool) (default: false)

您可以使用这些设置来控制如何完成漂亮的打印,这可能会更好地满足您的需求。特别是,从您的问题描述来看,我建议设置以下两个参数:

    pp.max_depth      --> 4294967295
    pp.min_alias_size --> 4294967295

(数字并不重要,只要让它们足够大。)这两个设置应该避免漂亮的打印机创建a!1子树,你看到了。

不幸的是,这些选项的确切含义并没有得到很好的记录。其中一些,你可以从他们的名字中猜到,其他的你可以玩一玩,看看他们的影响是什么。但是如果你真的想知道它们是如何改变输出的,你就必须深入研究 z3 源代码本身。祝你好运!


推荐阅读