в приведенной ниже программе я создаю что-то вроде проблемы голландского национального флага и следую той же логике, которая также указана здесь программа сортирует массив 0, 1 и 2 в порядке, равном 1 в начале0 в середине и 2 в конце.[1,1,1,0,0,2,2,2]
.но в инвариантах цикла я получаю ошибку This loop invariant might not be maintained by the loop.
изначально, i
и j
имеют индекс 0, а k
последний индекс.логика в том, что j движется вверх, если он видит 2, своп с k и k уменьшается, если видит 0, просто j
движется вверх, а если видит 1 своп с i
и оба i
и j
увеличиваются.
код также здесь в rise4fun
method sort(input: array?<int>)
modifies input
requires input !=null;
requires input.Length>0;
requires forall x::0<=x<input.Length ==> input[x]==0||input[x]==1||input[x]==2;
ensures sorted(input);
{
var k: int := input.Length;
var i, j: int := 0 , 0;
while(j != k )
invariant 0<=i<=j<=k<=input.Length;
/* the following invariants might not be maintained by the loop.*/
invariant forall x:: 0<=x<i ==> input[x]==1;
invariant forall x:: i<=x<j ==> input[x]==0;
invariant forall x:: k<=x<input.Length ==> input[x]==2;
invariant forall x:: j<=x<k ==> input[x]==0||input[x]==1||input[x]==2;
decreases if j <= k then k - j else j - k
{
if(input[j] == 2){
swap(input, j, k-1);
k := k - 1;
} else if(input[j] == 0){
j := j + 1;
} else {
swap(input, i, j);
i:= i + 1;
j := j + 1;
}
}
}
и здесь есть swap
метод и sorted
предикат
predicate sorted(input:array?<int>)
requires input!=null;
requires input.Length>0;
reads input;
{
forall i,j::0<=i<j<input.Length ==> input[i]==1 || input[i]==input[j] || input[j]==2
}
method swap(input: array?<int>, n:int, m:int)
modifies input;
requires input!=null;
requires input.Length>0;
requires 0<=n<input.Length && 0<=m<input.Length
{
var tmp : int := input[n];
input[n] := input[m];
input[m] := tmp;
}