Ada GNAT 证明 1 不是 >= 0

标签 ada proof invariants proof-of-correctness spark-ada

我试图证明,我在数组中查找第二大值的算法可以正常工作。这是我的代码:

function FindMax2 (V : Vector) return Integer is
    Max : Natural := 0;
    SecondMax : Natural := 0;
begin
    for I in V'Range loop

        pragma Assert
            (Max >= 0 and
            SecondMax >= 0 and
            V(I) > 0);

        if V(I) > Max then
            SecondMax := Max;
            Max := V(I);
        elsif V(I) /= Max and V(I) > SecondMax then
            SecondMax := V(I);
        end if;

        pragma Loop_Invariant
                    (Max > SecondMax and
                    V(I) > 0 and
                    (for all J in V'First .. I => V(J) <= Max));
    end loop;
    return SecondMax;
end FindMax2;

这是我的前置条件和后置条件:

package Max2 with SPARK_Mode is

    type Vector is array (Integer range <>) of Positive;

    function FindMax2 (V : Vector) return Integer
    with
        Pre => V'First < Integer'Last and V'Length > 0,
        Post => FindMax2'Result >= 0 and
        (FindMax2'Result = 0 or (for some I in V'Range => FindMax2'Result = V(I))) and
        (if FindMax2'Result /= 0 then (for some I in V'Range => V(I) > FindMax2'Result)) and
        (if FindMax2'Result = 0 then (for all I in V'Range => (for all J in V'Range => V(I) = V(J)))
        else
            (for all I in V'Range => (if V(I) > FindMax2'Result then (for all J in V'Range => V(J) <= V(I)))));
end Max2;

我现在被 GNATprove 的这条消息困住了:

max2.ads:8:17: medium: postcondition might fail (e.g. when FindMax2'Result = 1 and V = (others => 1) and V'First = 0 and V'Last = 0)

如果我没记错的话是指第一个条件结果大于等于0,那为什么要用1作为反例呢?有什么办法可以证明这一点吗?

最佳答案

我设法解决了我的问题。我对错误消息的理解是错误的,gnatprove 正在引用整个后置条件语句。如果有人对解决方案感兴趣,我在循环不变量中添加了几个条件

pragma Loop_Invariant
            (Max > SecondMax and
            V(I) > 0 and
            (for all J in V'First .. I => V(J) <= Max) and

            (Max = 0 or (for some J in V'First .. I => Max = V(J))) and
            (SecondMax = 0 or (for some J in V'First .. I => SecondMax = V(J))) and

            (if SecondMax = 0 then (for all J in V'First .. I => (for all K in V'First .. I => V(J) = V(K)))
            else (for all J in V'First .. I => (if V(J) > SecondMax then (for all K in V'First .. I => V(K) <= V(J))))));

关于Ada GNAT 证明 1 不是 >= 0,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67202546/

相关文章:

arrays - Ada 中的字符串数组

AVL 树的成员证明

coq - 了解 Show Proof 上的 COQ 证明。

java - 我正在使用 daikon Chicory 进行不变检测,但遇到 java.lang.VerifyError

C# 3.5 协方差问题?

ada - 尝试运行 gnattest 时出错

arrays - 将数组初始化为空对象

interrupt - Ada - pragma Attach_Handler() 是否可以将处理程序附加到 System.Priority'Last 优先级?

proof - Isabelle/HOL 中的 Verifier 核心

c++ - 前置条件通常与不变量重叠吗?