Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MCP-0027 Units of Literal Constants #2127

Open
modelica-trac-importer opened this issue Nov 4, 2018 · 91 comments
Open

MCP-0027 Units of Literal Constants #2127

modelica-trac-importer opened this issue Nov 4, 2018 · 91 comments
Labels
bug Something isn't working MCP Generic MCP label (prefer specific MCP label for grouping of issues belonging to the same MCP)
Milestone

Comments

@modelica-trac-importer
Copy link
Collaborator

Reported by fcasella on 11 Dec 2016 19:03 UTC
I have added a proposal for the clarification of the units of literal constants, which is currently unspecified in Modelica 3.3r1. I hope there's still time to have it in Modelica 3.4, the proposal is very simple and the evaluation process should be straightforward.

Documents can be accessed directly here: Overview and Specification Changes.


Migrated-From: https://trac.modelica.org/Modelica/ticket/2127

@modelica-trac-importer modelica-trac-importer added bug Something isn't working MCP Generic MCP label (prefer specific MCP label for grouping of issues belonging to the same MCP) labels Nov 4, 2018
@modelica-trac-importer
Copy link
Collaborator Author

Comment by fcasella on 14 Dec 2016 09:49 UTC
Discussion at the 92nd Design Meeting.

Conclusions

  • only specify when the unit is "1"

Make sure it works with

  • if expressions
  • relations
  • ideal diode model in MSL
  • degC to K conversion in MSL

@modelica-trac-importer
Copy link
Collaborator Author

Comment by fcasella on 19 May 2017 14:12 UTC
Updated the MCP text on SVN (r9715) at the 94th Design Meeting in Prague

@modelica-trac-importer
Copy link
Collaborator Author

Comment by stefanv on 20 May 2017 07:43 UTC
One issue that came up at the meeting yesterday was the need to define a large number of unit symbols, so expressions such as v = 2 * ohm * i can be written. Instead of defining these symbols, I'd like to propose adding a new built-in function instead, defined by the following pseudo-Modelica:

function Unit
    input String unit;
    output Real y(unit=unit) := 1;
end Unit;

After writing the above, I'm not sure this even needs to be built-in, because I think the above might already be valid Modelica.

Then, an expression like the one above could be written as v = 2 * Unit("ohm") * i. This makes it clear what is going on, and doesn't necessitate the introduction of a huge number of constants, many of which would have simple names like m that are likely to clash with variable names.

@modelica-trac-importer
Copy link
Collaborator Author

Comment by hansolsson on 22 May 2017 10:22 UTC
Replying to [comment:3 Stefan Vorkoetter]:

One issue that came up at the meeting yesterday was the need to define a large number of unit symbols, so expressions such as v = 2 * ohm * i can be written. Instead of defining these symbols, I'd like to propose adding a new built-in function instead, defined by the following pseudo-Modelica:

function Unit
    input String unit;
    output Real y(unit=unit) := 1;
end Unit;

After writing the above, I'm not sure this even needs to be built-in, because I think the above might already be valid Modelica.

Then, an expression like the one above could be written as v = 2 * Unit("ohm") * i. This makes it clear what is going on, and doesn't necessitate the introduction of a huge number of constants, many of which would have simple names like m that are likely to clash with variable names.

I agree that this seems like a better solution and might not need anything built-in.
It also seems to work better with more complicated units, e.g. "Ohm.m" (Resistivity) - rad/s2" (AngularAcceleration), and "J/(kg.K)" (SpecificEntropy).

However, it might be that it is clearer to write InUnit(2, "Ohm") than 2*Unit("Ohm") (except it needs a better name).

