You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Discrete-time variability based on GenerateEvents (#3610)
* Add variability change for these functions.
* After some thinking I believe this is how we handle multiple outputs.
So, an Integer output will be discrete-time, but a Real output still non-discrete time (assuming the inputs are non-discrete time).
* To handle the other case for GenerateEvents-functions.
* Forgot variability for inputs previously.
* State that variables in functions being discrete-time is a bit more complicated, with link.
* Add examples.
* Apply suggestions from code review
Co-authored-by: Henrik Tidefelt <henrikt@wolfram.com>
Copy file name to clipboardExpand all lines: chapters/functions.tex
+81-1Lines changed: 81 additions & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -173,7 +173,7 @@ \section{Function as a Specialized Class}\label{function-as-a-specialized-class}
173
173
\item
174
174
For initialization of local variables of a function see \cref{initialization-and-binding-equations-of-components-in-functions}).
175
175
\item
176
-
Components of a function will inside the function behave as though they had discrete-time variability.
176
+
Components of a function follow special variability rules where the \lstinline!GenerateEvents! annotation plays a central role, see \cref{discrete-time-expressions} for details.
177
177
\end{itemize}
178
178
179
179
Modelica functions have the following enhancements compared to a general Modelica \lstinline!class!:
@@ -1771,6 +1771,86 @@ \section{Function Inlining and Event Generation}\label{function-inlining-and-eve
1771
1771
1772
1772
If the function is called in a context where events will not be generated (e.g., inside another function without {\lstinline!GenerateEvents = true!}) no special action is needed.
1773
1773
\end{nonnormative}
1774
+
\begin{example}
1775
+
\lstinline!GenerateEvents! impacts variability according to \cref{variability-of-expressions}.
1776
+
The benefit of treating functions with \lstinline!GenerateEvents = true! in this way is that it makes it possible to construct functions behaving like the built-in event generating operators.
1777
+
E.g., it allows constructing a variant of \lstinline!integer()! that rounds towards closest \lstinline!Integer! instead of towards $-\inf$ that is usable in the same way as \lstinline!integer()!.
1778
+
\begin{lstlisting}[language=modelica]
1779
+
function nearestInteger
1780
+
input Real r;
1781
+
output Integer i;
1782
+
algorithm
1783
+
i :=if (r > 0) then integer(floor(r + 0.5)) else integer(ceil(r - 0.5));
1784
+
end nearestInteger;
1785
+
\end{lstlisting}
1786
+
1787
+
The following is an illustration of some trivial cases.
Boolean b4 = greaterEqualWO(if b1 then 2 else 0, 1);
1812
+
Real z = if greaterEqualWO(time, 1) then 2 else 1;
1813
+
end M;
1814
+
1815
+
function bad
1816
+
input Real x1;
1817
+
output Integer i;
1818
+
algorithm
1819
+
i := greaterEqualWO(x1, 1) then 2 else 1;
1820
+
annotation(GenerateEvents=true, LateInline=true);
1821
+
end bad;
1822
+
\end{lstlisting}
1823
+
1824
+
In \lstinline!M!, there will be an event when \lstinline!time! becomes greater or equal to \lstinline!1!, and thus the discrete-time variable \lstinline!b1! can be bound to this function call even though it involves the non-discrete time variable \lstinline!time!.
1825
+
Both \lstinline!b2! and \lstinline!b3! are illegal, since the right hand sides have non-discrete-time variability.
1826
+
The variable \lstinline!z! is legal, since a \lstinline!Real! variable can have non-discrete time variability.
1827
+
The variable \lstinline!b4! is legal, since the function inputs have discrete-time variability.
1828
+
The function \lstinline!bad! demonstrates that similar restrictions (as for \lstinline!b2! and \lstinline!b3!) apply inside functions with {\lstinline!GenerateEvents = true!}.
The function \lstinline!isBelowSat! demonstrates that it is possible to call functions that do not generate events (like \lstinline!saturatedSquare!) inside functions with {\lstinline!GenerateEvents = true!}.
1850
+
Combined, the last two examples demonstrate that {\lstinline!GenerateEvents = true!} does not propagate to called functions.
1851
+
1852
+
The annotation \lstinline!LateInline=true! is not needed, but makes the issue more obvious in tools that normally inline function before checking variability.
Evaluable parameter variables, see \cref{component-variability}.
1588
1588
\item
1589
-
Input variables in functions behave as though they were evaluable expressions.
1589
+
Input variables in functions not having annotation \lstinline!GenerateEvents = true! (\cref{modelica:GenerateEvents}) behave as though they were evaluable expressions.
1590
1590
\item
1591
1591
Except for the special built-in operators \lstinline!initial!, \lstinline!terminal!, \lstinline!der!, \lstinline!edge!, \lstinline!change!, \lstinline!sample!, and \lstinline!pre!, a function or operator with evaluable subexpressions is an evaluable expression.
\lstinline!cardinality(c)!, see restrictions for use in \cref{cardinality-deprecated}.
1599
1599
\item
1600
-
\lstinline!size(A)! (including \lstinline!size(A, j)! where \lstinline!j! is an evaluable expression) if \lstinline!A! is variable declared in a non-function class.
1600
+
\lstinline!size(A)! (including \lstinline!size(A, j)! where \lstinline!j! is an evaluable expression) if \lstinline!A! is variable declared in a non-function class).
Note that \lstinline!rem! and \lstinline!mod! generate events but are not discrete-time expressions.
1647
1647
In other words, relations inside \lstinline!noEvent!, such as \lstinline!noEvent(x>1)!, are not discrete-time expressions.
1648
1648
\end{nonnormative}
1649
+
\item
1650
+
Unless inside \lstinline!noEvent!: Function calls where the function has annotation \lstinline!GenerateEvents = true! (\cref{modelica:GenerateEvents}), the output does not contain a subtype of \lstinline!Real!, and any non-\lstinline!Real! inputs have discrete-time variability.
1651
+
For a function call returning multiple return values (see \cref{output-formal-parameters-of-functions}) the variability is decided separately for each output.
1649
1652
\item
1650
1653
The functions \lstinline!pre!, \lstinline!edge!, and \lstinline!change! result in discrete-time expressions.
1651
1654
\item
1652
-
Expressions in functions behave as though they were discrete-time expressions.
1655
+
Expressions in functions not having annotation \lstinline!GenerateEvents = true! (\cref{modelica:GenerateEvents}), behave as though they were discrete-time expressions.
1653
1656
\end{itemize}
1654
1657
1655
1658
Inside an \lstinline!if!-expression, \lstinline!if!-clause, \lstinline!while!-statement or \lstinline!for!-clause, that is controlled by a non-discrete-time (that is continuous-time, but not discrete-time) switching expression and not in the body of a \lstinline!when!-clause, it is not legal to have assignments to discrete-time variables, equations between discrete-time expressions, or real elementary relations/functions that should generate events.
0 commit comments