如何证明这个不变量呢?

2024-04-27

我的目的是证明霍纳规则是正确的。为此,我将霍纳当前计算的值与“实”多项式的值进行比较。
所以我写了这段代码:

package body Poly with SPARK_Mode is
   function Horner (X : Integer; A : Vector) return Integer is
      Y : Integer := 0;
      Z : Integer := 0 with Ghost;
   begin
      for I in reverse A'First .. A'Last loop
         pragma Loop_Invariant (Y * (X ** (I - A'First + 1)) = Z);
         Y := A(I) + Y * X;
         Z := Z + A(I) * (X ** (I - A'First));
      end loop;
      pragma Assert (Y = Z);
      return Y;
   end Horner;
end Poly;

这应该证明不变性。不幸的是,gnatprove 告诉我:

cannot prove  Y * (X ** (I - A'First + 1)) = Z
e.g. when A = (1 => 0, others => 0) and A'First = 0 and A'Last = 1 and I = 0 and X = 1 and Y = -1 and Z = 0

在这种情况下 Y=-1 是如何工作的?您有任何想法如何解决这个问题吗?


这里的反例是虚假的,它并不对应于真正的无效执行。该算法对于证明者来说过于复杂,这导致循环不变性保持未被证明,并且导致虚假的反例。

要调查此类未经证明的检查,您必须进入证明属性的“自动活动”模式,这需要将属性分解为较小的属性,直到自动证明者可以处理较小的步骤,或者您可以隔离未经证明的基本属性您可以在引理中隔离它,您可以单独验证它。

这里我在迭代开始时为 Y 的值引入了一个幽灵变量 YY,并将循环不变量分解为越来越小的断言,这表明问题出在求幂 (X ** (I - A'First + 1) = X * (X ** (I - A'First)) 我也在断言中隔离:

package body Poly with SPARK_Mode is
   function Horner (X : Integer; A : Vector) return Integer is
      Y : Integer := 0;
      Z : Integer := 0 with Ghost;
      YY : Integer with Ghost;
   begin
      for I in reverse A'First .. A'Last loop
         pragma Loop_Invariant (Y * (X ** (I - A'First + 1)) = Z);
         YY := Y;
         Y := A(I) + Y * X;
         Z := Z + A(I) * (X ** (I - A'First));
         pragma Assert (Z = YY * (X ** (I - A'First + 1)) + A(I) * (X ** (I - A'First)));
         pragma Assert (X ** (I - A'First + 1) = X * (X ** (I - A'First)));
         pragma Assert (Z = YY * X * (X ** (I - A'First)) + A(I) * (X ** (I - A'First)));
         pragma Assert (Z = (YY * X + A(I)) * (X ** (I - A'First)));
         pragma Assert (Z = Y * (X ** (I - A'First)));
      end loop;
      pragma Assert (Y = Z);
      return Y;
   end Horner;
end Poly;

现在,所有断言和循环不变式都使用 SPARK Community 2020 中的 --level=2 进行证明。当然,有些断言是不需要的,因此您可以删除它们。

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

如何证明这个不变量呢? 的相关文章

  • Ada 95:修改字典程序的输出

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

    Closed 这个问题是基于意见的 目前不接受答案 这是我之前的帖子的后续内容 Ada 了解私有类型并了解包装 一个实现Rectangular类型是使用一种实现来制作的 即Rectangular Method 1此实现需要一个规范文件和一个
  • Ada:gnat gprbuild 如何链接到库中?

    在我正在处理的这个多语言 GPRBuild 项目中 我有一些 C 库文件 a 我需要链接到我的可执行文件中 是否有 gpr 属性告诉它链接什么或无论如何将 l L 开关传递给链接器 或者甚至更好 Project my library is
  • 代码应该简短/简洁吗? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 在编写数学证明时 一个目标是继续压缩证明 证明变得更加优雅 但不一定更具可读性 压缩可以帮助您更好地理解 因为您可以删除不必要的字符和冗长的内容
  • 如何检查一个元素是否属于一种子类型或另一种子类型?

    刚刚了解了 Ada 中的枚举和类型 决定写一个小程序来练习 with Ada Text IO use Ada Text IO with Ada Integer Text IO use Ada Integer Text IO procedur
  • 仅数学证明助理

    大多数证明助手都是具有依赖类型的函数式编程语言 他们可以证明程序 算法 相反 我感兴趣的是最适合数学且仅适合数学 例如微积分 的证明助手 你能推荐一个吗 我听说过 Mizar 但我不喜欢源代码被关闭 但如果它最适合数学 我会使用它 Agda
  • 什么是“libgnarl”?

    What is libgnarl 我在不同的地方找到了对此的引用 例如在 gcc 源代码中或 gprbuild 的详细输出中 gprbuild 特别报告了有关决定是否libgnarl甚至是必要的 所以它显然是一个可选库 但实际的库是什么 我
  • 异质平等的一致性

    我正在尝试使用异构相等来证明涉及此索引数据类型的语句 data Counter Set where cut i j Counter suc i j 我能够使用以下方式编写我的证明Relation Binary HeterogenousEqu
  • 标准 ada 包含路径是什么

    我在使用 apt get 安装的 Ubuntu 上使用 gnat 4 6 我需要知道在哪里安装下载的库 例如APQ http sourceforge net projects apq 我应该设置什么ADA INCLUDE PATH and
  • Ada 中类型/包别名的单独声明

    我想声明一些 用户定义的编译器常量 以使我的规范文件尽可能保持 常量 这在 C 中很常见 例如 misc config hh namespace misc typedef std shared ptr a A ptr namespace a
  • 可以从 C++ 调用 Ada 函数吗?

    我是一个完全的 Ada 新手 尽管我在高中期间已经使用 Pascal 2 3 年了 IIRC 可以从 C C 调用 Pascal 编译函数 是否可以从 C 调用用 Ada 编写的过程和函数 根据这个旧教程 http www ghs com
  • Ada.Containers.Functional_Maps 在 Ada2012 中可用吗?

    有关的信息Ada Containers Functional Maps https docs adacore com gnat rm docs html gnat rm gnat rm the gnat library html ada c
  • 我该如何为这个不变量编写一个循环?

    这些是查找数组 b h k 最小值的算法的断言 Precondition h lt k lt b length Postcondition b x is the minimum of b h k 这是这个不变量的正确循环吗 不变式 b x
  • 伪代码归纳证明

    我不太明白如何在伪代码上使用归纳证明 它的工作方式似乎与在数学方程上使用它的方式不同 我正在尝试计算数组中可被 k 整除的整数的数量 Algorithm divisibleByK a k Input array a of n size nu
  • Ada T'Class 的基础知识

    虽然有点不好意思问这个问题 但我知道这是最好的 我已经使用 Ada 编程很多年了 并且几乎可以流利地理解该语言的每个部分 然而 我似乎始终无法完全理解 T Class 借用别人的话 有人可以 像我五岁一样解释一下吗 编辑 我买它只是为了拥有
  • Coq 中的案例分析证明

    我试图证明关于以下函数的命题 Program Fixpoint division m nat n nat measure m nat match lt nat 0 n with false gt 0 true gt match leq na
  • 协变类型 T 发生在不变位置

    我正在 Scala 中迈出第一步 我想让以下代码起作用 trait Gene T val gene Array T 编译器给出的错误是 covariant type T occurs in invariant position in typ
  • 让 Ada(用 GNAT 编译)从当前目录外部导入文件?

    我正在大学学习编程入门课程 选择的语言是 Ada 我正在 Kate 中编码并使用 GNAT 4 6 3 进行编译 我们必须为我们的程序使用教师提供的库 如下所示 with foo use foo 当然 然后文件foo adb必须包含在与我的
  • ‘access’参数模式有什么用处?

    Ada 中有三种传递参数的 正常 模式 in out and in out 但还有第四种模式 access 有什么需要它们的吗 即 否则不可能实现的事情 现在 我确实知道 GNAT JVM Ada 编译器在导入的 库 规范中大量使用了它们
  • [“03C0”]如何匹配附件P中的语法?

    我正在编写一个工具来使用 2005 年附录 P 中提供的语法来解析 Ada 源文件 通过下面的代码 我知道 03C0 代表 希腊字母Pi 但它是合法的变量名吗 01 package Ada Numerics is 02 Pi constan

随机推荐