如何使用Assert和loop_invariants

时间:2019-03-09 00:33:18

标签: ada formal-verification spark-ada spark-2014

规格:

package PolyPack with SPARK_Mode is 
type Vector is array (Natural range <>) of Integer;
function RuleHorner (X: Integer; A : Vector) return Integer
with
Pre => A'Length > 0 and A'Last < Integer'Last;
end PolyPack ; 

我想用Assert和loop_invariants编写PolyPack软件包的主体,以便gnatprove程序可以证明我的函数RuleHorner正确性。

我编写了函数Horner,但我不知道如何在程序中放置断言和loop_invariants来证明其核心:

with Ada.Integer_Text_IO;
package body PolyPack with SPARK_Mode is

   function RuleHorner (X: Integer; A : Vector) return Integer is
      Y : Integer := 0;
      begin       
      for I in 0 .. A'Length - 1 loop
         Y := (Y*X) + A(A'Last - I);
      end loop;
      return Y;
      end RuleHorner ;
end PolyPack ;

gnatprove:

overflow check might fail (e.g. when X = 2 and Y = -2)
overflow check might fail

溢出检查适用于Y行:=(Y * X)+ A(A'Last-I);

有人可以帮我如何使用loop_invariants删除溢出检查

1 个答案:

答案 0 :(得分:3)

分析是正确的。 Vector类型的元素类型为Integer。当X = 2,Y = -2,并且A(A'Last-I)小于Integer'First + 4时,将发生下溢。您认为如何在程序中处理此问题?循环不变式在这里不起作用,因为您无法证明不会发生上溢或下溢。 有没有一种方法可以设计Vector中使用的类型和/或子类型以及变量X和Y,以防止Y上溢或下溢?

我也很好奇为什么要忽略Vector中的最后一个值。您是否要反向遍历阵列?如果是这样,只需使用以下for循环语法:

for I in reverse A'Range loop