sorting - dafny implementation of insertionsort -
i new in dafny , have problems verifying insertionsort-implementation. dafny tells me the multiset invariants not holding, else working fine. after hours of searching mistake need :) nice if tell me trick!
my code:
predicate sorted(a:array<int>, min:int, max:int) requires != null; requires 0<= min <= max <= a.length; reads a; { forall j, k :: min <= j < k < max ==> a[j] <= a[k] } /* * */ method insertionsort(a: array<int>) requires != null; requires a.length > 0; ensures sorted(a, 0, a.length); ensures multiset(a[..]) == multiset(old(a[..])); modifies a; { var := 1; while(i < a.length) invariant 1 <= <= a.length; invariant sorted(a, 0, i); invariant != null; invariant multiset(old(a[..])) == multiset(a[..]); decreases a.length-i; { var j := - 1; var key := a[i]; while(j >= 0 && key < a[j]) invariant -1 <= j <= - 1 <= a.length; invariant (j == i-1 && sorted(a, 0, i)) || (sorted(a, 0, i+1)); invariant forall k :: j < k < ==> a[k] >= key; invariant -1 < j == - 1 ==> multiset(old(a[..])) == multiset(a[..]); invariant |multiset(old(a[..]))| == |multiset(a[..])|; invariant -1 < j < - 1 && key < a[j] ==> multiset(old(a[..])) == multiset(a[..]) - multiset({a[j+1]}) + multiset({key}); invariant -1 == j ==> multiset(old(a[..])) == multiset(a[..]) + multiset({key}) - multiset({a[j+1]}); decreases j; { a[j + 1] := a[j]; j := j - 1; } a[j + 1] := key; := + 1; } }
it produces
1 loop invariant might not maintained loop. 29,38 2 loop invariant might not maintained loop. 42,73 3 loop invariant might not maintained loop. 43,52
here modified algorithm verify. shifts elements doing swap. think bit more work adapted algorithm. needs more complex multiset invariant (which require lemma adding , removing things multisets).
predicate sorted(a:array<int>, min:int, max:int) requires != null; requires 0<= min <= max <= a.length; reads a; { forall j, k :: min <= j < k < max ==> a[j] <= a[k] } predicate sortedseq(a:seq<int>) { forall j, k :: 0 <= j < k < |a| ==> a[j] <= a[k] } lemma sortedseqsubsequencesorted(a:seq<int>, min:int, max:int) requires 0<= min <= max <= |a| requires sortedseq(a) ensures sortedseq(a[min .. max]) { } method swap(a: array<int>, i:int, j:int) modifies a; requires != null && 0 <= < j < a.length requires + 1 == j ensures a[..i] == old(a[..i]) ensures a[j+1..] == old(a[j+1..]) ensures a[j] == old(a[i]) ensures a[i] == old(a[j]) ensures multiset(a[..]) == multiset(old(a[..])) { var tmp := a[i]; a[i] := a[j]; a[j] := tmp; } method insertionsort(a: array<int>) modifies a; requires != null; requires a.length > 0; ensures sorted(a, 0, a.length); ensures multiset(a[..]) == multiset(old(a[..])); { var := 0; while(i < a.length) invariant 0 <= <= a.length invariant sorted(a, 0, i) invariant multiset(old(a[..])) == multiset(a[..]); { var key := a[i]; var j := - 1; ghost var a' := a[..]; assert sortedseq(a'[0..i]); while(j >= 0 && key < a[j]) invariant -1 <= j <= - 1 invariant a[0 .. j+1] == a'[0 .. j+1] invariant sorted(a, 0, j+1); invariant a[j+1] == key == a'[i]; invariant a[j+2 .. i+1] == a'[j+1 .. i] invariant sorted(a, j+2, i+1); invariant multiset(old(a[..])) == multiset(a[..]) invariant forall k :: j+1 < k <= ==> key < a[k] { ghost var a'' := a[..]; swap(a, j, j+1); assert a[0..j] == a''[0..j]; assert a[0..j] == a'[0..j]; assert a[j] == a''[j+1] == a'[i] == key; assert a[j+2..] == a''[j+2..]; assert a[j+2..i+1] == a''[j+2..i+1] == a'[j+1..i]; j := j - 1; sortedseqsubsequencesorted(a'[0..i], j+1, i); assert sortedseq(a'[j+1..i]); assert a[j+2 .. i+1] == a'[j+1 .. i]; assert sortedseq(a[j+2..i+1]); } := + 1; } }
Comments
Post a Comment