I am trying to prove, that my algorithm for finding second largest value in array works as it should. This is my code:
function FindMax2 (V : Vector) return Integer is
Max : Natural := 0;
SecondMax : Natural := 0;
begin
for I in V'Range loop
pragma Assert
(Max >= 0 and
SecondMax >= 0 and
V(I) > 0);
if V(I) > Max then
SecondMax := Max;
Max := V(I);
elsif V(I) /= Max and V(I) > SecondMax then
SecondMax := V(I);
end if;
pragma Loop_Invariant
(Max > SecondMax and
V(I) > 0 and
(for all J in V'First .. I => V(J) <= Max));
end loop;
return SecondMax;
end FindMax2;
and this are my pre- and postconditions:
package Max2 with SPARK_Mode is
type Vector is array (Integer range <>) of Positive;
function FindMax2 (V : Vector) return Integer
with
Pre => V'First < Integer'Last and V'Length > 0,
Post => FindMax2'Result >= 0 and
(FindMax2'Result = 0 or (for some I in V'Range => FindMax2'Result = V(I))) and
(if FindMax2'Result /= 0 then (for some I in V'Range => V(I) > FindMax2'Result)) and
(if FindMax2'Result = 0 then (for all I in V'Range => (for all J in V'Range => V(I) = V(J)))
else
(for all I in V'Range => (if V(I) > FindMax2'Result then (for all J in V'Range => V(J) <= V(I)))));
end Max2;
I'm stuck now on this message from GNATprove:
max2.ads:8:17: medium: postcondition might fail (e.g. when FindMax2'Result = 1 and V = (others => 1) and V'First = 0 and V'Last = 0)
If I am not mistaken it is reffering to the first condition about the result being greater or equal to 0, then why does it put 1 as a counter-example? Is there any way I can prove this?