我试图证明我在 Ada 中的 Select Sort 实现是正确的。我尝试了一些循环不变量,但使用 gnatprove 只能证明内循环的不变量:
package body Selection with SPARK_Mode is
procedure Sort (A : in out Arr) is
I: Integer := A'First;
J: Integer;
Min_Idx: Integer;
Tmp: Integer;
begin
while I < A'Last loop
pragma Loop_Invariant
(Sorted( A (A'First .. I) ));
Min_Idx := I;
J := I + 1;
while J <= A'Last loop
if A (J) < A (Min_Idx) then
Min_Idx := J;
end if;
pragma Loop_Invariant
(for all Index in I .. J => (A (Min_Idx) <= A (Index)));
J := J + 1;
end loop;
Tmp := A (Min_Idx);
A (Min_Idx) := A (I);
A (I) := Tmp;
I := I + 1;
end loop;
end Sort;
end Selection;
package Selection with SPARK_Mode is
type Arr is array (Integer range <>) of Integer;
function Sorted (A : Arr) return Boolean
is (for all I in A'First .. A'Last - 1 => A(I) <= A(I + 1))
with
Ghost,
Pre => A'Last > Integer'First;
procedure Sort (A : in out Arr)
with
Pre => A'First in Integer'First + 1 .. Integer'Last - 1 and
A'Last in Integer'First + 1 .. Integer'Last - 1,
Post => Sorted (A);
end Selection;
Gnatprove 告诉我
selection.adb:15:14: medium: loop invariant might not be preserved by an arbitrary iteration, cannot prove Sorted( A (A'First..I)) (e.g. when A = (-1 => 0, 0 => 0, others => 1) and A'First = -1)
你有什么想法可以解决这个问题吗?