我正在尝试编写一个简单的验证代码块以确保参数(Ada.Command_Line.Argument)和来自 GetLine 的输入是有效的,在我的情况下,我需要输入字符串中的所有字符都是数字(0 到 9 )。
主.adb:
pragma SPARK_Mode (On);
with test_procedure;
with Ada.Command_Line;
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
procedure Main is
package CL renames Ada.Command_Line;
user_str : String := CL.Argument(1);
Flag : Boolean := False;
begin
if CL.Argument_Count = 1 then
for I in user_str'Range loop
case user_str(I) is
when '0'..'9' => Flag := True;
when others => Flag := False; exit;
end case;
end loop;
end if;
if Flag then
test_procedure.ToA(user_str);
Put(user_str);
end if ;
end Main;
test_procedure.ads:
package test_procedure with SPARK_Mode is
procedure ToA(S : in out String) with
Pre => (for all I in S'Range => S(I) >= '0' and S(I) <= '9');
end test_procedure;
test_procedure.adb
package body test_procedure with SPARK_Mode is
procedure ToA(S : in out String) is
begin
for I in S'Range loop
S(I) := 'a';
end loop;
end ToA;
end test_procedure;
该程序运行良好。如果我输入./main 01234
它将返回aaaaa
,如果我输入./main f00
它将不返回任何内容。但是,当我使用 GNATprove(在 GPS -> SPARK -> Prove All 中)时,它给了我precondition might fail, cannot prove S(I) >= '0' (e.g. when I = 1 and user_str = (2 => '0', others => 'NUL'))
. 我不确定为什么会发生这种情况,因为如果没有数字字符存在,则不应调用 ToA 过程。