This builds on my previous proposal, which was too wide in scope, and drops "empty units" from its scope, to retain the wildcard effect of variables with empty unit string.
In effect, we have to replace "expression containing only literal constants" with "expression containing only literal constants and mathematical operations".
This deals with distinguishing between exp(...)
and specificEnthalpy(...,...)
situations.
This is a minimal-diff change. If agreeable, I propose a behaviour-neutral refactoring below (BB2b) that is a bit larger but makes the structure clearer.
Updated rule 1:
\item The result of \lstinline!x + L!, \lstinline!L + x\lstinline!, \lstinline!x - L!, \lstinline!L - x!, \lstinline!x*L!, \lstinline!L*x!, \lstinline!x/L!, where \lstinline!x! is an expression with non-empty \lstinline!unit! attribute string `<s>` and \lstinline!L! is an expression containing only literal constants and mathematical operations, shall have the \lstinline!unit! attribute string of \lstinline!x!.
See the next section for the definition of "mathematical operations".
Updated rule 4:
\item If either side of a relational operator is an expression containing only literal constants and mathematical operations, then it is assumed to have the \lstinline!unit! attribute string of the other side, if that is well-defined.
We need to add a definition for "mathematical operations". Please help refine this first definition:
"Mathematical operations" in the context of unit checking are
- Arithmetic operators (3.4)
abs
,sign
,sqrt
,Integer
(i.e, 3.7.1 without String() and EnumTypeName())- Event Triggering Mathematical Functions (3.7.2)
- Elementary mathematical functions (3.7.3)
I'm unsure about the role of 3.7.4 and 3.7.5.
Alternatively, maybe it's 3.4 + all of 3.7 except operations returning Strings or Enumerations?
Cf. the equivalent section "expressions with empty unit" of #3257, where we find
The following compound expressions result in the empty unit if and only if all operands have empty unit:
\begin{itemize}
\item \lstinline!Real!-valued numeric operator expressions.
\item Function calls to \lstinline!Real!-valued built-in functions (see \cref{built-in-mathematical-functions-and-external-built-in-functions}, \cref{modelica:der}, \cref{modelica:pre}, \cref{modelica:abs}, \cref{modelica:sqrt}, \cref{modelica:floor}, etc.).
\end{itemize}
I suspect (but am not sure) that we forgot to define the role of assignment/equality in unit checking (probably "correct" behaviour was assumed). If that's correct, we need to add a rule for that, see the relevant section in BB2b below. It was too tedious to formulate in the minimal-change context, but the intent is clear I think.
To make the structure clearer and avoid repetition, some rearrangement was also included, and a rule concerning equality.
Add additional rules at the head of the list; avoid repeating what L
and x
are:
\item The result of mathematical operations *(precise scope TBD)* where all operands have undefined \lstinline!unit! string attribute has an undefined \lstinline!unit! string attribute.
(Non-normative addition: they behave just like literal constants themselves with respect to unit handling)
\item \lstinline!x! is an expression with non-empty \lstinline!unit! attribute string `<s>` and \lstinline!L! is an expression with undefined \lstinline!unit! attribute string.
See above for the definition of "mathematical operations".
Current rule 1 is now slimmer:
\item The result of \lstinline!x + L!, \lstinline!L + x\lstinline!, \lstinline!x - L!, \lstinline!L - x!, \lstinline!x*L!, \lstinline!L*x!, \lstinline!x/L! shall have the \lstinline!unit! attribute string of \lstinline!x!.
Current rule 4 can be cleaned up, too, not needing the "well defined" any more:
\item If a relational operator has \lstinline!x! and \lstinline!L! on opposite sides, \lstinline!L! has the same \lstinline!unit! attribute string as \lstinline!x!.
I suspect (but am not sure, see modelica/ModelicaSpecification#3266 (comment)) that we forgot to define the role of assignment/equality in unit checking (probably "correct" behaviour was assumed). If that's correct, we need to add a rule for that, too:
Concerning unit compatibility of equality \lstinline!a = b! and assignment \lstinline!a := b!:
\item If \lstinline!a!, \lstinline!b!, or both are of type \lstinline!L!, unit compatibility is given.
Additionally, we may want to also specify this (but maybe not, to limit PR scope)
\item If expressions \lstinline!a! and \lstinline!b! both are of type \lstinline!x!, their
\lstinline!unit! attribute strings need to be identical (TBC or just "compatible"?)
Note that we don't say anything about equality with "empty-unit-string" operands.