我正在研究一个项目,其重点是使用术语重写来解决/简化固定大小的位向量算术问题,这对于某些决策过程的先前步骤(例如基于位的步骤)非常有用。 -爆破。术语重写可以解决问题,或者产生更简单的等效问题,因此两者的结合可以带来相当大的加速。
我知道许多SMT求解器实现了这种策略(例如Boolector,Beaver,Alt-Ergo或Z3),但很难找到详细描述这些重写步骤的论文/技术报告/等。一般来说,我只发现了作者在几段中描述这种简化步骤的论文。我想找一些文件详细解释术语重写的用法:提供规则的例子,讨论AC重写的便利性和/或其他等式公理,使用重写策略等。
目前,我刚刚找到了技术报告A Decision Procedure for Fixed-Width Bit-Vectors,其中描述了CVC Lite执行的规范化/简化步骤,我想找到更多像这样的技术报告!我还发现了一张关于Term rewriting in STP的海报,但这只是一个简短的总结。
我已经访问了那些SMT求解器的网站,我在他们的出版物页面中进行了搜索...
我很感激任何参考,或任何关于如何在当前版本的知名SMT求解器中使用术语重写的解释。我对Z3特别感兴趣,因为它看起来有一个最聪明的简化阶段。例如,Z3 3. *引入了一个新的位向量决策程序,但不幸的是,我找不到任何描述它的论文。
答案 0 :(得分:11)
我同意你的看法。很难找到描述现代SMT求解器中使用的预处理步骤的论文。
大多数SMT求解器开发人员都认为这些预处理步骤对于Bit-Vector理论非常重要。
我认为这些技术的出版不是出于以下几个原因:大多数技巧本身并不是一项重要的科学贡献。大多数技术仅适用于特定系统的环境;一种似乎在求解器A
上运行良好的技术,对解算器B
不起作用。
我相信拥有开源SMT求解器是解决这个问题的唯一方法。即使我们发布了特定求解器A
中使用的技术,如果没有看到它的源代码,也很难重现求解器A的实际行为。
无论如何,这里是Z3执行的预处理的摘要,以及重要的细节。
若干简化规则可能会在本地减小此大小,但会在全局范围内增加。简化器必须避免由这种简化引起的内存爆炸。您可以在以下网址找到示例:http://research.microsoft.com/en-us/um/people/leonardo/mit2011.pdf
第一个简化步骤仅执行保持等效性的局部简化。 示例:
2*x - x -> x x and x -> x
t = v
,其中v
是一个值。它用t
替换v
到处。t = 0 and F[t] -> t = 0 and F[0]
接下来,它对位矢量执行高斯消除。但是,只消除算术表达式中最多出现两次的变量。
此限制用于防止公式中加法器和乘数的增加。
例如,假设我们x = y+z+w
和x
出现在p(x+z)
,p(x+2*z)
,p(x+3*z)
和p(x+4*z)
。然后,在取消x
后,我们会p(y+2*z+w)
,p(y+3*z+w)
,p(y+4*z+w)
和p(y+5*z+w)
。虽然我们删除了x
,但我们有比原始公式更多的加法器。
接下来,它消除了无约束变量。 Robert Brummayer和Roberto Brutomesso的博士论文描述了这种方法。
然后,执行另一轮简化。这次,执行局部上下文简化。 这些简化可能非常昂贵。因此,使用了要访问的最大节点数的阈值(默认值为1000万)。 本地上下文简化包含诸如
(x != 0 or y = x+1) -> (x != 0 or y = 1)
a b + a c - > (B + C)* A
然后,它尝试通过应用关联性和可交换性来最小化加法器和乘数的数量。
假设公式包含术语a + (b + c)
和a + (b + d)
。然后,Z3会将其重写为:(a+b)+c
和(a+b)+d
。
在转换之前,Z3必须编码4个加法器。之后,只需要编码三个加法器,因为Z3使用完全共享的表达式。
如果公式仅包含相等,连接,提取和类似运算符。然后,Z3使用基于union-find和同余闭包的专用求解器。
否则,它会爆炸所有内容,使用AIG来最小化布尔公式,并调用其SAT求解器。
答案 1 :(得分:1)
Z3使用重写来进行预处理期间执行的许多简化。用于UFBV策略的许多重写规则(带有量词)在下面的文章中有详细描述:
Wintersteiger, Hamadi, de Moura: Efficiently Solving Quantified Bit-Vector Formulas, FMCAD, 2010