简化Z3中的AC符号:bvadd vs bvxor / bvor / etc.

时间:2013-03-24 15:38:04

标签: z3

我想知道为什么Z3能够通过在某些情况下应用关联性和交换性(AC)公理来证明一些微不足道的平等,但在其他情况下却不能。例如,

(simplify (= (bvadd x (bvadd y z)) (bvadd z (bvadd y x))))

reduces to true,但

(simplify (= (bvxor x (bvxor y z)) (bvxor z (bvxor y x))))

does not(Z3只会使bvxor应用程序变平)。

我看了一下源代码(src / ast / bv_decl_plugin.cpp),并且bvadd和bvxor都被声明为AC符号。它是否与应用于每个符号的重写规则相关?特别是,mk_bv_add(src / ast / rewriter / bv_rewriter.cpp)调用mk_add_core(src / ast / simplifier / poly_simplifier_plugin.cpp),它将bvadd术语处理为单项式的总和。

1 个答案:

答案 0 :(得分:4)

是的,它与应用于符号的重写规则有关。 Z3有两个表达式简化:src/ast/rewritersrc/ast/simplifiersrc/ast/simplifier是遗留的,不会在新代码中使用。 SMT-LIB前端中的simplify命令基于src/ast/rewritermk_bv_add实际上在mk_add_core中使用src/ast/rewriter/poly_rewriter.h

更改代码以强制Z3将问题中的bvxor表达式简化为true并不难。我们只需在src/ast/rewriter/bv_rewriter.h添加以下代码行。 新行只是对bvxor参数进行排序。这是任何AC操作员的正确重写。

br_status bv_rewriter::mk_bv_xor(unsigned num, expr * const * args, expr_ref & result) {
    SASSERT(num > 0);
    ...
    default:
        // NEW LINE
        std::sort(new_args.begin(), new_args.end(), ast_to_lt());
        //
        result = m_util.mk_bv_xor(new_args.size(), new_args.c_ptr());
        return BR_DONE;
    }
}

话虽这么说,Z3重写器不应该应用所有可能的简化和/或产生规范的正规形式。他们的主要目标是生成可能更容易求解的公式。规则基于需求而增长(例如,Z3在示例X中太慢,并且性能问题可以通过应用新的预处理规则来“固定”),或者基于用户请求。因此,如果您认为这是一个有用的功能,我们可以添加一个选项来对每个AC运算符的参数进行排序。

修改

更正:我们还必须修改以下声明

if (!merged && !flattened && (num_coeffs == 0 || (num_coeffs == 1 && !v1.is_zero() && v1 != (rational::power_of_two(sz) - numeral(1))))
    return BR_FAILED;

当没有现有的重写规则适用时,此语句会中断mk_bv_xor的执行。我们还必须修改它。我实施了这些修改here。我们可以使用新选项:bv-sort-ac激活它们。默认情况下,此选项未启用 。新选项在unstable(正在进行中)分支中可用。设置为true时,它将对位向量AC运算符进行排序。 请注意,unstable分支使用将在下一个正式版本中提供的新参数设置框架。 Here是有关如何构建unstable分支的说明。 这些修改也将于本周在nightly builds上提供。

以下是一些使用新选项的示例:

(declare-const a (_ BitVec 8))
(declare-const b (_ BitVec 8))
(declare-const c (_ BitVec 8))
(declare-const d (_ BitVec 8))

(simplify (= (bvxor a b c) (bvxor b a c)))
(simplify (= (bvxor a b c) (bvxor b a c)) :bv-sort-ac true)
(simplify (= (bvxor a (bvxor b c)) (bvxor b a c)) :bv-sort-ac true)

(simplify (= (bvor a b c) (bvor b a c)))
(simplify (= (bvor a b c) (bvor b a c)) :bv-sort-ac true)
(simplify (= (bvor a (bvor b c)) (bvor b a c)) :bv-sort-ac true)


(simplify (= (bvand a b c) (bvand b a c)))
(simplify (= (bvand a b c) (bvand b a c)) :bv-sort-ac true)
(simplify (= (bvand a (bvand b c)) (bvand b a c)) :bv-sort-ac true)

; In the new parameter setting framework, each module has its own parameters.
; The bv-sort-ac is a parameter of the "rewriter" framework.
(set-option :rewriter.bv-sort-ac true)

; Now, Z3 will rewrite the following formula to true even when we do not provide
; the option :bv-sort-ac true
(simplify (= (bvand a b c) (bvand b a c)))

; It will also simplify the following assertion.
(assert (= (bvand a b c) (bvand b a c)))

(check-sat)

结束编辑