ada - 如何使用 Assert 和 loop_invariants
问题描述
规格:
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 删除溢出检查
解决方案
分析是正确的。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
推荐阅读
- python - 如何使文件隐藏在python中
- c++ - 由于 NULL 指针,COutputList“隐藏”中的 MFC MDI OutputWnd.cpp 上下文弹出窗口不起作用
- r-exams - 为什么 while (is.null(...)) 经常与 num_to_schoice 结合使用?
- c++ - C++ 检查路径是否在给定目录之外
- linux - 通过 x86-64 汇编程序管道时的竞争条件
- javascript - 用另一个替换字符串中的某些值
- mysql - 使用 Cast() 和 Try_Cast() 将列转换为 INT 时遇到问题
- sprite-kit - 自定义 SKNode 的 SpriteKit 更新功能
- javascript - 如何防止对 Postman 中的模拟服务器的循环请求?
- java - 如何转发来自第三方的 HTTPPost 数据?