You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让GNATprove认可对同一输入两次调用Integer'Value结果一致?

解决GNATprove不认可同一字符串两次解析整数相等的问题

问题场景

当两次调用Integer'Value解析同一个合法整数字符串时,GNATprove无法自动证明两次解析结果相等,导致断言X1 = X2被标记为"might fail"。

代码示例

主程序 Eq_Test.adb

with String_Problem;

procedure Eq_Test is
begin
   String_Problem.String_Equal("4456");
end Eq_Test;

包规范 String_Problem.ads

package String_Problem
with Spark_Mode
is
   procedure String_Equal
     (A : String)
   with
       Ghost;
end String_Problem;

包体 String_Problem.adb

package body String_Problem
with Spark_Mode
is
   procedure String_Equal
     (A : String)
   is
      X1 : Integer;
      X2 : Integer;
   begin
      X1 := Integer'Value (A);
      pragma Annotate
        (Gnatprove, False_Positive, "precondition might fail", "we only call on valid integer strings");
      X2 := Integer'Value (A);
      pragma Annotate
        (Gnatprove, False_Positive, "precondition might fail", "we only call on valid integer strings");
      pragma Assert (X1 = X2);
   end String_Equal;
end String_Problem;

GNATprove 输出

alr gnatprove
Phase 1 of 2: generation of Global contracts ...
Phase 2 of 2: flow analysis and proof ...

string_problem.adb:16:22: medium: assertion might fail
   16 |      pragma Assert (X1 = X2);
      |                     ^~~~~~~
Summary logged in [path]/gnatprove/gnatprove.out

解决方案

1. 为过程添加前置条件约束输入合法性

修改String_Problem.ads,给String_Equal添加前置条件,明确输入字符串是合法的整数字符串。这不仅能消除Integer'Value前置条件的警告,还能让GNATprove明确输入的有效性,为后续的确定性证明提供基础:

package String_Problem
with Spark_Mode
is
   procedure String_Equal
     (A : String)
   with
       Ghost,
       Pre => Integer'Wide_Value_String(A); -- 确保输入是合法整数字符串
end String_Problem;

2. 移除不必要的False_Positive注解

修改String_Problem.adb,去掉针对Integer'Value的False_Positive注解,因为前置条件已经保证了输入符合Integer'Value的调用要求:

package body String_Problem
with Spark_Mode
is
   procedure String_Equal
     (A : String)
   is
      X1 : Integer;
      X2 : Integer;
   begin
      X1 := Integer'Value (A);
      X2 := Integer'Value (A);
      pragma Assert (X1 = X2);
   end String_Equal;
end String_Problem;

3. 验证证明结果

重新运行alr gnatprove,此时GNATprove会利用Integer'Value的纯函数特性(相同输入必然返回相同结果),结合前置条件的约束,成功证明X1 = X2的断言成立,不会再出现断言可能失败的警告。


内容的提问来源于stack exchange,提问作者user3519580

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 23:30:50