使用 SPARK 证明选择排序算法

2024-03-16

我试图证明我在 Ada 中的选择排序实现是正确的。我尝试了一些循环不变量,但使用 gnatprove 只能证明内部循环的不变量:

package body Selection with SPARK_Mode is

procedure Sort (A : in out Arr) is
    I: Integer := A'First;
    J: Integer;
    Min_Idx: Integer;
    Tmp: Integer;
begin
    while I < A'Last loop

        pragma Loop_Invariant
            (Sorted( A (A'First .. I) ));

        Min_Idx := I;
        J := I + 1;

        while J <= A'Last loop

            if A (J) < A (Min_Idx) then
                Min_Idx := J;
            end if;

            pragma Loop_Invariant
                (for all Index in I .. J => (A (Min_Idx) <= A (Index)));

            J := J + 1;
        end loop;

        Tmp := A (Min_Idx);
        A (Min_Idx) := A (I);
        A (I) := Tmp;

        I := I + 1;

    end loop;
end Sort;
end Selection;
package Selection with SPARK_Mode is
    type Arr is array (Integer range <>) of Integer;

    function Sorted (A : Arr) return Boolean
    is (for all I in A'First .. A'Last - 1 => A(I) <= A(I + 1))
    with
        Ghost,
        Pre => A'Last > Integer'First;

    procedure Sort (A : in out Arr)
    with
        Pre => A'First in Integer'First + 1 .. Integer'Last - 1 and
            A'Last in Integer'First + 1 .. Integer'Last - 1,
        Post => Sorted (A);

end Selection;

蚊子证明告诉我selection.adb:15:14: medium: loop invariant might not be preserved by an arbitrary iteration, cannot prove Sorted( A (A'First..I)) (e.g. when A = (-1 => 0, 0 => 0, others => 1) and A'First = -1) 您对如何解决这个问题有什么想法吗?


我稍微修改了例程,在外部循环中添加了两个循环不变量,并将它们全部移至循环末尾。两个附加循环不变量表明正在处理的元素始终大于或等于已处理的元素并且小于或等于尚未处理的元素。

我也改变了SortedGhost 函数/谓词仅将量化表达式应用于长度大于 1 的数组。这是为了防止溢出问题。对于长度为 0 或 1 的数组,该函数返回True根据定义为(if False then <bool_expr>) is True (or 空洞真实 https://en.wikipedia.org/wiki/Vacuous_truth,如果我没记错的话)。

所有 VC 都可以通过以下方式释放/证明gnatprove随 GNAT/SPARK CE 2020 级别 1 一起提供:

$ gnatprove -Pdefault.gpr -j0 --report=all --level=1

选择.ads

package Selection with SPARK_Mode is
   
   type Arr is array (Integer range <>) of Integer;

   function Sorted (A : Arr) return Boolean is
     (if A'Length > 1 then
         (for all I in A'First + 1 .. A'Last => A (I - 1) <= A (I)))
       with Ghost;
         
   procedure Sort (A : in out Arr)
     with Post => Sorted (A);

end Selection;

选择.adb

package body Selection with SPARK_Mode is
   
   ----------
   -- Sort --
   ----------
   
   procedure Sort (A : in out Arr) is
      M : Integer;      
   begin
      if A'Length > 1 then
         for I in A'First .. A'Last - 1 loop
         
            M := I;
         
            for J in I + 1 .. A'Last loop            
               if A (J) <= A (M) then
                  M := J;
               end if;
            
               pragma Loop_Invariant (M in I .. J);            
               pragma Loop_Invariant (for all K in I .. J => A (M) <= A (K));
            
            end loop;
            
            declare
               T : constant Integer := A (I);
            begin
               A (I) := A (M);
               A (M) := T;
            end;
                  
            --  Linear incremental sorting in ascending order.
            pragma Loop_Invariant (for all K in A'First .. I => A (K) <= A (I));
            pragma Loop_Invariant (for all K in I .. A'Last  => A (I) <= A (K));
         
            pragma Loop_Invariant (Sorted (A (A'First .. I)));         

         end loop;
      end if;
   end Sort;
   
end Selection;
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 SPARK 证明选择排序算法 的相关文章

  • 有谁知道协议缓冲区的 Ada 插件吗?

    我正在寻找用于协议缓冲区的 Ada 插件 看起来除了 Ada 之外 几乎所有语言插件都可用或正在开发中 嗯 我唯一发现的是这篇论文 不幸的是 我没有找到任何翻译工具的源代码 即你所说的plugin 我唯一能告诉的是该工具是用 C 开发的 U
  • 在 Ada 中创建子类型而不指定范围有什么意义?

    在Ada中 我经常看到这样的东西 type Number is new Integer 这有什么意义呢 难道你就不能快乐吗 Integer 我还看到过这样的代码 type Small Number is range 1 5 这对我来说是有道
  • Ada 95:修改字典程序的输出

    我找到了这本词典作者 William Whitaker 在互联网上 我喜欢它的解析能力 但输出不适合我 问题 对我来说是挑战 给定输入形式 例如 audiam 程序将返回以下输出 纯文本 audi am V 4 1 PRES ACTIVE
  • Ada:在块语句中写入文件

    我正在处理一个数组 其长度在程序执行期间确定 所以我正在利用block我可以在其中设置数组限制的语句 我在将数组的元素写入文件时遇到问题因为我在写入过程中使用了存根 我删除了存根 使所有内容都在同一代码中 虽然现在我的代码编译并运行 它没有
  • Ada 与 Netbeans

    我下载了 Netbeans 插件 用于使用 Ada 进行编程 但是 我不知道如何将Eclipse链接到Ada平台库 什么应该链接到 IDE lib 等 bin 我不知道该怎么办 安装后Ada 插件模块 http wiki netbeans
  • Ada:从文件中读取

    我正在尝试读取一个包含单列的文件Long Float值在Ada如下 with Ada Text IO use Ada Text IO with Ada Long Float Text IO with Ada Sequential IO pr
  • 为什么字符串需要用初始值初始化?

    我有一根绳子lx String我想稍后在代码中设置该值 但出现错误unconstrained subtype not allowed need initialization provide initial value or explicit
  • 什么是“libgnarl”?

    What is libgnarl 我在不同的地方找到了对此的引用 例如在 gcc 源代码中或 gprbuild 的详细输出中 gprbuild 特别报告了有关决定是否libgnarl甚至是必要的 所以它显然是一个可选库 但实际的库是什么 我
  • 如何阻止控制台窗口立即关闭 | GNAT-GPS

    我有 Ada 程序 可以使用 GNAT GPS 完美运行和编译 当我运行其 exe 文件并提供用户输入时 该 exe 会立即关闭 而不是说 按任意键继续 我在网上搜索了很多 但我只找到了与使用 system pause 的 c c visu
  • 在 Idris 中证明如果 n = m 且 m = o,则 n + m = m + o?

    我正在尝试通过查看一些练习来提高我的伊德里斯技能软件基础 https softwarefoundations cis upenn edu lf current toc html 最初是为 Coq 设计的 但我希望对 Idris 的翻译不会太
  • ADA 文件名与包名称

    我继承了一个 ADA 程序 其中源文件名和包文件名不遵循默认命名约定 ADA 对我来说是新的 所以我可能会错过一些简单的东西 但我在 GNAT Pro 用户指南中看不到它 这个类似的问题 https stackoverflow com qu
  • 将分隔的字段合并为一个

    我在 Ada 工作 我有一个非常丑陋的类型 我无法修改 我想做一些易于使用的事情 类型是这样的 for T Ugly Type Alignment use 4 for T Ugly Type Size use 48 for T Ugly T
  • 将数字排列成最大数 - 算法证明

    有众所周知的算法问题 http www programcreek com 2014 02 leetcode largest number java 给定数字数组 例如 1 20 3 14 在这种情况下 以尽可能形成最大数字的方式排列数字32
  • Ada:操作员不直接可见

    我正在使用 GNAT GPS studio IDE 来对 Ada 进行一些训练 我遇到了包可见性问题 首先 我在名为 DScale ads 的文件中指定一个包 其中包含以下类型 package DScale is type DMajor i
  • 我该如何为这个不变量编写一个循环?

    这些是查找数组 b h k 最小值的算法的断言 Precondition h lt k lt b length Postcondition b x is the minimum of b h k 这是这个不变量的正确循环吗 不变式 b x
  • 稳定的比较排序,时间复杂度为 O(n * log(n)),空间复杂度为 O(1)

    在经历的同时维基百科的排序算法列表 https secure wikimedia org wikipedia en wiki Sorting algorithm Comparison of algorithms我注意到没有稳定的比较排序 h
  • 使用 GtkAda 发出信号

    我担心的是我创建了一个回调函数 它应该显示Gtk Entry当我们点击Gtk Button但当我点击按钮时什么也没有发生 我不明白 File ads Package Test is Type T Test is record Contene
  • 协变类型 T 发生在不变位置

    我正在 Scala 中迈出第一步 我想让以下代码起作用 trait Gene T val gene Array T 编译器给出的错误是 covariant type T occurs in invariant position in typ
  • 在 Ada 中立即开始循环的下一次迭代

    我想要一个无限循环 其中循环几乎贯穿整个程序 并且在任何时候 基于条件语句 我希望它退出循环的特定迭代并返回到顶部并执行 有办法做到这一点吗 它不必是无限循环 它可以是一个for循环 我只想让它进入该循环的下一次迭代 您可以使用 goto
  • 在 Ada 中定义通用标量类型包

    我想通过制作一个用于操作多项式的 Ada 包来测试编写 Ada 包的水 可以为多种代数结构定义多项式 因此为了反映这一点 我想使该包通用 以便它可以与浮点数 整数或其他数字子类型一起使用 我现在想说 我对 Ada 的类型系统如何工作或者它的

随机推荐

  • 类型错误:流未定义

    无法向我的小型 React 应用程序添加数据库连接 我尝试了一堆 npm 模块 sqlite sqlite3 realm 全部因类型错误而回退 TypeError stream is undefined 我什么也没做 只是在我的组件中添加了
  • 我如何找到启动我的进程的计划任务的实例ID/相关ID

    如果我有一个运行我的 EXE 的 Windows 计划任务 有没有办法从我的 EXE 内部找到触发我的计划任务实例 简单的回答是 不 你能做的最好的事情是以编程方式访问任务调度程序库 看看你所在的进程是否处于 运行 模式 获取进程的 PID
  • 检测两张图片之间的相似点然后将它们叠加(Python)

    我有两张相同神经切口的照片 深度略有不同 每张切片使用不同的染料进行染色 我想叠加这两个图像 但它们在幻灯片 照片上没有完美对齐 因此无法简单地做到这一点 我想要做的是编写代码来检测两个切片之间的相似形状 即相同的单元格 然后根据这些单元格
  • Django自定义装饰器重定向问题

    我尝试在 Django 中编写一个自定义装饰器 如果用户未通过该页面登录 我想将用户重定向到自定义登录页面 我已经编写了装饰器并调试了它 虽然如果用户未登录 它可以正常工作 但在用户登录后 它会给出错误 The view APPNAME v
  • Playwright locator.evaluateAll 如何返回使用节点 forEach 填充的地图

    我想抢夺所有人的财产
  • 如何从文本文件中读取信息?

    我有数百个文本文件 每个文件中包含以下信息 Auto Corelation Results 1 09 19 18 non Significant STATISTICS FOR MANN KENDELL TEST S 609 VAR S 16
  • 您将如何做到这一点:表格还是 CSS? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 如何使用 Jersey(测试框架)将数据源依赖项注入到 RESTful Web 服务中?

    我正在使用 Jersey 构建一个 RESTful Web 服务 该服务依赖 MongoDB 来实现持久性 Web 服务本身连接到默认数据库 但对于单元测试 我想使用单独的测试数据库 我将在 setUp 中填充此测试数据库 运行测试 然后在
  • 每张信用卡的 paypal payer_id 是唯一的吗? [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 我想知道使用同一张信用卡的两次单独付款的 paypal payer id 是否相同 这显然对于检测可能的欺诈交易很有用 请注意 对于 paypal 帐
  • Vim 脚本突出显示大括号等标签的末尾

    我需要一个 Vim 脚本来在光标位于标签开头时突出显示标签的结尾 例如 在 html 标签中 当光标位于标签开头时 它应该突出显示标签结尾 接口应该是通用的 以便可以添加更多标签 如果您将 html vim 文件替换为this http w
  • 空值可以传递给包裹吗?

    是否可以写null to Parcel当分割一个对象时 得到null再次解压时又回来了 假设我们有以下代码 public class Test implements Parcelable private String string null
  • 在调用 Main() 之前 Windows 会做什么?

    Windows 必须做一些事情来解析 PE 标头 将可执行文件加载到内存中 并将命令行参数传递给main Using OllyDbg I have set the debugger to break on main so I could v
  • Twitter API请求限制问题

    我编写了一个小型 java 程序来从 Twitter 下载所有朋友和关注者的个人资料图片 但我收到错误 因为每个 IP 地址每小时只允许 150 个请求 确切的错误是 twitter4j TwitterException 400 The r
  • SELECT 语句中的子查询 (MySQL)

    我正在创建一个 SQL 语句 它将返回一个产品列表以及我在每个商店中可以找到的每种产品的数量 我的表的结构 带有一些示例数据 如下 productID size color stock storeID 1 S RED01 1 BCN 1 S
  • 如何根据单元格值有条件地设置 ReactJs 材料表单元格的样式?

    我在材料表中有一个列 其中包含成功 失败等值 根据这些值 我需要在单元格上应用颜色 如何使用材质表来实现 这个答案是专门针对反应材料表 https material table com 在列部分中 我们需要具有如下所述的内容 因此当在表中呈
  • 调用中参数“coder”缺少参数

    我将自定义 UIButton 编码为 class AccountOpeningButton UIButton required init coder aDecoder NSCoder super init coder aDecoder 我能
  • 无法在当前范围或上下文中解决。确保所有引用的变量都在范围内

    我收到此错误 无法在当前范围或上下文中解析 TblProduct 请确保所有引用的变量都在范围内 加载所需的架构 并且正确引用命名空间 在下面的代码中 我不确定为什么它不能正常工作 我希望有人能够提供帮助 谢谢 private void A
  • 短数组的最佳排序函数

    我正在研究一种处理图片的算法 基本上我将实现一个扩散 每个像素将获得周围 8 个像素的中值 它自己的值 我要做的就是使用该值创建一个包含 9 个整数的数组 对数组进行排序并获取 array 4 处的中值 我仍然不知道该使用什么来解决这个问题
  • 根据需要验证正文中的不可空属性 - AspNetCore 3.1

    我正在尝试验证是否在请求中完全忽略了属性 字段 即 ModelState 无效并且 BadRequest 被发送回客户端 但是我正在努力处理请求主体中的不可空类型 适用于可空类型 Required public string Nullabl
  • 使用 SPARK 证明选择排序算法

    我试图证明我在 Ada 中的选择排序实现是正确的 我尝试了一些循环不变量 但使用 gnatprove 只能证明内部循环的不变量 package body Selection with SPARK Mode is procedure Sort