Мы пытаемся написать алгоритм двоичного поиска, используя Дафни, и кажется, что Дафни не доказывает правильность программы.
Может кто-нибудь помочь?Вот ошибки, которые мы получаем:
При INV: этот инвариант цикла может не поддерживаться циклом. Дафни VSCode
В Guard1: уменьшение выражения может не уменьшаться Дафни VSCode
predicate Sorted(q: seq<int>)
{
forall i,j :: 0 <= i <= j < |q| ==> q[i] <= q[j]
}
method BinarySearch(q: seq<int>, key: int) returns (j: nat)
requires Sorted(q) && key in q
ensures j < |q| && q[j] == key
{
var i: nat, k: nat;
i,j,k := Init(q,key);
while Guard1(q,key,j)
invariant Inv(q,key,i,j,k)
decreases V(i,k)
{
if Guard2(q,key,j)
{
i := UpdateI(q,key,i,j,k);
}
else
{
k := UpdateK(q,key,i,j,k);
}
j := (i+k)/2;
}
}
predicate Inv(q: seq<int>, key: int, i: nat, j: nat, k: nat)
{
i <= j <= k < |q| &&
key in q[i..k+1]
}
predicate method Guard1(q: seq<int>, key: int, j: nat)
requires Sorted(q) && key in q
{
0 <= j < |q| && q[j] != key
}
method Init(q: seq<int>, key: int) returns (i: nat, j: nat, k: nat)
requires Sorted(q) && key in q
ensures 0 <= i <= j <= k < |q| && key in q[i..k+1]
{
i, k := 0, |q|-1;
j := (k+i) / 2;
}
function V(i: nat, k: nat): int
{
if (k > i) then k-i
else 0
}
predicate method Guard2(q: seq<int>, key: int, j: nat)
{
0 <= j < |q| && q[j] < key
}
method UpdateI(q: seq<int>, key: int, i0: nat, j: nat, k: nat) returns (i: nat)
requires Guard2(q,key,j) && Inv(q,key,i0,j,k)
ensures i0 <= i
{
if(j < |q|-1 ){
i:= j + 1;
}
else {
i:= j;
}
}
method UpdateK(q: seq<int>, key: int, i: nat, j: nat, k0: nat) returns (k: nat)
requires (!Guard2(q,key,j)) && Inv(q,key,i,j,k0)
ensures k <= k0
{
if(j > 0){
k:= j - 1;
}
else {
k:= j;
}
}