Ada 隐式函数契约不可用于证明

Ada 隐式函数契约不可用于证明,ada,gnat,spark-ada,Ada,Gnat,Spark Ada,我在SPARK包中有一个过程,它调用了none SPARK包中的一些函数 procedure do_monitoring is U_C1 : constant Float := Sim.Get_U_C1; I_L1 : constant Float := Sim.Get_I_L1; U_C2 : constant Float := Sim.Get_U_C2; I_L2 : constant Float := Sim.Get_I_L2; begin pragma As

我在SPARK包中有一个过程,它调用了none SPARK包中的一些函数

procedure do_monitoring is
   U_C1 : constant Float := Sim.Get_U_C1;
   I_L1 : constant Float := Sim.Get_I_L1;
   U_C2 : constant Float := Sim.Get_U_C2;
   I_L2 : constant Float := Sim.Get_I_L2;
begin
   pragma Assert (U_C1 in Float_Signed1000);
   pragma Assert (I_L1 in Float_Signed1000);
   pragma Assert (U_C2 in Float_Signed1000);
   pragma Assert (I_L2 in Float_Signed1000);
   --  Monitor PFC intermediate voltage
   monitor_signal (monitor_pfc_voltage, U_C1);
   --  Monitor PFC inductor current
   monitor_signal (monitor_pfc_current, I_L1);
   --  Monitor output voltage
   monitor_signal (monitor_output_voltage, U_C2);
   --  Monitor output inductor current
   monitor_signal (monitor_output_current, I_L2);
end do_monitoring;
GNAT为我提供了
信息:隐式函数契约不可用于证明(可能不会返回)
用于我从全局保护类型调用函数的所有四个声明行

受保护类型功能在非火花包中定义如下,并使用在受保护类型专用部分中声明的记录
Sim_Out
。所有记录值都用
0.0
初始化

function Get_I_L1 return Float is
begin
   return Sim_Out.I_L1;
end Get_I_L1;

function Get_U_C1 return Float is
begin
   return Sim_Out.U_C1;
end Get_U_C1;

function Get_I_L2 return Float is
begin
   return Sim_Out.I_L2;
end Get_I_L2;

function Get_U_C2 return Float is
begin
   return Sim_Out.U_C2;
end Get_U_C2;
解决这个问题的替代方案是什么?我已经添加了一些pragmas来向验证程序提供附加信息
子类型Float\u Signed1000是Float range-1\u 000.0。。1_000.0
但这并没有像我预期的那样奏效


我想在这里谈谈你对这个话题的建议。

如果允许我编辑
Sim
软件包,我可以说

package-Sim
带火花点火模式
是
函数Get return Float
带注释=>(Gnatprove,终止);
终端Sim;
(这是使用AdaCore的spark2017版本),然后使用无火花车身

包体Sim卡为
函数Get return Float为(42.0);
终端Sim;
报告显示已跳过Sim.Get

我不知道SPARK2014的后续版本将如何对此做出反应,因为从中可以看出,
注释
为验证者设置了一个目标,但我们不允许它查看
Sim
的主体进行检查


参考手册中可能还有更多内容-访问adacore.com,选择Resources/Documentation/SPARK。

如果允许我编辑
Sim
软件包,我可以说

package-Sim
带火花点火模式
是
函数Get return Float
带注释=>(Gnatprove,终止);
终端Sim;
(这是使用AdaCore的spark2017版本),然后使用无火花车身

包体Sim卡为
函数Get return Float为(42.0);
终端Sim;
报告显示已跳过Sim.Get

我不知道SPARK2014的后续版本将如何对此做出反应,因为从中可以看出,
注释
为验证者设置了一个目标,但我们不允许它查看
Sim
的主体进行检查


参考手册中可能还有更多内容-请访问adacore.com,选择Resources/Documentation/SPARK。

我会按照提示“函数可能不会返回”。。。我们没有Sim_Get_*的来源,但你有。有没有什么路径不会返回?@BrianDrummond等一下,我会快速编辑我的问题。我刚刚在谷歌上搜索了“隐式函数契约无法证明”(没有引号;我刚刚得到了这个问题的引号),第七个答案看起来很有关联;在最后一节。当我添加“spark2014”时,谷歌将这一点击排名更高@SimonWright如果你粘贴URL,我将不胜感激:-)试试……我会按照提示“函数可能不会返回”。。。我们没有Sim_Get_*的来源,但你有。有没有什么路径不会返回?@BrianDrummond等一下,我会快速编辑我的问题。我刚刚在谷歌上搜索了“隐式函数契约无法证明”(没有引号;我刚刚得到了这个问题的引号),第七个答案看起来很有关联;在最后一节。当我添加“spark2014”时,谷歌对这一点击率的排名更高。@SimonWright如果您粘贴URL,我将不胜感激:-)试试……有没有可能告诉SPARK我已经测试了它终止的功能保证?当您有一个不能处于SPARK模式的包,因为它使用SPARK中不允许的功能,其子程序由SPARK包调用时,如何解决此类问题。Brian Drummonds包装包是一个可行的替代方案吗?明年,验证人如何知道这仍然是真的?我认为,在某种程度上,你必须证明这类事情的合理性——也许是在验证报告中。例如,如果你不能更改
Sim
软件包,布赖恩的建议可能会有所帮助,但在底层仍然会存在无法实现的问题。我有一种感觉,当prover看到一个
pragma assessment
,如果它在这里也起作用的话,它会报告(这样你就会知道哪些部分必须“手动”进行验证)。我选择使用注释来验证消息。我在中找到了更多信息,并尝试在每个标记行下方添加
pragma注释(GNATprove,False_Positive,“may not return”,“checked by Simon”)
。但它不起作用,可能是因为它不是一个错误或警告,而是一个信息。有什么建议吗?我在上面给出的链接表明,出于此目的,您需要一种不同形式的
pragma Annotate
(或者我在回答中显示的方面;此注释特定于指定的子程序,而您尝试使用的注释特定于代码中的位置)。谢谢,这完全奏效了。我在被调用者软件包规范中激活了SPARK,并添加了带有
关键字的建议注释。在您给出答案后,我已经尝试了很短的时间,但我收到了一个关于非初始化数组的主动警告,该数组使GNATprove终止,并且没有检查其他内容。我不知道这一点,认为注释不起作用。GNATprove继续检查源代码的其余部分,随后我修复了数组初始化和注释。是否有可能告诉SPARK我已经测试了函数保证它终止?当您有一个不能处于SPARK模式的包,因为它使用SPARK中不允许的功能,其子程序由SPARK包调用时,如何解决此类问题。Brian Drummonds包装包是可行的替代方案吗?验证人怎么知道,nex