我有一个功能,通过应用一个简单的检查信号是否在给定的容差范围内来监控受控信号。该函数被调用is_within_limits
。我有第二个函数is_within_expanded_limits
,它的作用相同,但事先将扩展因子(扩大公差带)应用于配置的限制。monitor.config
通过目标值和与该值的最大偏差或下限和上限阈值来配置限制。枚举monitor.config.monitoring_mode
指定如何指定有效范围。
先看一下代码。
规格
subtype Float_Signed1000 is Float range -1_000.0 .. 1_000.0;
subtype Float_Signed10000 is Float range -10_000.0 .. 10_000.0;
type Monitor_Config_T is record
monitoring_mode : Monitoring_Mode_T := mean_based;
mean : Float_Signed1000 := 0.0;
maximum_deviation : Float range Float'Small .. 1_000.0 := 100.0e-3;
lower_threshold : Float_Signed1000 := -100.0e-3;
upper_threshold : Float_Signed1000 := 100.0e-3;
settling_tolerance_expansion : Float range (1.0 + Float'Small) .. 2.0 := 1.2;
startup_time : Time_Span := Milliseconds (5);
settling_time : Time_Span := Milliseconds (2);
violation_time : Time_Span := Milliseconds (5);
retry_time : Time_Span := Milliseconds (100);
end record;
type Monitor_T is record
config : Monitor_Config_T;
timer : Time_Span := Milliseconds (0);
current_state : Monitor_State_T := reset;
next_state : Monitor_State_T := reset;
end record;
function is_within_expanded_limits (monitor : in Monitor_T;
signal_value : in Float_Signed1000)
return Boolean
with Pre => (if monitor.config.monitoring_mode = mean_based then
monitor.config.maximum_deviation > 0.0)
and then (if monitor.config.monitoring_mode = threshold_based then
monitor.config.lower_threshold <
monitor.config.upper_threshold)
and then monitor.config.settling_tolerance_expansion > 1.0;
执行
function is_within_expanded_limits (monitor : in Monitor_T;
signal_value : in Float_Signed1000)
return Boolean is
within_expanded_limits : Boolean := False;
expanded_lower_threshold : Float Float_Signed10000;
expanded_upper_threshold : Float Float_Signed10000;
begin
case monitor.config.monitoring_mode is
when mean_based =>
if abs (monitor.config.mean - signal_value) <=
(monitor.config.maximum_deviation *
monitor.config.settling_tolerance_expansion) then
within_expanded_limits := True;
end if;
when threshold_based =>
-- Added due to recommendation by Jacob Sparre Andersen
-- Assertion is proved successfully
-- pragma Assert (monitor.config.lower_threshold < monitor.config.upper_threshold);
-- Added due to recommendation by Martin Becker
-- Adding this assumption still causes the assertion to fail
-- pragma Assume (monitor.config.lower_threshold = 10.0);
-- Adding this assumption still causes the assertion to fail
-- pragma Assume (monitor.config.upper_threshold = 11.0);
-- Replacing the assumption with this one results in the assertion being proved
-- pragma Assume (monitor.config.upper_threshold = 20.0);
-- Calculate expanded thresholds
if monitor.config.lower_threshold >= 0.0 then
expanded_lower_threshold := monitor.config.lower_threshold /
monitor.config.settling_tolerance_expansion;
else
expanded_lower_threshold := monitor.config.lower_threshold *
monitor.config.settling_tolerance_expansion;
end if;
if monitor.config.upper_threshold >= 0.0 then
expanded_upper_threshold := monitor.config.upper_threshold *
monitor.config.settling_tolerance_expansion;
else
expanded_upper_threshold := monitor.config.upper_threshold /
monitor.config.settling_tolerance_expansion;
end if;
-- @TODO why does this assertion fail?
pragma Assert (expanded_lower_threshold < expanded_upper_threshold);
-- Check limits with expanded thresholds
if signal_value >= expanded_lower_threshold and signal_value <=
expanded_upper_threshold then
within_expanded_limits := True;
end if;
end case;
return within_expanded_limits;
end is_within_expanded_limits;
我的问题是断言pragma Assert (expanded_lower_threshold < expanded_upper_threshold)
被标记为可能失败,我不明白为什么。我添加了该断言以检查我的代码是否没有像反转下阈值和上限阈值的关系那样奇怪,但主要是为了尝试断言。先决条件monitor.config.lower_threshold < monitor.config.upper_threshold
与计算代码的结合expanded_lower_threshold
应expanded_upper_threshold
保证断言始终成立。问题出在哪里,我该如何解决?