Z3 Dafny作为SAT-QBF解算器没有给出正确的结果

Z3 Dafny作为SAT-QBF解算器没有给出正确的结果,z3,dafny,quantifiers,bounded-quantification,Z3,Dafny,Quantifiers,Bounded Quantification,我试图养成习惯,使用Dafny作为一些简单公式的友好SAT-QBF解算器,因为在Z3中这样做太不舒服了 这样做的背景是,我已经实现了库珀的量词消除算法,当所有变量都有界时,它可以用作决策过程:因此,我想知道在执行之前应该得到哪个结果 然而,我在达夫尼遇到了一个问题 例如,让我们提出以下公式(用Dafny编写): 在my Cooper中,它返回True,而Dafny也返回断言冲突。我已经做了一个手工库珀执行(铅笔和纸),我认为正确是正确的 知道发生了什么吗 PS:我还没有在Z3中尝试过,因为我正在

我试图养成习惯,使用Dafny作为一些简单公式的友好SAT-QBF解算器,因为在Z3中这样做太不舒服了

这样做的背景是,我已经实现了库珀的量词消除算法,当所有变量都有界时,它可以用作决策过程:因此,我想知道在执行之前应该得到哪个结果

然而,我在达夫尼遇到了一个问题

例如,让我们提出以下公式(用Dafny编写):

在my Cooper中,它返回
True
,而Dafny也返回
断言冲突
。我已经做了一个手工库珀执行(铅笔和纸),我认为
正确
是正确的

知道发生了什么吗

PS:我还没有在Z3中尝试过,因为我正在用其他理论做第一次尝试

编辑

使用一个简单的技巧来实例化量化的变量可以避免触发警告:创建一个未解释的函数


method Main() {
 assert exists x_1 : int {:trigger P(x_1)} :: exists y_1: int {:trigger P(y_1)} 
    :: exists x_2: int {:trigger P(x_2)} :: exists y_2 : int {:trigger P(y_2)}
        :: (y_2<y_1) && (x_2<y_2) && (x_1<x_2);
}


predicate P(a: int)
{
   true
}


方法Main(){
断言存在x_1:int{:触发器P(x_1)}::存在y_1:int{:触发器P(y_1)}
::exists x_2:int{:trigger P(x_2)}::exists y_2:int{:trigger P(y_2)}

:(y_2Dafny无法做到这一点。Dafny支持量词、布尔、算术和许多其他东西(递归函数、集合、序列、对象和引用、多维数组、归纳、归纳和共归纳数据类型、位向量、单调函数的最大和最小不动点等),它不适用于SAT-QBF(或QBF+Artimetic)基准

Dafny的错误,包括
断言违规
,告诉您验证器无法进行验证。可能是该属性仍然有效,但您需要自己提供更多证据。换句话说,您应该将
断言违规
解释为“不知道”回答。换言之,您不能用Dafny决定(仅半决定)公式

Dafny通过匹配模式在SMT解算器中使用量词,即触发器。当量词没有好的触发器时,Dafny的“无触发器”警告告诉您,您可能会看到性能差、验证不稳定以及所谓的蝴蝶效应(程序中一个看似不相关的小部分导致其他证明的自动构造发生变化)触发器由未解释的函数符号驱动,而您的示例中根本没有


如果你想要一个可读的语法,你可以通过Boogie做你正在尝试的事情。我还没有尝试过,但是你可以尝试将Boogie设置为单态模式,然后提供prover选项来请求SAT-QBF或类似的东西(请参阅Boogie的
/help
)。否则,如果您对确定这些问题感兴趣,那么直接转到SMT solver是一个不错的选择。

您好,谢谢您的回答!!在我的编辑中,我使用了一个未解释的函数解决了触发警告,但仍然不起作用。似乎我误解了断言冲突的含义(我认为在某些情况下这是一个强有力的句子:断言
  assert exists x_1: int :: exists y_1: int :: exists x_2: int :: exists y_2 : int
    :: (y_2<y_1) && (x_2<y_2) && (x_1<x_2);

method Main() {
 assert exists x_1 : int {:trigger P(x_1)} :: exists y_1: int {:trigger P(y_1)} 
    :: exists x_2: int {:trigger P(x_2)} :: exists y_2 : int {:trigger P(y_2)}
        :: (y_2<y_1) && (x_2<y_2) && (x_1<x_2);
}


predicate P(a: int)
{
   true
}