Dafny,将序列切片分配给数组

时间:2018-05-19 01:47:54

标签: z3 verification dafny

在我的Dafny程序中,我有一个长度均匀的数组input:array?<int>,我希望将它分成两个相等的部分,然后单独对它们进行排序,然后以刷卡顺序合并。 (插入排序已经实现并验证的int数组)。使用seq<int>在Dafny中进行切片和合并很简单,并在rise4fun中提供完整的文档。但我找不到一个简单的数组方法。与带数组的序列一样,最简单的方法是什么?

        method MySort(input:array?<int>)
        { var mid:= input.Length/2;
          var subOne := input[0..mid];
          var subTwo := input[mid..input.Length];
          insertionSort(subOne); // ofcourse ERROR as insertion sort is implemented for array<int>
          insertionSort(subTwo); // ofcourse ERROR as insertion sort is implemented for array<int>
          input := subTwo + subOne;
        } 

完整的代码是here in rise4fun,在这段代码中,我已经注释掉序列approch并使用while循环进行了一些切片。如果这是最好的方法,我应该如何进行连接。

另外Here我已经使用seq<int>制作了排序方法,但在交换部分(input[j := b]; input[j-1 := a];),我得到了expected method call, found expression。根据教程input[j:=b],应将seq输入的索引j替换为b

的值

1 个答案:

答案 0 :(得分:3)

您需要做的是将insertionSort方法的输出分配给这样的变量:

subOne := insertionSort(subOne); 
subTwo := insertionSort(subTwo);

现在您将在下一行遇到问题

input := subTwo + subOne;

,因为

subOne + subTwo

是一个序列,但input是一个指向数组的指针。您不想更改指针,您想要更改数组的内容。一种方法如下所示:

method probOneSort(input:array?<int>) 
modifies input;
requires input != null;
requires input.Length > 0;
requires input.Length%2==0;
{
 var mid:= input.Length/2;

 var subOne := input[0..mid];
 var subTwo := input[mid..input.Length];

 subOne := insertionSort(subOne);
 subTwo := insertionSort(subTwo);

 var val := subOne + subTwo ;
 forall i | 0 <= i && i < input.Length { input[i] := val[i] ; }
}

为了验证这一点,您需要insertionSort确保其输出的长度与其输入的长度相同。否则验证者无法验证下标val[i]是否在范围内。