Я не уверен, что вы подразумеваете под «вариантом» и «связанной функцией», и у меня нет доступа к вашей версии SPARK.
В SPARK 2014, с GNAT CE 2018, это доказывает (после большой боли, может быть, мне стоит пройтись по некоторым учебникам SPARK) без каких-либо инвариантов цикла.
Я думаю, что я мог бы обойтись без Supported_Range
, если бы запустил цикл в обратном порядке.
Мне бы хотелось заменить True
в постусловии на (for all D of Data => D /= Key)
, но я оставлю это на этом.
Я понимаю, что это не отвечает на ваш вопрос, извините.
package Memo with SPARK_Mode is
subtype Supported_Range is Natural range 0 .. Natural'Last - 1;
type My_Array is array (Supported_Range range <>) of Integer;
procedure Find
(Key : Integer;
Data : My_Array;
Index : out Integer;
Found : out Boolean)
with
Pre => Data'Length >= 1,
Post => ((Found and then Index in Data'Range and then Data (Index) = Key)
or else True);
end Memo;
package body Memo with SPARK_Mode is
procedure Find
(Key : Integer;
Data : My_Array;
Index : out Integer;
Found : out Boolean)
is
subtype Possible_J is Integer range Data’Range;
J : Possible_J;
begin
J := Possible_J'First;
Index := -1; -- have to initialize with something
Found := False;
loop
if Data (J) = Key
then
Found := True;
Index := J;
exit;
else
exit when J = Data'Last;
J := J + 1;
end if;
end loop;
end Find;
end Memo;