我想证明此过程中的循环将使用变量(绑定函数)终止
变量将是I,下限为0(I:= 0)每次重复,我的大小……
我将使用有界循环结构(for循环)迭代数组。 for循环更容易处理数组边界和空数组。这适用于我在GNAT CE 2018(在这里使用SPARK 2014):
package Foo with SPARK_Mode => On is type MyArray is array (Integer range <>) of Integer; procedure Find (Key : in Integer; Data : in MyArray; Index : out Integer; Found : out Boolean) with Post => (if Found then Data (Index) = Key); end Foo;
和
package body Foo with SPARK_Mode => On is ---------- -- Find -- ---------- procedure Find (Key : in Integer; Data : in MyArray; Index : out Integer; Found : out Boolean) is begin Found := False; Index := Data'First; for I in Data'Range loop if Data (I) = Key then Found := True; Index := I; end if; pragma Loop_Invariant (Index in Data'Range); pragma Loop_Invariant (if Found then Data (Index) = Key else Data (Index) /= Key); exit when Found; end loop; end Find; end Foo;
如果我用典型的Ada成语写这个,我得到
package SPARK_Proof is type Integer_List is array (Positive range <>) of Integer; type Find_Result (Found : Boolean := False) is record case Found is when False => null; when True => Index : Positive; end case; end record; function Match_Index (Value : Integer; List : Integer_List) return Find_Result; end SPARK_Proof; package body SPARK_Proof is function Match_Index (Value : Integer; List : Integer_List) return Find_Result is -- Empty begin -- Match_Index Search : for I in List'Range loop if Value = List (I) then return (Found => True, Index => I); end if; end loop Search; return (Found => False); end Match_Index; end SPARK_Proof;
这更短更清晰。我不知道用SPARK证明是否更容易。