隐式函数合约不可用于证明
Implicit Function Contract not available for Proof
我在 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 为我从全局受保护类型调用函数的所有四个声明行提供 info: implicit function contract not available for proof (<function_name> may not return)
。
受保护类型函数在 非 SPARK 包 中定义如下,并使用在受保护类型私有部分中声明的记录 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 来为证明者提供额外的信息 subtype Float_Signed1000 is Float range -1_000.0 .. 1_000.0
但结果并不像我预期的那样。
我想在这里听听你对这个话题的建议。
如果允许我编辑 Sim
包,我可以说
package Sim
with SPARK_Mode
is
function Get return Float
with Annotate => (Gnatprove, Terminating);
end Sim;
(那是用AdaCore的spark2017版本),跟进一个非SPARK的body
package body Sim is
function Get return Float is (42.0);
end Sim;
报告显示 Sim.Get 已被跳过。
我不知道 SPARK2014 的后续版本对此有何反应,因为 User Guide 的含义是 Annotate
为证明者设定了一个目标,但我们已经不允许它查看 Sim
的主体进行检查。
也许参考手册中还有更多内容 - 转到 adacore.com、select Resources/Documentation/SPARK。
我在 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 为我从全局受保护类型调用函数的所有四个声明行提供 info: implicit function contract not available for proof (<function_name> may not return)
。
受保护类型函数在 非 SPARK 包 中定义如下,并使用在受保护类型私有部分中声明的记录 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 来为证明者提供额外的信息 subtype Float_Signed1000 is Float range -1_000.0 .. 1_000.0
但结果并不像我预期的那样。
我想在这里听听你对这个话题的建议。
如果允许我编辑 Sim
包,我可以说
package Sim
with SPARK_Mode
is
function Get return Float
with Annotate => (Gnatprove, Terminating);
end Sim;
(那是用AdaCore的spark2017版本),跟进一个非SPARK的body
package body Sim is
function Get return Float is (42.0);
end Sim;
报告显示 Sim.Get 已被跳过。
我不知道 SPARK2014 的后续版本对此有何反应,因为 User Guide 的含义是 Annotate
为证明者设定了一个目标,但我们已经不允许它查看 Sim
的主体进行检查。
也许参考手册中还有更多内容 - 转到 adacore.com、select Resources/Documentation/SPARK。