Dafny函数,while循环上的逻辑表达式无效

时间:2018-05-21 01:01:20

标签: z3 verification insertion-sort dafny

我是Dafny的新手并且遇到了一些我无法理解的错误。

  • 在我的Dafny插件forSort(https://docs.confluent.io/current/streams/developer-guide/memory-mgmt.html)程序中,我不明白为什么我在变量invalid logical expression上得到i while循环。 while (i < |input|)
  • 在交换部分(input[j := b]; input[j-1 := a];)的相同代码中,我得到expected method call, found expression。根据教程input[j:=b]将seq输入的索引j替换为b
  • 的值

1 个答案:

答案 0 :(得分:4)

第一个错误是因为您被声明为function而不是method。在Dafny中,function的主体应该是一个表达式,而不是一系列语句。因此,当解析器看到关键字&#34;而#34;时,它意识到某些内容是错误的(因为&#34;而#34;不能成为语句的一部分)并给出错误消息。我不确定为什么错误消息会引用&#34;逻辑&#34;表达。

无论如何,您可以通过声明method而不是function来解决此问题。

您需要一种方法,因为您使用的是命令式算法,而不是功能算法。确实,您需要一个子程序来计算其输出作为其输入的函数而没有副作用。但是,在Dafny中,当你想要它的方式涉及分配和while循环等命令式构造时,你仍然使用method

第二个问题是input[j := b]是一个表达式,而解析器则使用了一个语句。您可以通过将input[j := b]; input[j-1 := a];重写为input := input[j:=b]; input := input[j-1];来解决此问题。

不幸的是,这将导致另一个问题,即在Dafny中,输入参数无法分配。所以你最好再制作另一个变量。请参阅下文,了解我是如何做到的。

method insertionSort(input:seq<int>)
// The next line declares a variable you can assign to.
// It also declares that the final value of this variable is the result
// of the method.
returns( output : seq<int> )
    // No reads clause is needed.
    requires |input|>0
    // In the following I changed "input" to "output" a few places
    ensures perm(output,old(input))
    ensures sortedBetween(output, 0, |output|) // 0 to input.Length = whole input

{
    output := input ;
    // From here on I changed your "input" to "output" most places
    var i := 1;
    while (i < |output|) 
        invariant perm(output,old(input))
        invariant 1 <= i <= |output|
        invariant sortedBetween(output, 0, i)       
        decreases |output|-i
    {
        ...
            output := output[j := b];
            output := output[j-1 := a];
            j := j-1;
        ...
    }
}

顺便说一句,由于输入参数无法更改,只要您拥有old(input),就可以使用input。他们的意思是一样的。