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

Z3中AC符号的简化:bvadd vs bvxor/bvor/etc,z3,Z3,我想知道为什么Z3能够通过在某些情况下应用结合性和交换性AC公理来证明一些平凡的等式,而在其他情况下却不能。比如说, (simplify (= (bvadd x (bvadd y z)) (bvadd z (bvadd y x)))) ,但是 Z3只是将bvxor应用程序展平 我查看了源代码src/ast/bv_decl_plugin.cpp,bvadd和bvxor都声明为AC符号。它是否与适用于这些符号的重写规则有关?特别是,mk_bv_add src/ast/rewriter/bv_rew

我想知道为什么Z3能够通过在某些情况下应用结合性和交换性AC公理来证明一些平凡的等式,而在其他情况下却不能。比如说,

(simplify (= (bvadd x (bvadd y z)) (bvadd z (bvadd y x))))
,但是

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/simplier/poly_simplier\u plugin.cpp,将bvadd项处理为单项式之和。

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

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

br_状态bv_重写器::mk_bv_xorunsigned num,expr*const*args,expr_ref&result{ SASSERTnum>0; ... 违约: //新线 std::sortnew_args.begin、new_args.end、ast_to_lt; // 结果=m_util.mk_bv_xornew_args.size,new_args.c_ptr; 返回BR_DONE; } } 也就是说,Z3重写器不应该应用所有可能的简化和/或生成规范范式。他们的主要目标是生成可能更易于求解的公式。规则根据需求增长,例如,示例X中的Z3速度太慢,可以通过应用新的预处理规则或基于用户请求来解决性能问题。因此,如果您认为这是一个有用的特性,我们可以添加一个选项,对每个AC运算符的参数进行排序

编辑

更正:我们还必须修改以下语句

如果合并&!展平&&num|coefs==0 | | num|coefs==1&!v1.is_zero&&v1!=rational::twosz的幂-1 返回BR_失败; 当现有重写规则均不适用时,此语句中断mk_bv_xor的执行。我们还必须修改它。我实施了这些修改。我们可以使用新选项bv-sort-ac激活它们。默认情况下,此选项未启用。新选项在不稳定的“正在进行的工作”分支中可用。当设置为true时,它将对位向量AC运算符进行排序。 注意,不稳定分支使用新的参数设置框架,该框架将在下一个正式版本中提供。是关于如何构建不稳定分支的说明。 这些修改也将在本周的网站上提供

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

声明常量a_uuvec8 声明常量b_uuvec8 声明常量c_uuvec8 声明常量d_uuvec8 简化=bvxor AB 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=b或a b c或b a c simplify=bv或AB c bv或AB c:bv排序ac true simplify=b或a或b或b或b a c:bv排序ac true simplify=BV和AB c和b a c simplify=bv和a b c bv和b a c:bv sort ac true simplify=bv和a bv和b b c bv和b a c:bv sort ac true ; 在新的参数设置框架中,每个模块都有自己的参数。 ; bv sort ac是重写器框架的一个参数。 设置选项:rewriter.bv-sort-ac true ; 现在,Z3将把下面的公式改写为true,即使我们没有提供 ; 选项:bv sort ac true simplify=BV和AB c和b a c ; 它还将简化以下断言。 assert=bVC和bVC和bAC 检查sat
结束编辑是的,它与应用于符号的重写规则有关。 Z3有两个表达式简化器:src/ast/rewriter和src/ast/simplifier。src/ast/simplifier是遗留的,它不在新代码中使用。SMT-LIB前端中的simplify命令基于src/ast/rewriter。mk_bv_add实际上使用src/ast/rewriter/poly_rewriter.h中的mk_add_核心

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

br_状态bv_重写器::mk_bv_xorunsigned num,expr*const*args,expr_ref&result{ SASSERTnum>0; ... 违约: //新线 std::sortnew_args.begin、new_args.end、ast_to_lt; // 结果=m_util.mk_bv_xornew_args.size,new_args.c_ptr; 返回BR_DONE; } } 也就是说,Z3重写器不应该应用所有可能的简化和/或生成规范范式。他们的主要目标是生成可能更易于求解的公式。规则根据需求增长,例如,示例X中的Z3速度太慢,可以通过应用新的预处理规则或基于用户请求来解决性能问题。因此,如果您认为这是一个有用的特性,我们可以添加一个选项,对每个AC运算符的参数进行排序

编辑

更正:我们还必须修改以下语句

如果合并&!展平&&num|coefs==0 | | num|coefs==1&!v1.is_zero&&v1!=rational::twosz的幂-1 返回BR_失败; 当现有重写规则均不适用时,此语句中断mk_bv_xor的执行。我们还必须修改它。我实施了这些修改。我们可以使用新选项bv-sort-ac激活它们。默认情况下,此选项未启用。新选项在不稳定的“正在进行的工作”分支中可用。当设置为true时,它将对位向量AC运算符进行排序。 注意,不稳定分支使用新的参数设置框架,该框架将在下一个正式版本中提供。是关于如何构建不稳定分支的说明。 这些修改也将在本周的网站上提供

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

声明常量a_uuvec8 声明常量b_uuvec8 声明常量c_uuvec8 声明常量d_uuvec8 简化=bvxor AB 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=b或a b c或b a c simplify=bv或AB c bv或AB c:bv排序ac true simplify=b或a或b或b或b a c:bv排序ac true simplify=BV和AB c和b a c simplify=bv和a b c bv和b a c:bv sort ac true simplify=bv和a bv和b b c bv和b a c:bv sort ac true ; 在新的参数设置框架中,每个模块都有自己的参数。 ; bv sort ac是重写器框架的一个参数。 设置选项:rewriter.bv-sort-ac true ; 现在,Z3将把下面的公式改写为true,即使我们没有提供 ; 选项:bv sort ac true simplify=BV和AB c和b a c ; 它还将简化以下断言。 assert=bVC和bVC和bAC 检查sat
END EDIT

如果有这样一个选项,可以对AC运算符的参数进行排序,那就太好了。我有一个比较SHA1块的两个AC等效实现的简单基准。大多数SMT解算器超时12小时或内存不足。我可以在z3test.codeplex.com的某个地方提交吗?如果这有用的话。这来自一个关于位向量程序等价性检查的项目,该项目最初由一家公司提出。值得注意的是,这家公司的评论之一是,SMT解算器对AC运营商的重新排序参数非常敏感。事实上,这一行并不能使Z3简化示例。mk_bv_xor函数返回BR_FAILED。原来num==flat_args.size so flatted没有设置为true…是的,您是对的。我修正了答案,并实现了新选项。我希望这会有所帮助。如果有这样一个选项,能够对AC运算符的参数进行排序,那将是一件非常棒的事情。我有一个比较SHA1块的两个AC等效实现的简单基准。大多数SMT解算器超时12小时或内存不足。我可以在z3test.codeplex.com的某个地方提交吗?如果这有用的话。这来自一个关于位向量程序等价性检查的项目,该项目最初由一家公司提出。值得注意的是,这家公司的评论之一是,SMT解算器对AC运营商的重新排序参数非常敏感。事实上,这一行并不能使Z3简化示例。mk_bv_xor函数返回BR_FAILED。原来num==flat_args.size so flatted没有设置为true…是的,您是对的。我修正了答案,并实现了新选项。我希望有帮助。
(simplify (= (bvxor x (bvxor y z)) (bvxor z (bvxor y x))))