我有两条评论。首先,请记住,在处理子句时,使用运算符来明确说明您所指的值是新的还是以前的值when
,通常是谨慎的。pre(...)
我不知道在这种情况下是否是绝对必要的(即使我知道,我也不确定 Modelica 工具的所有开发人员是否都使用一致的语义),但如果只是明确说明一下是个好主意代码的读者。
另一个问题是算法的处理。algorithm
通常,语句按照它们在该部分中出现的顺序执行。但是when
子句有点棘手,因为它们具有异步性质。when
同样,关于子句与模型中其他赋值语句的交错,我不清楚确切的语义是什么,但是algorithm
像你这样写一个部分有点模棱两可。假设when
语句被评估并被x
赋予一个新值,您希望它保持该值多长时间?编译器在重复评估算法部分有自由度可能会在when
调用子句后立即评估,在这种情况下x
将被赋予一个新值5
(也许甚至根本没有时间推进)。
我不确定你对这个模型的真正意图是什么。但是,如果您希望它以一个值开始,然后在 time>3 之后采用新值(基于旧值),我在 Modelica 中看到了两种实现方式,它们都涉及如何设置初始值价值。考虑以下模型:
model InitAndEvent
discrete Integer x(start=1);
algorithm
when initial() then
x := 5;
end when;
when time >= 3 then
x := pre(x) + 5;
end when;
end InitAndEvent;
该模型使用pre
运算符,但更重要的是,它还使用initial()
事件为x
. 通过这种方式,这避免了您在以前的模型中可能遇到的不断覆盖x
to值的问题5
。另一种方法可能是:
model InitAndEvent
discrete Integer x(start=1);
initial algorithm
x := 5;
algorithm
when time >= 3 then
x := pre(x) + 5;
end when;
end InitAndEvent;
尽管我承认我怀疑不同的工具可能对每个版本有不同的语义。我想说这个when initial()
版本可能更普遍一致。
更新:
我认为您的误解来自于没有考虑后续评估的影响。在 的情况下try1
,在 time==3 时,该when
子句被评估并被x
赋予一个新值。
但是下一次模型评估会发生什么?再次评估算法部分并x
设置回 5。在条件表达式变为假然后再次变为真之前,不会再次评估该when
子句。所以在这种情况下,它只触发一次!如果您希望对大于 3 的所有时间进行评估,则需要使用语句。if
when
并记住这个问题......从执行子句到下一次模型评估(何时x
重置)之间经过了多少模拟时间?很可能没有。您无法知道何时执行算法部分(这取决于事件、使用的积分器等)。因此,如果您想x
在模拟开始时和在 时获得一个值time==3
,那么您需要在模型中声明它(就像我在示例中所做的那样)。