From c6e314f72a9f7ad4062c5f538fb9aa9007ee47fe Mon Sep 17 00:00:00 2001 From: HOS Date: Thu, 18 Dec 2025 11:52:22 +0100 Subject: [PATCH 1/6] Update based on comment. --- RationaleMCP/0027/ReadMe.md | 77 ++++++++++++++++++++++++++++++++++--- 1 file changed, 72 insertions(+), 5 deletions(-) diff --git a/RationaleMCP/0027/ReadMe.md b/RationaleMCP/0027/ReadMe.md index 6d604d515..6687e74fc 100644 --- a/RationaleMCP/0027/ReadMe.md +++ b/RationaleMCP/0027/ReadMe.md @@ -1,5 +1,5 @@ # Modelica Change Proposal MCP-0027
Units of Literal Constants -Francesco Casella, Henrik Tidefelt +Francesco Casella, Henrik Tidefelt, Hans Olsson **(In Development)** @@ -11,24 +11,91 @@ The problem with undefined unit is that it gets in the way of carrying out check | Date | Description | | --- | --- | | 2022-10-04 | Henrik Tidefelt. Filling this document with initial content. | +| 2025-12-18 | Hans Olsson, simple proposal https://github.com/modelica/ModelicaSpecification/issues/2127#issuecomment-349162852 | ## Contributor License Agreement All authors of this MCP or their organizations have signed the "Modelica Contributor License Agreement". ## Rationale -FIXME +The basic rationale for using units is to reduce the risk of errors. + +For the specific rules the rationale is that treating literals as having unit `"1"` in multiplicative contexts will catch many simple errors, without requriring excessive changes. +Thus e.g., `SI.Temperature T=293.15` and `SI.Enthalphy h=Medium.h_pT(1e5, 298.15)` are allowed. +In order to handle connectors in a good way, `zeros(n)` is treated the same as literals, allowing `a.f+b.f=zeros(3);` and `a.f=f0*zeros(3);`, but `a.f=T0*zeros(3);` (when `a.f` is a force and `T0` a temperature) is detected as an error. + +The rationale for only giving the rules for variables instead of providing a specific implementation is to make the expectation clear for library authors. +And at the same time allow tool vendors to implement the rules to varying degrees (there is sufficient experience with the prototypes to ensure that it will work). + +Many libraries, including the Modelica Standard Library already largely follow this rule. ## Backwards Compatibility As current Modelica doesn't clearly reject some models with non-sensical combination of units, this MCP will break backwards compatibility by turning at least some of these invalid. +It is thus necessary to have the possibility to disable the rules for specific libraries (and specific equations in other libraries) to ease the adoption. + ## Tool Implementation -None, so far. +For scalars implemented in some version of Wolfram System Modeler (to be given). +Almost fully implemented on a flag in Dymola 2026x, and 3D Experience platform. ### Experience with Prototype -N/A +Generally it correctly finds some issues in libraries, but some libraries have systematic issues. +E.g., the buildings library uses a large number of multiplicative literals without unit for converting between different time and power units. ## Required Patents To the best of our knowledge, there are no patents that would conflict with the incorporation of this MCP. ## References -(None.) +https://doi.org/10.3384/ecp21817 and its references. + +## Detailed rules + +Unit restrictions for variables +- Each scalar variable and array element may only have one unit during the simulation. +- Arrays may have heterogenous units. Notes: + - This is for each instance of the variable, so different component instances and function calls (of the same model/function) may have different units. + - This applies after evaluating evaluable parameters. + - The s-parametrization needed for diodes and friction requires special work-arounds in models. + +General rules + +- Expressions (including equations, binding equations, and start values) must be unit consistent, except for listed exceptions, and can be used to infer units. +- If a variable has a non-empty unit-attribute that is the unit of the variable. The unit-attributes should preferable be in base SI-units. +- Variables that are declared without (non-empty) unit-attribute have unspecified unit, which may be inferred if there is a unique unit that makes the expressions unit consistent. + +Detailed default rules: + +- Literals without unit and zeros() are treated as empty unit except in multiplicative context (multiplication and division operators) where it has multiplicative-unit with the following rules: + - If both operands have multiplicative-unit the result has multiplicative-unit. + - If one operand has multiplicative-unit and the other not, the multiplicative-unit decays to unit `"1"`. +- If a constant is declared without unit, and with a binding equation that lacks units (even after inference) the constant is treated as empty unit. (This is primarily for package constants, where we don't want to infer a unit for `pi` and use it at unrelated places; but that also applies in models.) +- An expression having empty unit will match any constraint, and inference will not give it a unit. +- The rules for operands are fairly logical, but see appendix A in https://doi.org/10.3384/ecp21817 for the details. + +## Notes + +These are just rules for models, and doesn't require tools to diagnose all issues in models. + +Arrays with heterogenous units are somewhat rare but needed for state-space forms etc, and for some connectors in the electrical library. + +The rules are compatible with: +- The traditional unit inference in Dymola (Mattsson&Elmqvist https://modelica.org/events/conference2008/sessions/session1a2.pdf ) +- Hindley-Milner for scalars (https://github.com/modelica/ModelicaSpecification/pull/3491) +- The advanced combination(s) thereof in https://doi.org/10.3384/ecp21817 + +They are seen as different quality-of-implementations, but we could recommend a minimum for tools. + +It says: +- "default rules" to allow allow stricter or less strict variants, e.g., as described in https://github.com/modelica/ModelicaSpecification/issues/3690 +- "except for the listed exceptions" to allow exceptions for specific equations etc https://github.com/modelica/ModelicaSpecification/issues/3690#issuecomment-2866443687 +- "multiplicative context", but it is for both multiplication and division (the division explains why the multiplicative-unit decays to `"1"` instead of just using the other one). + +Treating the empty unit-attribute as unspecified is needed, since it is the default - but it normally doesn't make sense to explicitly give it for a variable declaration. + +Specific exceptions for equations, and libraries, should preferably be added to the proposal. + +The restriction that variables only having one unit could be violated in different ways in models: +- Temporaries in algorithms in functions (and even models) may be re-used to store expressions with different units. +- The s-parametrization is an example of a variable that switches e.g., from voltage to current. + +For s-parametrization one solution is to divide out the unit and generate an expression with unit `"1"` and store that. + From 0585394f691ef4d4f36073d7a5b1f74fe36a8cee Mon Sep 17 00:00:00 2001 From: HOS Date: Wed, 7 Jan 2026 17:26:49 +0100 Subject: [PATCH 2/6] Restructure and explain further. --- RationaleMCP/0027/ReadMe.md | 55 ++----------------------------------- 1 file changed, 3 insertions(+), 52 deletions(-) diff --git a/RationaleMCP/0027/ReadMe.md b/RationaleMCP/0027/ReadMe.md index 6687e74fc..1167b6b49 100644 --- a/RationaleMCP/0027/ReadMe.md +++ b/RationaleMCP/0027/ReadMe.md @@ -12,6 +12,7 @@ The problem with undefined unit is that it gets in the way of carrying out check | --- | --- | | 2022-10-04 | Henrik Tidefelt. Filling this document with initial content. | | 2025-12-18 | Hans Olsson, simple proposal https://github.com/modelica/ModelicaSpecification/issues/2127#issuecomment-349162852 | +| 2026-01-07 | Hans Olsson, improved - based on feedback | ## Contributor License Agreement All authors of this MCP or their organizations have signed the "Modelica Contributor License Agreement". @@ -44,58 +45,8 @@ E.g., the buildings library uses a large number of multiplicative literals witho ## Required Patents To the best of our knowledge, there are no patents that would conflict with the incorporation of this MCP. -## References -https://doi.org/10.3384/ecp21817 and its references. +## Details -## Detailed rules +[Design details](design.md) -Unit restrictions for variables -- Each scalar variable and array element may only have one unit during the simulation. -- Arrays may have heterogenous units. Notes: - - This is for each instance of the variable, so different component instances and function calls (of the same model/function) may have different units. - - This applies after evaluating evaluable parameters. - - The s-parametrization needed for diodes and friction requires special work-arounds in models. - -General rules - -- Expressions (including equations, binding equations, and start values) must be unit consistent, except for listed exceptions, and can be used to infer units. -- If a variable has a non-empty unit-attribute that is the unit of the variable. The unit-attributes should preferable be in base SI-units. -- Variables that are declared without (non-empty) unit-attribute have unspecified unit, which may be inferred if there is a unique unit that makes the expressions unit consistent. - -Detailed default rules: - -- Literals without unit and zeros() are treated as empty unit except in multiplicative context (multiplication and division operators) where it has multiplicative-unit with the following rules: - - If both operands have multiplicative-unit the result has multiplicative-unit. - - If one operand has multiplicative-unit and the other not, the multiplicative-unit decays to unit `"1"`. -- If a constant is declared without unit, and with a binding equation that lacks units (even after inference) the constant is treated as empty unit. (This is primarily for package constants, where we don't want to infer a unit for `pi` and use it at unrelated places; but that also applies in models.) -- An expression having empty unit will match any constraint, and inference will not give it a unit. -- The rules for operands are fairly logical, but see appendix A in https://doi.org/10.3384/ecp21817 for the details. - -## Notes - -These are just rules for models, and doesn't require tools to diagnose all issues in models. - -Arrays with heterogenous units are somewhat rare but needed for state-space forms etc, and for some connectors in the electrical library. - -The rules are compatible with: -- The traditional unit inference in Dymola (Mattsson&Elmqvist https://modelica.org/events/conference2008/sessions/session1a2.pdf ) -- Hindley-Milner for scalars (https://github.com/modelica/ModelicaSpecification/pull/3491) -- The advanced combination(s) thereof in https://doi.org/10.3384/ecp21817 - -They are seen as different quality-of-implementations, but we could recommend a minimum for tools. - -It says: -- "default rules" to allow allow stricter or less strict variants, e.g., as described in https://github.com/modelica/ModelicaSpecification/issues/3690 -- "except for the listed exceptions" to allow exceptions for specific equations etc https://github.com/modelica/ModelicaSpecification/issues/3690#issuecomment-2866443687 -- "multiplicative context", but it is for both multiplication and division (the division explains why the multiplicative-unit decays to `"1"` instead of just using the other one). - -Treating the empty unit-attribute as unspecified is needed, since it is the default - but it normally doesn't make sense to explicitly give it for a variable declaration. - -Specific exceptions for equations, and libraries, should preferably be added to the proposal. - -The restriction that variables only having one unit could be violated in different ways in models: -- Temporaries in algorithms in functions (and even models) may be re-used to store expressions with different units. -- The s-parametrization is an example of a variable that switches e.g., from voltage to current. - -For s-parametrization one solution is to divide out the unit and generate an expression with unit `"1"` and store that. From 6211947c920a6950cd4a43eceea9d091e692849d Mon Sep 17 00:00:00 2001 From: HOS Date: Wed, 7 Jan 2026 17:27:24 +0100 Subject: [PATCH 3/6] Restructure and explain further. --- RationaleMCP/0027/design.md | 109 ++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 RationaleMCP/0027/design.md diff --git a/RationaleMCP/0027/design.md b/RationaleMCP/0027/design.md new file mode 100644 index 000000000..3a73c945c --- /dev/null +++ b/RationaleMCP/0027/design.md @@ -0,0 +1,109 @@ +## References +https://doi.org/10.3384/ecp21817 and its references. + +## Detailed rules + +Unit restrictions for variables +- Each scalar variable and array element may only have one unit during the simulation. +- Arrays may have heterogenous units. Notes: + - This is for each instance of the variable, so different component instances and function calls (of the same model/function) may have different units. + - This applies for each value of the [evaluable parameters](#evaluable-parameter). + - The s-parametrization needed for diodes and friction requires special work-arounds in models. + +General rules + +- Expressions (including equations, binding equations, and start values) must be unit consistent, except for listed exceptions, and can be used to infer units. +- If a variable has a non-empty unit-attribute that is the unit of the variable. The unit-attributes should preferable be in base SI-units. +- Variables that are declared without unit-attribute (or with empty one) have unspecified unit, which may be inferred if there is a unique unit that makes the expressions unit consistent. + +Detailed default rules: + +- Literals without unit and zeros() are treated as empty unit except in multiplicative context (multiplication and division operators) where it has multiplicative-unit with the following rules: + - If both operands have multiplicative-unit the result has multiplicative-unit. + - If one operand has multiplicative-unit and the other not, the multiplicative-unit decays to unit `"1"`. + - There's a future refinement for the literal 0 (both real and integer) and `zeros()` in arrays see [advanced arrays](#advanced-array-handling) for details. +- If a constant is declared without unit, and with a binding equation that lacks units (even after inference) the constant is treated as empty unit. (This is primarily for package constants, where we don't want to infer a unit for `pi` and use it at unrelated places; but that also applies in models.) +- An expression having empty unit will match any constraint, and inference will not give it a unit. +- The rules for operands are fairly logical, but see appendix A in https://doi.org/10.3384/ecp21817 for the details. + +## Arrays + +Arrays with heterogenous units are somewhat rare but needed for state-space forms etc, and for some connectors in the electrical library. + +Without scalarizing arrays there are a number of options: +- Ignore units for arrays. +- Only infer units for elements, and arrays that are inferred/declared to be homogenous. (Proposed here.) +- Something more advanced. (Not proposed as it hasn't been tested.) + +This simple array handling implies that unit-handling is consistent between MultiBody mechanics and Rotational/Translational mechanics. + +### Advanced array handling + +The advanced array handling is not included yet as part of the proposal as it is not fully clear and not test-implemented, even if models ideally should fulfill something along these lines. + +It is included in this document, because there are some non-trivial issues if tools were to support this. +Based on the experience with existing models it will likely infer units for a number of variables, but find few, if any, new errors. + +One considerations is whether the arrays are just arrays or have more structure. +Many (likely most) arrays are used as vectors, matrices, etc in the linear algebra sense, but not all. +E.g., Modelica.Blocks.Tables.CombiTable2Ds has a table where the first row and column effectively has different units from the rest of the table. +It seems that tools could identify whether a 2d-array is used as a matrix (or even bilinear form) based on the equations, i.e. `A*x` imply that `A` is a matrix, and `x*A*x` that it is a bilinear form. + +The changes needed to support a more advanced array handling would be something like: +- Arrays built using `cat`, `[,;]` should (at least in some cases) support heterogenous inputs giving heterogenous unit-results, replacing parts of appendix A of https://doi.org/10.3384/ecp21817 +- Literal 0 (both real and integer) and `zeros()` inside arrays should be treated as the empty unit, and not decay to unit `"1"` as other literals without unit. +- If something is used as a matrix its units are restricted (it must be representable as an outer product); as noted above. +- Potentially more. + +The reason for the second rule can be seen from considering structured matrices in equations. +E.g., a simple state-space system without direct terms: +`[der(x);y]=[A,B;C,zeros(...)]*[x;u]` +(and correspondingly with a literal 0 if it has a single input and a single output). +In text books those zeros are often omitted, but that is not allowed in Modelica. + +Basically the zeros are seen as structural zeros and one would expand it as `y=C*x` (not `y=C*x+zeros(...)*u`), imposing no unit-constraint between `u` and `y`. +In contrast for `f1+f2=0*f1` it seems natural to have unit `"1"` for the literal. +And if one writes `[der(x);y]=[A,B;C,1]*[x;u]` then `u` and `y` should be scalars (or vectors of length 1) that both have the same unit. + +This also apply to the literal zeros in `diagonal()` and `skew()`, they are seen as having empty unit - not impacting the result. + +## Evaluable parameter + +The reason it applies for each value of the evaluable parameters is to make it sufficiently general to handle even models where evaluable parameters switch between different unit-configurations. +If the evaluable parameter has been evaluated this is fairly unproblematic. + +The issue is if it has not been evaluated. +Tools should avoid having the unit-handling (except for the unit-attribute) cause evaluation of evaluable parameters. + +In many cases it does not matter, e.g., an evaluable mass-parameter will have unit `"kg"` regardless of its value. + +When it does matter (in particular for boolean conditions) it's a quality-of-implementation issue for tools to handle it in a good way, and possibilities include: +- Ignore those constraints. (Not good.) +- Temporarily evaluate the evaluable parameters, without impacting the translation. (This will only check the model for one set of values.) +- Treat them as conditional constraint in some advanced way. (Should check conditional constraint in https://github.com/modelica/ModelicaSpecification/pull/3491 ) + +## Notes + +These are just rules for models, and doesn't require tools to diagnose all issues in models. + +The rules are compatible with: +- The traditional unit inference in Dymola (Mattsson&Elmqvist https://modelica.org/events/conference2008/sessions/session1a2.pdf ) +- Hindley-Milner for scalars (https://github.com/modelica/ModelicaSpecification/pull/3491) +- The advanced combination(s) thereof in https://doi.org/10.3384/ecp21817 + +They are seen as different quality-of-implementations, but we could recommend a minimum for tools. + +It says: +- "default rules" to allow allow stricter or less strict variants, e.g., as described in https://github.com/modelica/ModelicaSpecification/issues/3690 +- "except for the listed exceptions" to allow exceptions for specific equations etc https://github.com/modelica/ModelicaSpecification/issues/3690#issuecomment-2866443687 +- "multiplicative context", but it is for both multiplication and division (the division explains why the multiplicative-unit decays to `"1"` instead of just using the other one). + +Treating the empty unit-attribute as unspecified is needed, since it is the default - but it normally doesn't make sense to explicitly give `unit=""` for a variable declaration. + +Specific exceptions for equations, and libraries, should preferably be added to the proposal. + +The restriction that variables only having one unit could be violated in different ways in models: +- Temporaries in algorithms in functions (and even models) may be re-used to store expressions with different units. +- The s-parametrization is an example of a variable that switches e.g., from voltage to current. + +For s-parametrization one solution is to divide out the unit and generate an expression with unit `"1"` and store that. \ No newline at end of file From ed5eb730c4ffcb3d04450b3a900605f15d326a27 Mon Sep 17 00:00:00 2001 From: HOS Date: Wed, 7 Jan 2026 17:29:14 +0100 Subject: [PATCH 4/6] AddMore --- RationaleMCP/0027/design.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RationaleMCP/0027/design.md b/RationaleMCP/0027/design.md index 3a73c945c..691d87366 100644 --- a/RationaleMCP/0027/design.md +++ b/RationaleMCP/0027/design.md @@ -62,7 +62,7 @@ E.g., a simple state-space system without direct terms: In text books those zeros are often omitted, but that is not allowed in Modelica. Basically the zeros are seen as structural zeros and one would expand it as `y=C*x` (not `y=C*x+zeros(...)*u`), imposing no unit-constraint between `u` and `y`. -In contrast for `f1+f2=0*f1` it seems natural to have unit `"1"` for the literal. +In contrast for `f1+f2=0*f1` it seems natural to have unit `"1"` for the literal, even if it is unlikely that someone makes a mistake for that equation. And if one writes `[der(x);y]=[A,B;C,1]*[x;u]` then `u` and `y` should be scalars (or vectors of length 1) that both have the same unit. This also apply to the literal zeros in `diagonal()` and `skew()`, they are seen as having empty unit - not impacting the result. From 52af186cc72826cea461f5629a530760479c75e5 Mon Sep 17 00:00:00 2001 From: HOS Date: Thu, 8 Jan 2026 11:19:34 +0100 Subject: [PATCH 5/6] ExplainVaryingDegrees --- RationaleMCP/0027/ReadMe.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/RationaleMCP/0027/ReadMe.md b/RationaleMCP/0027/ReadMe.md index 1167b6b49..59ca8d831 100644 --- a/RationaleMCP/0027/ReadMe.md +++ b/RationaleMCP/0027/ReadMe.md @@ -27,6 +27,9 @@ In order to handle connectors in a good way, `zeros(n)` is treated the same as l The rationale for only giving the rules for variables instead of providing a specific implementation is to make the expectation clear for library authors. And at the same time allow tool vendors to implement the rules to varying degrees (there is sufficient experience with the prototypes to ensure that it will work). +The rationale for considering implementing the rules to varying degrees, and even considering rules beyond the proposed ones is to ensure that they are consistent. +That means that rules are designed such that a model unit-consistent with the most restrictive rules will also be unit-consistent with less restrictive rules with a consistent subset of inferred units. + Many libraries, including the Modelica Standard Library already largely follow this rule. ## Backwards Compatibility From 639b72a7da7a9879cb9d89a64d0b3dbee600eca3 Mon Sep 17 00:00:00 2001 From: HOS Date: Thu, 8 Jan 2026 13:14:18 +0100 Subject: [PATCH 6/6] Clarified --- RationaleMCP/0027/design.md | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/RationaleMCP/0027/design.md b/RationaleMCP/0027/design.md index 691d87366..0d552e89e 100644 --- a/RationaleMCP/0027/design.md +++ b/RationaleMCP/0027/design.md @@ -45,7 +45,7 @@ It is included in this document, because there are some non-trivial issues if to Based on the experience with existing models it will likely infer units for a number of variables, but find few, if any, new errors. One considerations is whether the arrays are just arrays or have more structure. -Many (likely most) arrays are used as vectors, matrices, etc in the linear algebra sense, but not all. +Many (likely most) arrays are used as vectors, matrices, etc in the linear algebra sense, but not all. E.g., Modelica.Blocks.Tables.CombiTable2Ds has a table where the first row and column effectively has different units from the rest of the table. It seems that tools could identify whether a 2d-array is used as a matrix (or even bilinear form) based on the equations, i.e. `A*x` imply that `A` is a matrix, and `x*A*x` that it is a bilinear form. @@ -70,19 +70,31 @@ This also apply to the literal zeros in `diagonal()` and `skew()`, they are seen ## Evaluable parameter The reason it applies for each value of the evaluable parameters is to make it sufficiently general to handle even models where evaluable parameters switch between different unit-configurations. -If the evaluable parameter has been evaluated this is fairly unproblematic. +In practice the handling will depend on whether the parameter has been evaluated or not. -The issue is if it has not been evaluated. +### Evaluated evaluable parameter + +This is the simpler case, but still requires care, since expanding and evaluating expressions is normally mixed in tools. +For practical reasons one wants to perform the unit check on the original non-expanded expressions, where the evaluable parameters were not yet evaluated. + +This can be handled in various ways: +- Simplifying the original expressions based on the values of evaluable parameters. (In some sense this will be a form of double-work.) +- Having conditional constraints as in https://github.com/modelica/ModelicaSpecification/pull/3491. + +### Non-evaluated evaluable parameter + +This is a particular concern. Tools should avoid having the unit-handling (except for the unit-attribute) cause evaluation of evaluable parameters. +Note that it doesn't suffice to separate parameters in evaluated and non-evaluated as different tools may evaluate different evaluable parameters with different result for unit consistency. -In many cases it does not matter, e.g., an evaluable mass-parameter will have unit `"kg"` regardless of its value. +However, in many cases it does not matter, e.g., an evaluable mass-parameter will have unit `"kg"` regardless of its value, and many boolean evaluable conditions don't influence the units. When it does matter (in particular for boolean conditions) it's a quality-of-implementation issue for tools to handle it in a good way, and possibilities include: -- Ignore those constraints. (Not good.) +- Ignore the unit-constraints in such expressions. (Not good.) - Temporarily evaluate the evaluable parameters, without impacting the translation. (This will only check the model for one set of values.) -- Treat them as conditional constraint in some advanced way. (Should check conditional constraint in https://github.com/modelica/ModelicaSpecification/pull/3491 ) +- Treat them as conditional constraint in some advanced way. (This is more advanced that the conditional constraints in https://github.com/modelica/ModelicaSpecification/pull/3491 ) -## Notes +## Varying quality-of-implementation These are just rules for models, and doesn't require tools to diagnose all issues in models. @@ -93,12 +105,21 @@ The rules are compatible with: They are seen as different quality-of-implementations, but we could recommend a minimum for tools. +The unit-handling doesn't prioritize different operands (in contrast to selecting initial conditions and states), since that might give different results for the different levels for unit-consistent models. +For unit-inconsistent models it *possible* that using different set of rules will infer different units without detecting errors; the solution is to improve the quality-of-implementation to detect the underlying error in that case. +Additionally, this only occurs the different rules are not sub-sets of each other, so having a common understanding of hieararchy of the rules may reduce this risk. + +## Notes + +The rules for literals break the substitution principles for equality, so even if `A=[1,2;3,4]` it doesn't follow that `A` and `[1,2;3,4]` behave the same in terms of units. + It says: - "default rules" to allow allow stricter or less strict variants, e.g., as described in https://github.com/modelica/ModelicaSpecification/issues/3690 - "except for the listed exceptions" to allow exceptions for specific equations etc https://github.com/modelica/ModelicaSpecification/issues/3690#issuecomment-2866443687 - "multiplicative context", but it is for both multiplication and division (the division explains why the multiplicative-unit decays to `"1"` instead of just using the other one). Treating the empty unit-attribute as unspecified is needed, since it is the default - but it normally doesn't make sense to explicitly give `unit=""` for a variable declaration. +If the goal is just to remove an existing unit an alternative is `unit=break`. Specific exceptions for equations, and libraries, should preferably be added to the proposal.