触发Z3中的问题

时间:2012-07-25 12:06:45

标签: z3

我最近观察到Z3中有关触发的几种行为,我不明白。不幸的是,这些例子来自大型Boogie文件,所以我想我现在抽象地描述它们,只是为了看看是否有明显的答案。但是,如果具体文件更好,我可以附加它们。

基本上有三个问题,虽然第三个可能是第二个问题的一个特例。据我所知,没有任何行为是预期的,但也许我错过了一些东西。任何帮助将不胜感激!


首先:就触发而言,我的程序中的琐碎平等似乎被忽略了。例如,如果t1是一个应该与量化公理的模式匹配的术语,如果我在表格的Boogie程序中添加一行

assert t1 == t1;

然后t1 似乎被用作量化公理的触发器。我明确地添加了这一行,以便提供t1作为证明者的触发器,我经常在Boogie程序中做/做。

如果我引入了额外的功能,比如说

function f(x : same_type_as_t1) : bool
{ true }

现在改为添加一行

assert f(t1);

到我的程序,然后t1 似乎被Z3用作触发器。我检查过前程序的Z3翻译,t1上的(平凡)平等确实在Boogie翻译中存活下来(即,不是Boogie尝试做一些聪明的事情)。


其次:次要模式似乎对我不起作用。例如,我有一个程序,其中一个公理具有形式

axiom (forall ... :: {t1,t2} {t3,t4,t5} ..... );

以及t3, t4t5都已发生的情况。程序无法验证,显然是因为公理没有实例化。但是,如果我将公理重写为

axiom (forall ... :: {t3,t4,t5} {t1,t2} ..... );

然后程序验证。在这两种情况下,运行Boogie的时间大约为3秒,并且模式可以存活到Z3输出。


第三:这很可能是第二个问题的症状,但我对以下行为感到惊讶:

我写了

形式的公理
axiom (forall .. :: {t1,t2} .... );

axiom (forall ... :: {t2,t4} {t2,t3} ...some expression involving t1... );

并且在t2t3发生的情况下,第一个公理没有被实例化(我预期它是,因为在第二个公理实例化之后,{{1}发生)。但是,如果我改写为

t1

然后第一个公理被实例化。但是,如果由于某种原因,二级模式一般不会被使用,那么这也可以解释这种行为。

如果明确的例子是有用的,我当然可以附加长的例子,并且可以尝试将它们减少一点(但当然触发问题有点微妙,所以如果我也做出这个例子,我可能会失去这种行为小)。

非常感谢您的任何建议!

Alex Summers

编辑:这是一个部分说明上述第二和第三种行为的示例。我已经附加了Boogie代码,以便在此处更容易阅读,但如果它更有用,我也可以复制或通过电子邮件发送Z3输入。我已经删除了几乎所有原始的Boogie代码,但似乎很难让它变得更简单而不会完全失去行为。

下面的代码已经与我原来的例子略有不同,但我认为它足够接近。基本上,下面标记为(1)的公理不能使其第二个模式集匹配。如果我注释掉axiom(1),而是用(当前评论的)公理(2)和(3)替换它,它们只是两个模式集中每个模式集的原始副本,然后程序验证。实际上,在这种特殊情况下,有足够的公理(2)就足够了。在我的原始代码中(在我将其剪切之前),在公理(1)中翻转两个模式集的顺序也足够了,但在我的小型复制品中似乎不再是这种情况。

axiom (forall .. ::  {t2,t3} {t1,t2} .... );

axiom (forall ... :: {t2,t4} {t2,t3} ...some expression involving t1... );

1 个答案:

答案 0 :(得分:4)

第一个问题:

在预处理步骤中Z3简化了微不足道的断言。断言assert t1 == t1简化为assert true。因此,E匹配引擎不考虑术语t1。诀窍assert f(t1)是使标准t1可用于Z3的E匹配的标准方法。 Z3中目前的预处理器不够智能"删除不相关的断言assert f(t1)。当然,Z3的未来版本可能有更好的预处理器,而且这个技巧将不再适用。

对于第二个和第三个问题,有(小)Z3脚本产生所描述的行为会很好。

修改 我在你的问题中分析了这个例子。事实证明这是Z3中的一个错误。我修复了错误,修复程序将在Z3 4.1中提供。 感谢您抽出宝贵时间来缩小示例的大小。对此,我真的非常感激。在更大的实例中找到这个bug需要“永远”。 电子匹配引擎缺少一些实例。 该问题会影响包含多模式的Z3脚本,这些模式使用的函数符号f不会出现在任何一元模式中。 多模式也应该在地面f应用之前发生。 此外,必须禁用MBQI引擎。默认情况下,Boogie禁用MBQI引擎。 在这种情况下,可能会错过多模式的实例。 这个bug很长一段时间都在E-matching引擎中。我认为从未发现它有两个原因:

1-它不影响健全性(Z3不会产生错误答案,但“未知”答案)

2- MBQI引擎“补偿”任何缺失的实例。

关于为电子匹配提供附加条款的额外命令,我们可以通过以下方式对其进行模拟。 命令add_term(t)只是(assert (add_term t))的语法糖。 即使我们实现了一个预处理器来消除仅正(或负)出现的谓词符号,它也不会消除保留的谓词符号add_term。因此,即使我们添加这个预处理器,这个技巧仍将继续工作。