Skip to content

Commit 5bfe4c3

Browse files
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>
1 parent e794500 commit 5bfe4c3

File tree

2 files changed

+87
-4
lines changed

2 files changed

+87
-4
lines changed

chapters/functions.tex

Lines changed: 81 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ \section{Function as a Specialized Class}\label{function-as-a-specialized-class}
173173
\item
174174
For initialization of local variables of a function see \cref{initialization-and-binding-equations-of-components-in-functions}).
175175
\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.
177177
\end{itemize}
178178

179179
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
17711771

17721772
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.
17731773
\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.
1788+
\begin{lstlisting}[language=modelica]
1789+
function greaterEqual
1790+
input Real x1;
1791+
input Real x2;
1792+
output Boolean b;
1793+
algorithm
1794+
b := x1 >= x2;
1795+
annotation(GenerateEvents=true, LateInline=true);
1796+
end greaterEqual;
1797+
1798+
function greaterEqualWO
1799+
input Real x1;
1800+
input Real x2;
1801+
output Boolean b;
1802+
algorithm
1803+
b := x1 >= x2;
1804+
annotation(LateInline=true);
1805+
end greaterEqualWO;
1806+
1807+
model M
1808+
Boolean b1 = greaterEqual(time, 1);
1809+
Boolean b2 = greaterEqualWO(time, 1) "Illegal";
1810+
Boolean b3 = noEvent(greaterEqual(time, 1)) "Illegal";
1811+
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!}.
1829+
\begin{lstlisting}[language=modelica]
1830+
function saturatedSquare
1831+
input Real x2;
1832+
output Real y;
1833+
algorithm
1834+
if x2 > 1 then
1835+
y := 1;
1836+
else
1837+
y := x2^2;
1838+
end if;
1839+
end saturatedSquare;
1840+
1841+
function isBelowSat
1842+
input Real x1, x2;
1843+
output Boolean b;
1844+
algorithm
1845+
b : = x1 < saturatedSquare(x2);
1846+
annotation (GenerateEvents=true, LateInline=true);
1847+
end isBelowSat;
1848+
\end{lstlisting}
1849+
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.
1853+
\end{example}
17741854
\end{semantics}
17751855
\end{annotationdefinition}
17761856

chapters/operatorsandexpressions.tex

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1586,7 +1586,7 @@ \subsection{Evaluable Expressions}\label{evaluable-expressions}
15861586
\item
15871587
Evaluable parameter variables, see \cref{component-variability}.
15881588
\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.
15901590
\item
15911591
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.
15921592
\item
@@ -1597,7 +1597,7 @@ \subsection{Evaluable Expressions}\label{evaluable-expressions}
15971597
\item
15981598
\lstinline!cardinality(c)!, see restrictions for use in \cref{cardinality-deprecated}.
15991599
\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).
16011601
\item
16021602
\lstinline!Connections.isRoot(A.R)!
16031603
\item
@@ -1646,10 +1646,13 @@ \subsection{Discrete-Time Expressions}\label{discrete-time-expressions}
16461646
Note that \lstinline!rem! and \lstinline!mod! generate events but are not discrete-time expressions.
16471647
In other words, relations inside \lstinline!noEvent!, such as \lstinline!noEvent(x>1)!, are not discrete-time expressions.
16481648
\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.
16491652
\item
16501653
The functions \lstinline!pre!, \lstinline!edge!, and \lstinline!change! result in discrete-time expressions.
16511654
\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.
16531656
\end{itemize}
16541657

16551658
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

Comments
 (0)