使用 Dafny 反转堆栈
Reverse a stack using Dafny
我正在学习 Dafny,但还没有找到解决这个问题的方法。
我有这种方法可以反转堆栈,从堆栈中弹出并推入另一个堆栈。但它不起作用,因为 dafny 指出“后置条件可能不适用于此 return 路径。”在方法 Reverse 上。
var arr: array<nat>;
var tail: nat;
const initialSize := 5;
ghost var Content: seq<nat>;
predicate Reversed(seq1:seq<nat>, seq2: seq<nat>)
requires |seq1| > 0
requires |seq1| == |seq2|
{
forall j :: 0 <= j < |seq1| ==> seq1[j] == seq2[|seq1|-1-j]
}
此 return 路径可能不支持后置条件。验证者
Stack.dfy(88, 12):这是可能不成立的后置条件。
Stack.dfy(10, 15): 相关位置 < 反向谓词
method Reverse()
requires |Content| > 0
ensures old(|Content|) == |Content|
ensures Reversed(old(Content), Content)
{
var newArray := new nat[arr.Length];
var newTail := 0;
ghost var newContent: seq<nat>;
var element;
while(tail>0)
// invariant Content[|Content|-1] == newContent[|newContent|-1]
{
// Pop from old stack
tail := tail - 1;
element := arr[tail];
Content := arr[0..tail];
// Push into new stack
newArray[newTail] := element;
newTail := newTail + 1;
newContent := newContent + [element];
}
arr := newArray;
tail:= newTail;
Content := newContent;
}
我已经尝试找出一些循环不变量但没有成功。
编辑:
我正在使用自动合约
我使用 forall 而不是 while 解决了这个问题,因为它不需要不变量:
method Reverse()
requires |Content| > 0
ensures old(|Content|) == |Content|
ensures Reversed(old(Content), Content)
{
var newArray := new nat[arr.Length];
forall i | 0 <= i < tail
{
newArray[i] := arr[tail - i - 1];
}
arr := newArray;
Content := arr[..tail];
}
我正在学习 Dafny,但还没有找到解决这个问题的方法。 我有这种方法可以反转堆栈,从堆栈中弹出并推入另一个堆栈。但它不起作用,因为 dafny 指出“后置条件可能不适用于此 return 路径。”在方法 Reverse 上。
var arr: array<nat>;
var tail: nat;
const initialSize := 5;
ghost var Content: seq<nat>;
predicate Reversed(seq1:seq<nat>, seq2: seq<nat>)
requires |seq1| > 0
requires |seq1| == |seq2|
{
forall j :: 0 <= j < |seq1| ==> seq1[j] == seq2[|seq1|-1-j]
}
此 return 路径可能不支持后置条件。验证者
Stack.dfy(88, 12):这是可能不成立的后置条件。
Stack.dfy(10, 15): 相关位置 < 反向谓词
method Reverse()
requires |Content| > 0
ensures old(|Content|) == |Content|
ensures Reversed(old(Content), Content)
{
var newArray := new nat[arr.Length];
var newTail := 0;
ghost var newContent: seq<nat>;
var element;
while(tail>0)
// invariant Content[|Content|-1] == newContent[|newContent|-1]
{
// Pop from old stack
tail := tail - 1;
element := arr[tail];
Content := arr[0..tail];
// Push into new stack
newArray[newTail] := element;
newTail := newTail + 1;
newContent := newContent + [element];
}
arr := newArray;
tail:= newTail;
Content := newContent;
}
我已经尝试找出一些循环不变量但没有成功。
编辑: 我正在使用自动合约
我使用 forall 而不是 while 解决了这个问题,因为它不需要不变量:
method Reverse()
requires |Content| > 0
ensures old(|Content|) == |Content|
ensures Reversed(old(Content), Content)
{
var newArray := new nat[arr.Length];
forall i | 0 <= i < tail
{
newArray[i] := arr[tail - i - 1];
}
arr := newArray;
Content := arr[..tail];
}