A somewhat related issue is to construct units for blocks (#921) - think of building this expression with block-diagrams with units. Previously I thought that using unit-names directly for that was more problematic than using the SIunits-types; but if units are more intuitive for equations it might be that they are more intuitive there as well and it is more a matter of making that even more convenient.
(The risk of errors is mitigated by the fact that the units are checked; people are about as likely to misspell enthalpy as "J/(kg.K)" - and both errors can be detected).

@modelica-trac-importer
Copy link
Collaborator Author

Comment by stefanv on 22 May 2017 14:30 UTC
I guess it's a matter of preference, but I prefer 2 * Unit("ohm"). Another possibility is to introduce a new syntax, such as 2 * "ohm", which is even simpler to read (the grammar probably allows that already; it just has no meaning at this point).

Also, making use of * (and /) makes it possible to write inverse units in a natural way, such as velocity := 3 * distance / Unit("s").

@modelica-trac-importer
Copy link
Collaborator Author

Comment by cbuerger on 22 May 2017 15:12 UTC
I do not feel comfortable with any of the expression-based notations like 2 * Unit("ohm") or 2 * "ohm" and much prefer a special built-in function that takes a literal and a unit specification like Unit(2, "ohm").

My rational is, that an expression-based approach requires special checks that are in their nature syntactical but must be realised and specifified on a semantic level. Consider the following examples; are they valid and if not what are the exact restrictions?:

  • Unit("ohm") * 2
  • 2 * Unit("m") * Unit("m") or 2 * Unit("m")^2
  • 2 * f() whereas f returns Unit("ohm")
  • 2 + Unit("ohm")
  • 2 * Unit(f()) with f returning a string
  • 2 * f() with f returning the string "ohm" (is that a type error or a proper unit specification for the literal 2 considering the proposed 2 * "ohm" notation)

@modelica-trac-importer
Copy link
Collaborator Author

Comment by fcasella on 22 May 2017 16:04 UTC
Replying to [comment:6 Christoff Bürger]:

I guess what is currently in the MCP i.e., adding constants with units to Modelica.SIUnits and using them in expressions, implicitly addresses these concerns, using syntax and semantics which are already defined in the specification as of today.

When defining the constants, we should try to follow authoritative recommendations such as this, or better ones if you know them. That is outside the scope of the MCP.

@modelica-trac-importer
Copy link
Collaborator Author

Comment by stefanv on 22 May 2017 17:07 UTC
Replying to [comment:6 Christoff Bürger]:

I do not feel comfortable with any of the expression-based notations like 2 * Unit("ohm") or 2 * "ohm" and much prefer a special built-in function that takes a literal and a unit specification like Unit(2, "ohm").

My rational is, that an expression-based approach requires special checks that are in their nature syntactical but must be realised and specifified on a semantic level.

No special checks are required at all, beyond any unit checking already done by the code. For example, my proposed function Unit simply returns the value 1.0 with the specified unit. Other than implementing the Unit function, no further changes are required in the tool. All of your examples except the last are well-defined under this scheme (the last is probably a good reason not to use the 2 * "ohm" scheme).

@modelica-trac-importer
Copy link
Collaborator Author

Comment by stefanv on 22 May 2017 17:10 UTC
Replying to [comment:7 Francesco Casella]:

Replying to [comment:6 Christoff Bürger]:

I guess what is currently in the MCP i.e., adding constants with units to Modelica.SIUnits and using them in expressions, implicitly addresses these concerns, using syntax and semantics which are already defined in the specification as of today.

And as I have pointed out, what I suggest also does, and doesn't require the introduction of any new symbols (except for Unit), and thus also no need to choose these symbols (we just use the existing unit strings as the argument to Unit).

@modelica-trac-importer
Copy link
Collaborator Author

Comment by anonymous on 23 May 2017 11:38 UTC
Replying to [comment:8 Stefan Vorkoetter]:

Replying to [comment:6 Christoff Bürger]:

I do not feel comfortable with any of the expression-based notations like 2 * Unit("ohm") or 2 * "ohm" and much prefer a special built-in function that takes a literal and a unit specification like Unit(2, "ohm").

My rational is, that an expression-based approach requires special checks that are in their nature syntactical but must be realised and specifified on a semantic level.

No special checks are required at all, beyond any unit checking already done by the code. For example, my proposed function Unit simply returns the value 1.0 with the specified unit. Other than implementing the Unit function, no further changes are required in the tool. All of your examples except the last are well-defined under this scheme (the last is probably a good reason not to use the 2 * "ohm" scheme).

Given that Unit("ohm") simply returns the value 1.0 with the specified unit, what is the semantic of my 4th example 2 + Unit("ohm"). Should the value of that expression be 3 ohm or should it be an error?

Remember, that we do not enforce units everywhere, but just check that if units are given the equation system is well-typed (to which end we automatically derive units). That is why I am cautious with introducing a built-in function that just returns a unit; we have no such thing as an value-less expression with just a unit in the language so far. Using a two argument built-in function that combines value and unit makes it more explicit and less fragile to unexpected unit derivations and value computation combinations.

@modelica-trac-importer
Copy link
Collaborator Author

Comment by cbuerger on 23 May 2017 11:40 UTC
Above post was me; forgot to login.

@modelica-trac-importer
Copy link
Collaborator Author

Comment by stefanv on 23 May 2017 12:13 UTC
Replying to [comment:10 anonymous]:

Given that Unit("ohm") simply returns the value 1.0 with the specified unit, what is the semantic of my 4th example 2 + Unit("ohm"). Should the value of that expression be 3 ohm or should it be an error?

The semantics of 2 + Unit("ohm") are the identical to the semantics of the following that we can already write:

    constant Modelica.SIunits.Resistance R = 1;
equation
    x = 2 + R;

and also identical to writing 2 + Unit(1,"ohm") in the two-argument form you are preferring.

That is why I am cautious with introducing a built-in function that just returns a unit; we have no such thing as an value-less expression with just a unit in the language so far.

And with my proposal, we still won't. Unit("ohm") is not a "value-less expression with just a unit", it is 1 Ohm. It is equivalent to writing Unit(1,"ohm") in the two-argument form.

Using a two argument built-in function that combines value and unit makes it more explicit and less fragile to unexpected unit derivations and value computation combinations.

I disagree. It is semantically equivalent, but harder to read.

I'm not sure what you mean by "unexpected unit derivations". Doing unit arithmetic is a well understood problem. In the 1970s, there even existed a slide rule that could do this (i.e., it worked purely with units, not numbers).

@modelica-trac-importer
Copy link
Collaborator Author

Comment by fcasella on 23 May 2017 12:34 UTC
Replying to [comment:10 anonymous]:

Given that Unit("ohm") simply returns the value 1.0 with the specified unit, what is the semantic of my 4th example 2 + Unit("ohm"). Should the value of that expression be 3 ohm or should it be an error?

According to the text of the MCP, the constant 2 will have unit "1" and Unit("ohm") will have unit ohm, so a unit checker should report that this expression is dimensionally inconsistent. Whether this is a warning or an error is a tool issue, and may also depend on the settings.

@modelica-trac-importer
Copy link
Collaborator Author

Comment by hansolsson on 23 May 2017 13:11 UTC
Replying to [comment:7 Francesco Casella]:

Replying to [comment:6 Christoff Bürger]:

I guess what is currently in the MCP i.e., adding constants with units to Modelica.SIUnits and using them in expressions, implicitly addresses these concerns, using syntax and semantics which are already defined in the specification as of today.

When defining the constants, we should try to follow authoritative recommendations such as this, or better ones if you know them. That is outside the scope of the MCP.

That recommendation is a good guide, and not primarily about defining constants - but about how to use units in general - and I agree that we should follow it if possible.

Note in particular that 2*kg is not according to those recommendations - it is always 2 kg (both numbers and units are written in roman style - but variables in italics).

In particular recommendation 12 says:
It is clear to which unit symbol a numerical value belongs and which mathematical operation applies to the value of a quantity.

It seems that if we have something like Unit(2, "kg") that fulfills the requirement and it would be fairly simple to render equation y=Unit(2,"kg"); as y=2 kg (similarly as Dymola already generates a more "mathematical notation").

@modelica-trac-importer
Copy link
Collaborator Author

Comment by fcasella on 23 May 2017 13:41 UTC
Replying to [comment:14 Hans Olsson]:

When defining the constants, we should try to follow authoritative recommendations such as this, or better ones if you know them. That is outside the scope of the MCP.

That recommendation is a good guide, and not primarily about defining constants - but about how to use units in general - and I agree that we should follow it if possible.

Yeah, that's what I meant :)

Note in particular that 2*kg is not according to those recommendations - it is always 2 kg (both numbers and units are written in roman style - but variables in italics).

I think this is no big deal. In mathematical notation you would write v = sqrt(2gh) with no explicit multiplications, but in programming languages you always have to put the {*} sign explicitly. As I see it, 2 kg means 2 times a kilogram, and I don't see a problem if we have to make the "times" explicit.

Anyway, let me remind everyone that in its current form, this MCP is not really about how you write literal constants with units. To the contrary, it only specifies when a literal constant is actually a nondimensional number, so as to avoid bogus unit checking when such constants are involved in expressions and may end up being used as "unit slack variables".

I would recommend that we don't mix this issue up with how we can write 4 kg in a Modelica expression, which is also probably bad modelling style, as I'd define a constant with the proper unit to store that numerical value, and then use that instead of the literal constant, rather than hard-wire it in an expression. The suggestion about defining and using unit constants is in the non-normative part and I can actually remove it if it causes controversy. That won't change the proposal significantly.

@modelica-trac-importer
Copy link
Collaborator Author

Comment by hansolsson on 23 May 2017 14:48 UTC
Replying to [comment:15 Francesco Casella]:

Replying to [comment:14 Hans Olsson]:

Note in particular that 2*kg is not according to those recommendations - it is always 2 kg (both numbers and units are written in roman style - but variables in italics).

I think this is no big deal. In mathematical notation you would write v = sqrt(2gh) with no explicit multiplications, but in programming languages you always have to put the {*} sign explicitly. As I see it, 2 kg means 2 times a kilogram, and I don't see a problem if we have to make the "times" explicit.

The guides and recommendation make it clear that it is multiplication, but that the normal multiplication sign is not used.

Recommendation 15 says (NIST guide 7.2):
"There is a space between the numerical value and unit symbol, even when the value is used in an adjectival sense, except in the case of superscript units for plane angle."

Recommendation 5 says:
"A space or half-high dot is used to signify the multiplication of units" (in the other document it is described that a normal dot can be used as fallback - as we do in Modelica).

Note that they use "x" for multiplication of values, e.g. 1 Ci = 3.7 x 1010 Bq - i.e. not the same symbol used when multiplying units (see NIST guide 10.5.4 - https://www.nist.gov/pml/nist-guide-si-chapter-10-more-printing-and-using-symbols-and-numbers-scientific-and-technical#1054).

Note that they also make a minor difference between how "2" is written as part of "2 kg" and as a general number (10.5.1).

The main part here is that they don't have "kg" free-floating in expressions, it is always "2 kg" or similarly.

BTW - division is allowed on the other hand so both of the following are ok:
m=2 kg
m/kg=2
(Quite useful for tables.)

However, the proposal will not unit-check the one with division as I understand it.

@modelica-trac-importer
Copy link
Collaborator Author

Comment by hansolsson on 24 Oct 2017 12:20 UTC
Calling a function with a literal should be included in the list of exceptions.

E.g. if foo takes an argument of type Temperature then foo(293.15) is ok; we might view the call of the function as "assigning" to the input - but I believe it deserves its own item.
--
A different, but related topic is the unit for Reals without any specified unit.

Assuming that they have unit "1" works in some cases, e.g.
Modelica.Blocks.Sources.CombiTimeTable: nextTimeEventScaled
but also fails for some cases e.g. Modelica.Blocks.Sources.KinematicPTP: sdd_max (which has unit "1/s").

@henrikt-ma
Copy link
Collaborator

Bottom line: in general we can only perform "dimensional inference", but most definitely not "unit inference", as the above examples clearly demonstrate.

Do we have a consensus on everything I stated in this comment? Only then I believe we can start actually delving into the concrete MCP text.

I think you may have read too much into the presence of unit inference in #3257. In that proposal, unit inference is only allowed where there's one and only one obvious unit candidate for the inference. Hence, I don't see that any of the concerns you raise regarding unit inference would apply to my proposal.

Further, #3257 doesn't involve any "dimensional inference"; the very limited unit inference is considered sufficient.

@henrikt-ma
Copy link
Collaborator

If someone has time to check: what would happen to user libraries if rad was added as a base unit to the unit checker?

That would require a quite major change in Modelica.Mechanics - in particular for Rotational.

We currently have type MomentOfInertia Real(unit="kg.m2") and type Torque=Real(unit="N.m"), and for a rotational inertia energy=J*w^2 and J*a=tau. To me the unit for MomentOfInertia seems quite natural, so I don't see how they plan to handle that.

When this happens, isn't the solution to modify some of the equations by multiplication of a 1 with unit "rad" raised to a suitable power? Except that it involves a bit of work, I think the main drawback of such an approach is that formulas might end up not looking exactly like in the textbooks.

@mestinso
Copy link

We currently have type MomentOfInertia Real(unit="kg.m2") and type Torque=Real(unit="N.m"), and for a rotational inertia energy=J*w^2 and J*a=tau. To me the unit for MomentOfInertia seems quite natural, so I don't see how they plan to handle that.

Another paper and some relevant tables (same author as the previous material on angles):
https://arxiv.org/pdf/1409.2794.pdf

Screen Shot 2022-10-10 at 12 55 52 PM

Screen Shot 2022-10-10 at 11 42 48 AM

...maybe an issue with the centrifugal force?

I will say it feels more natural having the denominator of rad for torque. It is a little bothersome to me that torque has units of work. Rather in this framework it's the more intuitive work per unit rotation (or angle). In the same sense that for a linear force it's work per unit distance.

Sort of an interesting topic, but not clear if the juice is worth the squeeze here.

@HansOlsson
Copy link
Collaborator

When this happens, isn't the solution to modify some of the equations by multiplication of a 1 with unit "rad" raised to a suitable power?

The problem is that it is basically cheating - as soon as you allow formulas to have unitRad in them you have the lost the benefit of unit-checking - and you get things like "centrifugal force" having unit="N.rad" as if it were different from other forces.

@mestinso
Copy link

mestinso commented Oct 11, 2022

When this happens, isn't the solution to modify some of the equations by multiplication of a 1 with unit "rad" raised to a suitable power?

The problem is that it is basically cheating - as soon as you allow formulas to have unitRad in them you have the lost the benefit of unit-checking - and you get things like "centrifugal force" having unit="N.rad" as if it were different from other forces.

A minor note on the centrifugal force result as pictured in the table is that the 2022 paper actually specifically calls out and corrects that error. The table is primarily derived from a rule of thumb, but that rule of thumb apparently doesn't apply to that particular case.

Another comment I would give is that the proposed/implied changes from the discussed literature seem to have two different flavors:

  1. In some cases, the equations are fully unchanged, but the units for the terms are "upgraded" to include radians. Examples include tau=I*alpha, E=0.5*I*omega^2, L=I*omega, and omega=d/dt theta (and others). For these cases, the unit checking comes automatically.
  2. In other cases, the rad factors need to be added. Examples include sin(theta/(1 rad)), exp(i*theta/(1 rad)), or a_c=(omega/(1 rad))^2*R, omega=sqrt(g/L) * 1 rad, and s=(theta/(1 rad))*r. These are the ones that feel a little like "cheating", but on the other hand, they do appear logically necessary for things like sin and exp which should have dimensionless inputs. And, related to one of @casella 's points, without these explicit factors, it is otherwise impossible to deduce units in many situations, so in a way, it should be no surprise that explicit addition of units is necessary sometimes.

@HansOlsson
Copy link
Collaborator

To me treating "rad" as sort of "1" avoids adding those odd factors, and still helps. You will be unable to "deduce units" for unit-conversion - but Modelica doesn't have automatic unit-conversions in models.

More importantly I don't see that it will necessarily reduce the number of problems so significantly that it is worth the effort - as the rad-factors and similar unit-factors can also be applied incorrectly; as seen in modelica/ModelicaStandardLibrary#4040

At least this can wait until we have the other unit-checking things in place.

@HansOlsson
Copy link
Collaborator

HansOlsson commented Oct 13, 2022

Going back to Francesco's proposal I see that it importantly states expressions only containing numbers are fine, and not only expressions that consists of just one number.

That's important and Dymola's (not officially released (*) ) current unrelaxed unit-checking doesn't allow that (it opts for the second alternative) and thus e.g.,
Modelica.Electrical.Analog.Examples.CauerLowPassAnalog causes problems due to:

  parameter SI.Capacitance c2=1/(1.704992^2*l1)
    "Filter coefficient c2";
  parameter SI.Capacitance c3=1.682 "Filter coefficient c3";
  parameter SI.Capacitance c4=1/(1.179945^2*l2)
    "Filter coefficient c4";

I'm not saying that it is the best way of writing such parameter bindings, but I can understand that we allow it - while still detecting the problem in2*c4-c2*c3

*: Obviously, we plan on improving it before releasing it.

@henrikt-ma
Copy link
Collaborator

henrikt-ma commented Oct 13, 2022

Going back to Francesco's proposal I see that it importantly states expressions only containing numbers are fine, and not only expressions that consists of just one number.

That's important and Dymola's (not officially released (*) ) current unrelaxed unit-checking doesn't allow that (it opts for the second alternative)

It was also my impression some time ago that such strict rules were desired, as it would allow every inferred unit to be attached to a particular literal in a formula. However, the discussion in #2127 made it clear to me that it was generally considered too restrictive, and #3257 has been designed with the more relaxed approach in mind.

I'm not sure what is the desired result here, to me the c2 and c4 look like the kind of problems we'd like to detect. This is how #3257 handles the declaration equation c2 = 1 / (1.704992^2 * l1), from the bottom of the expression tree and up, as usual:

  • 1.704992 has empty unit.
  • 2 has empty unit, and gets inferred unit "1" due to being right operand of binary exponentiation.
  • It "goes without saying" (in the end it should be stated clearly, but we're not there yet) that 1.704992^2 propagates the empty unit of the left operand up the expression tree. In other words, 1.704992^2 has empty unit.
  • l1 has unit "H" according to its declaration
  • As one of the operands in the multiplication 1.704992^2 * l1 has non-empty unit, the other operand gets inferred unit "1". Hence, the unit of 1.704992^2 * l1 is "1" * "H" = "H".
  • 1 is implicitly cast to Real and hence as empty unit.
  • As one of the operands in the division 1 / (1.704992^2 * l1) has non-empty unit, the other operand gets inferred unit "1". Hence, the unit of 1 / (1.704992^2 * l1) is "1" / "H" = "1/H" = "kg-1.m-2.s2.A2"
  • The declared unit of c2 is "F" = "kg-1.m-2.s4.A2", so the declaration equation has a dimensional homogenity error in the seconds.

Edit: I suppose a unit-correct way of expressing the declaration equation would require the use of an auxiliary constant to which the missing unit can be attached, for example:

protected
 constant Real t2(unit = "s") = 1 / 1.704992;
public
  parameter SI.Capacitance c2 = t2^2 / l1
    "Filter coefficient c2";

@HansOlsson
Copy link
Collaborator

I'm not sure what is the desired result here, to me the c2 and c4 look like the kind of problems we'd like to detect.

Ah, sorry - I was tired and saw it as 11 not l1; so probably Dymola did the right thing.

@casella
Copy link
Collaborator

casella commented Oct 25, 2022

See PR #3266 with my concrete proposal for amending the Specification text.

@bilderbuchi
Copy link

bilderbuchi commented Jun 12, 2023

From the various comments here and in the rejected #3266, I had compiled this list of examples/test cases for desired unit checking behaviour involving literals: https://gist.github.com/bilderbuchi/317bc1a2e039f477462a61f5826260ea#file-mcp-0027-test-examples-md
AFAIK, this list is uncontentious w.r.t. the rejected/accepted outcome of a given example, and probably also w.r.t the given reasoning. It might come in handy during potential future iterations on this MCP's topic.

@casella
Copy link
Collaborator

casella commented Jun 12, 2023

AFAIK, this list is uncontentious w.r.t. the rejected/accepted outcome of a given example, and probably also w.r.t the given reasoning. It might come in handy during potential future iterations on this MCP's topic.

Thanks @bilderbuchi, it is definitely good for me.

@mestinso
Copy link

From the various comments here and in the rejected #3266, I had compiled this list of examples/test cases for desired unit checking behaviour involving literals: https://gist.github.com/bilderbuchi/317bc1a2e039f477462a61f5826260ea#file-mcp-0027-test-examples-md AFAIK, this list is uncontentious w.r.t. the rejected/accepted outcome of a given example, and probably also w.r.t the given reasoning. It might come in handy during potential future iterations on this MCP's topic.

One comment regarding the ones with pi and gamma: as is, I agree with the "undecided" status. With that said, I feel the following issue should be resolved and unit="1" should be added to pi, gamma, etc.: modelica/ModelicaStandardLibrary#4046

@casella
Copy link
Collaborator

casella commented Jun 13, 2023

One comment regarding the ones with pi and gamma: as is, I agree with the "undecided" status. With that said, I feel the following issue should be resolved and unit="1" should be added to pi, gamma, etc.: modelica/ModelicaStandardLibrary#4046

I absolutely agree with that. But I understand this may also be a subject of debate. I once added unit = "1" to the definition of pi to one of the libraries I am developing (can't remember which one) and I remember some comments from @dietmarw that pointed out some possible drawbacks. @dietmarw, maybe he can give some advice to modelica/ModelicaStandardLibrary#4046 as well.

@gwr69
Copy link
Contributor

gwr69 commented Jun 13, 2023

I am confused: Aren't rad the unit of pi? :)

@HansOlsson
Copy link
Collaborator

HansOlsson commented Jun 13, 2023

I am confused: Aren't rad the unit of pi? :)

Yes, and no.

One of the underlying issues with the unit-system is that "rad" and "1" are sort of the same. Having "rad" would imply that A=pi*r^2 should have unit "rad.m2"; which is more confusing - so having "1" is preferable.
The reason for selecting radians is exactly that it is possible to treat it as unit "1".

I know there are people that claim that they can differentiate between them, but those tricks normally makes everything more confusing.

@gwr69
Copy link
Contributor

gwr69 commented Jun 13, 2023

I am confused: Aren't rad the unit of pi? :)

Yes, and no.

One of the underlying issues with the unit-system is that "rad" and "1" are sort of the same. Having "rad" would imply that A=pi*r^2 should have unit "rad.m2"; which is more confusing - so having "1" is preferable. The reason for selecting radians is exactly that it is possible to treat it as unit "1".

I know there are people that claim that they can differentiate between them, but those tricks normally makes everything more confusing.

D'accord and I would be really interested in any reason to not let pi have final unit = "1".

@casella
Copy link
Collaborator

casella commented Jun 13, 2023

As a side note, I've been participating to Modelica Design Meetings for 20 years, and I sometimes thought our discussions had something in common with the scholarly debates of medieval theologians about how many angels would fit on a pin. Though I was impressed by the progress we made over the years, contrary to the motto that "a language should be designed by a person, not by a committee". At least, Modelica came out way better than Ada 😃 .

I guess the discussion on units is particularly fit for this scenario 😅

@casella
Copy link
Collaborator

casella commented Jun 13, 2023

D'accord and I would be really interested in any reason to not let pi have final unit = "1".

@gwr69 on this topic please also check my comment above, specifically on the difference between unit checking and dimensional consistency checking.

My feeling is that dimensional consistency is what we should try to check, and from that point of view "rad" or "1" make no difference, because they are both dimensionless. Proper unit checking and unit inference are a lot more demanding, and I have a strong feeling that they require some understanding of the equations, as the examples in my comment above demonstrate. Maybe we should eventually have our models checked by LLMs? 😅

@HansOlsson
Copy link
Collaborator

HansOlsson commented Oct 22, 2023

Issues that we need to consider and decide on (the list may be incomplete):

  • The handling of literal constants (in general - but see additional issues below); according to Added "four-line" proposal for units of literals #3266 (comment) one possibility is to state that literal constants that are multiplied/divided are assumed to have unit="1"; whereas in addition/subtraction/relations and assignments they are assumed to have a suitable unit
  • Aiming for dimensional consistency or unit-checking; the conclusion from MCP-0027 Units of Literal Constants #2127 (comment) seems to be that we "only" want dimensional consistency
    • One part is separating rad vs. 1.
    • Another part is allowing prefixes, like 4 mm (as unit); historically the goal was to only have it in displayUnit
  • Only checking or full inference? It seems fairly clear we want inference
    • Possibly with some exception for inferencing some constants(?) from equations.
  • Fractional powers; Support non-integer exponents to handle the result of square root #3439
    • The idea is that sqrt should work even if the input doesn't have a squared unit. (I think we agreed on that.)
    • Should it also be possible to specify m^0.5 as unit in some way? Note that m0.5 doesn't seem to work in terms of syntax. I don't know if we need rational powers in general (we cannot write m^(1/3) using decimal numbers) - or just repeated sqrt.
  • How to enable/disable the checking feature; and at what level (equation, model, top-level package). Note that even if one model has disabled the feature we want to combine that with other models without compromising them. (Hans: I want the ability for equations, and to me that mindset works better for combinations.)
    • One case are correlations with literal numbers see Unit error in Modelica.Clocked.Examples.Systems.Utilities.ComponentsThrottleControl.IntakeManifold ModelicaStandardLibrary#4097
    • Another case are simple test-cases; like p=1000000+1000*time
    • Non-SI units; should we have some clear way to indicate in the unit that they are non-SI for input/output, make it clearer that it isn't allowed, or have some other way of disabling the restriction.
    • Note that it was changed from "disable" to "enable/disable". Viewing it as "disable" would imply that the default is the most strict checking - that may not be good; so this should be considered as well.
  • Do we need a way specifying a value in a unit like Real(value=2, unit="m") or should we rely on named constants/parameters? (An intermediate variant would be to add it, but not recommend it.) Note that for constants/parameters one can use a different displayUnit - that is handled by the parameter dialog showing the value in the displayUnit.
  • Non-technical units like currencies, The Mole Day Proposal: Modelica should better accommodate the modeling needs of non-technical domains #3425
  • Check how this works in practice (there are still hundred of issues in MSL when enabling such a check.)

@HansOlsson
Copy link
Collaborator

To discuss:

  • Are some issues missed in that list?

@henrikt-ma
Copy link
Collaborator

  • Are some issues missed in that list?
  • Unit semantics of all built-in operators and functions.
  • Unit semantics of calls to user-defined functions.
  • Generalizing discussion about literal constants to entire subexpressions that are free of units.
  • An overall strategy designed with gradual deprecation in mind, so that we don't need to deprecate all inconsistent uses of units at once, but can put some inconsistent uses on a roadmap of things planned for deprecation in future versions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working MCP Generic MCP label (prefer specific MCP label for grouping of issues belonging to the same MCP)
Projects
None yet
Development

No branches or pull requests