A Modelica operator record can overload the behavior for operations such as constructing, adding, multiplying etc.
The overloading is defined in such a way that ambiguities are not allowed and give an error. Furthermore, it is sufficient to define overloading for scalars. Overloaded array operations are automatically deduced from the overloaded scalar operations.
In an operator record the definition of operations are done using the specialized class operator (a specialized class similar to package, see section 4.6) followed by the name of the operation. Each operator class is comprised of functions implementing different variants of the operation for the operator record class in which the definition resides.
Overloaded constructors, see section 14.3:
’constructor’, ’0’
Overloaded string conversions, see section 14.4:
’String’
Overloaded binary operations, see section 14.5:
’+’, ’-’ (subtraction), ’*’, ’/’, ’^’,
’==’, ’<=’’, ’>’, ’<’,
’>=’, ’<=’, ’and’, ’or’
Overloaded unary operations, see section 14.6:
’-’ (negation), ’not’
The functions defined in the operator-class must take at least one component of the record class as input, except for the constructor-functions which instead must return one component of the record class. All of the functions shall return exactly one output.
The functions can be either called as defined in this section, or they can be called directly using the hierarchical name. The operator or operator function must be encapsulated; this allows direct calls of the functions and prohibits the functions from using the elements of operator record class.
The operator record may also contain additional functions, and declarations of components of the record. It is not legal to extend from an operator record, except as a short class definition modifying the default attributes for the component elements directly inside the operator record.
If an operator record was derived by a short class definition, the overloaded operators of this operator record are the operators that are defined in its base class, for subtyping see chapter 6.
The precedence and associativity of the overloaded operators is identical to the one defined in table 3.1 in section 3.2.
[Note, the operator overloading as defined in this section is only a short hand notation for function calls.]
All functions defined inside the operator class must return one output (based on the restriction above), and may include functions with optional arguments, i.e. functions of the form
The vector P indicates whether argument m of f has a default value (true for default value, false otherwise). A call f(, ,…, , = ,…, = ) with distinct names is a valid match for the function f, provided (treating Integer and Real as the same type)
= typeOf() for 1 i k,
the names = , Qj > k, = typeOf() for 1 j p, and
if the union of {i: 1 i k }, {Qj: 1 j p}, and {m: true and 1 m n } is the set {i: 1 i n}.
[This corresponds to the normal treatment of function calls with named arguments, requiring that all inputs have some value given by a positional argument, named argument, or a default value (and that positional and named arguments do not overlap). Note, that this only defines a valid call, but does not explicitly define the set of domains.]
Let C denote an operator record class and consider an expression C(, , , , =, , =).
If there exists a unique function in C.’constructor’ such that (, , …, , =, …, =) is a valid match for the function , then C(, , , , =, , =) is resolved to C.’constructor’.(, , , , =, , =).
If there is no operator C.’constructor’ the automatically generated record constructor is called.
Otherwise the expression is erroneous.
Restrictions:
The operator C.’constructor’ shall only contain functions that declare one output component, which shall be of the operator record class C.
For an operator recordclass there shall not exist any potential call that lead to multiple matches in item 1 above.
[How to verify this is not specified.]
For a pair of operator record classes C and D and components c and d of these classes both of C.’constructor’(d) and D.’constructor’(c) shall not both be legal.
[Hence, one of the two definitions must be removed.]
[By the last restriction the following problem for binary operators is avoided:
Assume there are two operator record classes C and D that both have a constructor from Real. If we want to extend c + c and d + d to support mixed operations, one variant would be to define c + d and d + c; but then c + 2 becomes ambiguous (since it is not clear which instance should be converted to). Without mixed operations expressions such as c + d are only ambiguous if both conversion from C to D and back from D to C are both available, and this possibility is not allowed by the restriction above.]
Additionally there is an operator ’0’ defining the zero-value which can also be used to construct an element. The operator ’0’ for an operator record C can contain only one function, having zero inputs and one output of type C (the called function is therefore unambiguous). It should return the identity element of addition, and is used for generating flow-equations for connect-equations and zero elements for matrix multiplication.
Consider an expression String(, , , , =, , =), where is an element of class A.
If A is a predefined type, i.e., Boolean, Integer, Real, String or an enumeration, or a type derived from them, then the corresponding built-in operation is performed.
If A is an operator record class and there exists a unique function
in A.’String’ such that
A.’String’.(, , , , =, , =)
is a valid match for , then
String(, , , , =, , =)
is evaluated to
A.’String’.(, , , , =, , =).
Otherwise the expression is erroneous.
Restrictions:
The operator A.’String’ shall only contain functions that declare one output component, which shall be of the String type, and the first input argument shall be of the operator record class A.
For an operator record class there shall not exist any call that lead to multiple matches in (2) above.
[How to verify this is not specified.]
Let denote a binary operator and consider an expression a b where a is an instance or array of instances of class A and b is an instance or array of instances of class B.
If A and B are predefined types of such, then the corresponding built-in operation is performed.
Otherwise, if there exists exactly one function in the union of A. and B. such that (a, b) is a valid match for the function , then a b is evaluated using this function. It is an error, if multiple functions match. If A is not an operator record class, A. is seen as the empty set, and similarly for B.
[Having a union of the operators ensures that if A and B are the same, each function only appears once.]
Otherwise, consider the set given by in A. and an operator record class C (different from B) with a constructor, , such that C.’constructor’.(b) is a valid match, and f(a, C.’constructor’.(b)) is a valid match; and another set given by in B. and an operator record class D (different from A) with a constructor, , such that D.’constructor’.(a) is a valid match and (D.’constructor’.(a), b) is a valid match. If the sum of the sizes of these sets is one this gives the unique match. If the sum of the sizes is larger than one it is an error.
[Informally, this means: If there is no direct match of a b, then it is tried to find a direct match by automatic type casts of a or b, by converting either a or b to the needed type using an appropriate constructor function from one of the operator record classes used as arguments of the overloaded op functions. Example using the Complex-definition below:
]
Otherwise, if a or b is an array expression, then the expression is conceptually evaluated according to the rules of section 10.6 with the following exceptions concerning section 10.6.4:
* should be left undefined.
[The scalar product of table 10.9 does not generalize to the expected linear and conjugate linear scalar product of complex numbers.]
* should be left undefined.
[The corresponding definition of table 10.9 does not generalize to complex numbers in the expected way.]
If the inner dimension for * or * is zero, this uses the overloaded ’0’ operator of the result array element type. If the operator ’0’ is not defined for that class it is an error if the inner dimension is zero.
[For array multiplication it is assumed that the scalar elements form a non-commutative ring that does not necessarily have a multiplicative identity.]
Otherwise the expression is erroneous.
For an element-wise operator, a .op b, items 1, 4, and 5 are used; e.g. the operator .+ will always be defined in terms of ’+’.
Restrictions:
A function is allowed for a binary operator if and only if it has at least two inputs; at least one of which is of the operator record class, and the first two inputs shall not have default values, and all inputs after the first two must have default values.
For an operator record class there shall not exist any (potential) call that lead to multiple matches in (2) above.
Let denote a unary operator and consider an expression a where a is an instance or array of instances of class A. Then a is evaluated in the following way.
If A is a predefined type, then the corresponding built-in operation is performed.
If A is an operator record class and there exists a unique function in A. such that A..(a) is a valid match, then a is evaluated to A..(a). It is an error, if there are multiple valid matches.
Otherwise, if a is an array expression, then the expression is conceptually evaluated according to the rules of section 10.6.
Otherwise the expression is erroneous.
Restrictions:
A function is allowed for a unary operator if and only if it has least one input; and the first input is of the record type (or suitable arrays of such) and does not have a default value, and all inputs after the first one must have default values.
For an operator record class there shall not exist any (potential) call that lead to multiple matches in (2) above.
A binary and/or unary operator-class may only contain functions that are allowed for this binary and/or unary operator-class; and in case of ’-’ it is the union of these sets, since it may define both a unary (negation) and binary (subtraction) operator.
[Example: The rules in the previous subsections are demonstrated at hand of a record class to work conveniently with complex numbers:
How overloaded operators can be symbolically processed. Example:
Due to inlining of functions, the equation for c is transformed to:
or
These equations can be symbolically processed as other equations.
Complex can be used in a connector:
The two connect-equations result in the following connection equations:
The restrictions on extends are intended to avoid combining two variants inheriting from the same operator record, but with possibly different operations; thus ComplexVoltage and ComplexCurrent still use the operations from Complex. The restriction that it is not legal to extend from any of its enclosing scopes implies that:
]