Modelica 意外的断言行为
Modelica unexpected behaviour of assertion
我需要断言一个变量(下面 MWE 中的 a)大于另一个变量(b)。
我注意到导入模型中的断言 a>b
表现得像 a>=b
。
我试图解决该问题以改为断言 a>(b+Constants.small)
。
更改断言,即使在断言 a>(b+someBiggerNumber)
时仍然不能像预期的那样为 a=b
工作。如果 a!=b
断言按预期工作。
这是一个错误还是我做错了什么?如果是错误,是否有解决方法?
MWE:
model MWE
model SomeModel
parameter Real a(start=1);
parameter Real b(start=1);
protected
Real c=5/(a-b);
equation
assert(a > b, "a has to be bigger than b. However, a (=" + String(a) +") < b (=" + String(b) + ")");
//assert(a > (b + 1), "a has to be bigger than b+1. However, a (=" + String(a) +") < b (=" + String(b) + ")");
end SomeModel;
SomeModel sm(a = 5, b = 5);
Real var;
equation
var = sm.c;
end MWE;
// assert a > b
// a=5, b=4 no fail, as expected, same for b<4
// a=5, b=5 no fail
// a=5, b=6 fail, as expected, same for b>3
// assert a > (b + 1)
// a=5, b=3 no fail, as expected, same for b<3
// a=5, b=4 fail, as expected
// a=5, b=5 no fail
// a=5, b=6 fail, as expected, same for b>3
您可以检查 Real 变量是否与 Modelica.Math.isEqual(a,b)
相等,并像这样组合它:(a > b) or Modelica.Math.isEqual(a,b)
和往常一样,问题出在键盘前:/
我无法通过在脑海中逐步解决问题来解决问题。
断言工作正常,但 Modelica 不会像大多数编程语言那样按顺序逐步执行方程式,因此 运行 在断言任何事情之前进入被零错误除法。
像这样改变顺序
protected
Real c;
initial equation
assert(a > b, "a has to be bigger than b. However, a (=" + String(a) +") < b (=" + String(b) + ")");
algorithm
assert(a > b, "a has to be bigger than b. However, a (=" + String(a) +") < b (=" + String(b) + ")");
equation
assert(a > b, "a has to be bigger than b. However, a (=" + String(a) +") < b (=" + String(b) + ")");
c=5/(a-b);
不会改变这一点。
如果有人知道如何首先 运行 断言以获得更清晰的错误消息,欢迎您输入:)
如果你想得到一个可预测的顺序,使用一个算法:
protected
Real c;
algorithm
assert(a > b, "a has to be bigger than b. However, a (=" + String(a) +") <= b (=" + String(b) + ")");
c:=5/(a-b);
或者将其转换为函数并将断言放入函数中。
你必须在算法部分做你想控制的部分,例如:
model MWE
model SomeModel
parameter Real a(start=1);
parameter Real b(start=1);
protected
Real c;
algorithm
assert(a > b, "a has to be bigger than b. However, a (=" + String(a) +") < b (=" + String(b) + ")");
//assert(a > (b + 1), "a has to be bigger than b+1. However, a (=" + String(a) +") < b (=" + String(b) + ")");
c := 5/(a-b);
end SomeModel;
SomeModel sm(a = 5, b = 5);
Real var;
equation
var = sm.c;
end MWE;
如果您在一个算法中放置两个赋值,它们肯定会按正确的顺序执行。编译器可以自由更改其他方程式的顺序,如果我没记错的话,断言将被视为 "removed equations",它没有任何对模拟有贡献的输出值,这些是在完整步骤之后计算的。所以它总是在方程式被评估之后。这样做是因为断言通常在步骤结束时进行测试,以防止下一个步骤发生。
编辑:啊,我刚刚看到@Hans Olson 发布了相同的解决方案,抱歉!
我需要断言一个变量(下面 MWE 中的 a)大于另一个变量(b)。
我注意到导入模型中的断言 a>b
表现得像 a>=b
。
我试图解决该问题以改为断言 a>(b+Constants.small)
。
更改断言,即使在断言 a>(b+someBiggerNumber)
时仍然不能像预期的那样为 a=b
工作。如果 a!=b
断言按预期工作。
这是一个错误还是我做错了什么?如果是错误,是否有解决方法?
MWE:
model MWE
model SomeModel
parameter Real a(start=1);
parameter Real b(start=1);
protected
Real c=5/(a-b);
equation
assert(a > b, "a has to be bigger than b. However, a (=" + String(a) +") < b (=" + String(b) + ")");
//assert(a > (b + 1), "a has to be bigger than b+1. However, a (=" + String(a) +") < b (=" + String(b) + ")");
end SomeModel;
SomeModel sm(a = 5, b = 5);
Real var;
equation
var = sm.c;
end MWE;
// assert a > b
// a=5, b=4 no fail, as expected, same for b<4
// a=5, b=5 no fail
// a=5, b=6 fail, as expected, same for b>3
// assert a > (b + 1)
// a=5, b=3 no fail, as expected, same for b<3
// a=5, b=4 fail, as expected
// a=5, b=5 no fail
// a=5, b=6 fail, as expected, same for b>3
您可以检查 Real 变量是否与 Modelica.Math.isEqual(a,b)
相等,并像这样组合它:(a > b) or Modelica.Math.isEqual(a,b)
和往常一样,问题出在键盘前:/
我无法通过在脑海中逐步解决问题来解决问题。 断言工作正常,但 Modelica 不会像大多数编程语言那样按顺序逐步执行方程式,因此 运行 在断言任何事情之前进入被零错误除法。
像这样改变顺序
protected
Real c;
initial equation
assert(a > b, "a has to be bigger than b. However, a (=" + String(a) +") < b (=" + String(b) + ")");
algorithm
assert(a > b, "a has to be bigger than b. However, a (=" + String(a) +") < b (=" + String(b) + ")");
equation
assert(a > b, "a has to be bigger than b. However, a (=" + String(a) +") < b (=" + String(b) + ")");
c=5/(a-b);
不会改变这一点。
如果有人知道如何首先 运行 断言以获得更清晰的错误消息,欢迎您输入:)
如果你想得到一个可预测的顺序,使用一个算法:
protected
Real c;
algorithm
assert(a > b, "a has to be bigger than b. However, a (=" + String(a) +") <= b (=" + String(b) + ")");
c:=5/(a-b);
或者将其转换为函数并将断言放入函数中。
你必须在算法部分做你想控制的部分,例如:
model MWE
model SomeModel
parameter Real a(start=1);
parameter Real b(start=1);
protected
Real c;
algorithm
assert(a > b, "a has to be bigger than b. However, a (=" + String(a) +") < b (=" + String(b) + ")");
//assert(a > (b + 1), "a has to be bigger than b+1. However, a (=" + String(a) +") < b (=" + String(b) + ")");
c := 5/(a-b);
end SomeModel;
SomeModel sm(a = 5, b = 5);
Real var;
equation
var = sm.c;
end MWE;
如果您在一个算法中放置两个赋值,它们肯定会按正确的顺序执行。编译器可以自由更改其他方程式的顺序,如果我没记错的话,断言将被视为 "removed equations",它没有任何对模拟有贡献的输出值,这些是在完整步骤之后计算的。所以它总是在方程式被评估之后。这样做是因为断言通常在步骤结束时进行测试,以防止下一个步骤发生。
编辑:啊,我刚刚看到@Hans Olson 发布了相同的解决方案,抱歉!