为什么在ada的contador是oveflow?

时间:2019-06-22 19:34:26

标签: ada

我不知道为什么证明变量变量contador溢出时是错误的。我需要帮助。

 contador: Integer;
   J: Integer;

   function noPrimos (lista : My_Array) return Boolean

   with
      Global  => contador,
      --Depends => ...,
      Pre     => True and contador < Integer'Last,
      Post    => (noPrimos'Result = True or noPrimos'Result = False);  



FILE ADB

function noPrimos (lista : My_Array)  return Boolean is
      contador: Integer;
   begin
      for I in lista'Range loop
         contador:= 0;
         if lista(I) /= 1 then
            for J in 1.. lista(I) loop
               if lista(I) rem J = 0 then
                  contador := contador + 1;
               end if;
            end loop;
            if contador <= 2 then
               return false;
            end if;
         else
            return true;
         end if;
         pragma Loop_Variant(Increases => I);
      end loop;
      return true;
   end noPrimos;  

问题是溢出的结果: 第2阶段的第1阶段:生成全球合同... 第2阶段的第2阶段:流程分析和证明... 15:40:中:溢出检查可能会失败(例如,当contador = 2147483647时) 47:40:中等:溢出检查可能会失败(例如,当contador = 0时)

1 个答案:

答案 0 :(得分:3)

首先,我假设仅当列表noPrimos不包含任何质数时,函数True才会返回lista。话虽这么说,但我对代码片段的某些方面感到有些困惑:

  • 缺少My_Array的类型定义。

  • 从给定的代码片段中不清楚contador的全局实例(英语:counter)的作用。通过编写Global=> contador,您声明全局变量contador将由函数noPrimos(另请参见here)读取,但这不会发生,因为本地实例contador中的{}遮盖了contador的全局实例。

  • 尚不清楚全局定义变量J的原因,您可以忽略它。

  • 前提条件True(在布尔运算符and的左侧)很简单,可以省略。

  • 后置条件指出noPrimos的结果可以是TrueFalse。这很简单,因为noPrimos返回一个布尔值,因此可以省略。后置条件应在给出其输入的情况下说明函数的预期结果。

  • 循环变量pragma Loop_Variant(Increases => I);很小,因为变量I将因for循环的定义而增加。因此可以省略循环变量。

下面是函数No_Primes的示例,该函数在给定列表L中搜索素数,如果找不到则返回True。在GNAT CE 2019中得到了证明:

primes.ads (规范)

package Primes with SPARK_Mode is

   type List is
     array (Natural range <>) of Positive;

   --
   --  Returns True if N is a prime number (or False otherwise).
   --
   function Is_Prime (N : Positive) return Boolean
     with
       Global => null,
       Post => Is_Prime'Result =
         (if N = 1 then False
            else (for all I in 2 .. N - 1 => N rem I /= 0));  

   --
   -- Returns True if list L does not contain any prime numbers (or False otherwise).
   --
   function No_Primes (L : List) return Boolean
     with
       Global => null,
       Post => No_Primes'Result =
         (for all I in L'Range => Is_Prime (L (I)) = False);

end Primes;

primes.adb (正文)

package body Primes with SPARK_Mode is

   --------------
   -- Is_Prime --
   --------------

   function Is_Prime (N : Positive) return Boolean is
   begin
      if N = 1 then
         return False;
      else
         for I in 2 .. N - 1 loop

            if N rem I = 0 then               
               return False;
            end if;

            pragma Loop_Invariant
              (for all J in 2 .. I => N rem J /= 0);

         end loop;
      end if;
      return True;
   end Is_Prime;

   ---------------
   -- No_Primes --
   ---------------

   function No_Primes (L : List) return Boolean is
   begin

      for I in L'Range loop

         if Is_Prime (L (I)) then
            return False;
         end if;

         pragma Loop_Invariant
           (for all J in L'First .. I => Is_Prime (L (J)) = False);

      end loop;
      return True;

   end No_Primes;

end Primes;

一个小型测试程序( main.adb

with Ada.Text_IO; use Ada.Text_IO;
with Primes;      use Primes;

procedure Main is

   --  Some test vectors.
   L1 : List := (1 => 1);         --  Expect TRUE  : 1 is not a prime.
   L2 : List := (1, 2, 3, 5, 7);  --  Expect FALSE : All are prime except 1.
   L3 : List := (2, 3, 5, 7);     --  Expect FALSE : All are prime.
   L4 : List := (1, 4, 6, 8, 9);  --  Expect TRUE  : None are prime.
   L5 : List := (4, 6, 8, 9);     --  Expect TRUE  : None are prime.
   L6 : List := (3, 4, 5);        --  Expect FALSE : 3 and 5 are prime.

begin
   Put_Line ("No_Primes (L1) = " & Boolean'Image (No_Primes (L1)));
   Put_Line ("No_Primes (L2) = " & Boolean'Image (No_Primes (L2)));
   Put_Line ("No_Primes (L3) = " & Boolean'Image (No_Primes (L3)));
   Put_Line ("No_Primes (L4) = " & Boolean'Image (No_Primes (L4)));
   Put_Line ("No_Primes (L5) = " & Boolean'Image (No_Primes (L5)));
   Put_Line ("No_Primes (L6) = " & Boolean'Image (No_Primes (L6)));
end Main;

收益

No_Primes (L1) = TRUE
No_Primes (L2) = FALSE
No_Primes (L3) = FALSE
No_Primes (L4) = TRUE
No_Primes (L5) = TRUE
No_Primes (L6) = FALSE