ModelicaSpecification icon indicating copy to clipboard operation
ModelicaSpecification copied to clipboard

Uses annotation should support mutliple libraries

Open modelica-trac-importer opened this issue 7 years ago • 13 comments

Reported by fcasella on 13 Mar 2013 15:19 UTC The uses annotation allows to specify a single version of a certain library that another library depends upon. This is too restrictive. Library X might work perfectly well with multiple versions of library Y, so it is really inconvenient to have multiple versions of X which only differ because of a different uses annotation.

This problem has been around for years. It is related to #132, #536, #573, but in my opinion it should be fixed as soon as possible, without waiting for any of those proposals to coalesce into an official specification, which might take some more years because of their complexity.

My very simple proposal is to allow specifying an ordered list of libraries in the uses annotation, e.g.,

annotation(uses(Modelica(version="3.2.1", version = "3.3")));

similarly to the noneFromVersion conversion annotation.

The Modelica tool will load the latest available/supported/tested/licensed version (i.e., the one one corresponding to the latest possible element in the comma-separated list) or, in case of multiple dependencies among different libraries, the latest possible version that fits the requirements of all the other loaded libraries.

The specification and the implementation looks straightforward, and if all tool vendors agree, we could add this to 3.3 rev1, without having to wait for 3.4. Shall I file an MCP for this?


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

modelica-trac-importer avatar Nov 04 '18 01:11 modelica-trac-importer

Comment by sjoelund.se on 13 Mar 2013 15:38 UTC I would make some changes to this... You may not modify the same component twice (which you do in this example).

See 12.9.4 to see how the Library annotation deals with multiple choices (it allows either version="3.2.1" or version={"3.2.1","3.3"}). I personally do prefer that way of handling these things even though it is weird since you are allowed to use a scalar for something that takes an array...

modelica-trac-importer avatar Nov 04 '18 01:11 modelica-trac-importer

Comment by mtiller on 13 Mar 2013 15:48 UTC I would strongly prefer to see us focus on #573 that to come up with yet another proposal. There has already been quite a bit of discussion around #573 (on this topic).

modelica-trac-importer avatar Nov 04 '18 01:11 modelica-trac-importer

Comment by hansolsson on 15 Mar 2013 09:25 UTC This proposal seems like a good change.

As for the implementation: most of the issues for version-handling occur when there is a need to update libraries (since we currently have no mechanism for detecting if the library will stay compatible with both versions).

A simple solution for that is to restrict it to "read-only" libraries (that could be viewed as a tool-issue).

This goes together with viewing the extra version-compatibility as something that only a library developer adds for his/her users (after testing).

The second issue is that it will be difficult to figure out what to load, if the goal is to load the best set of library. (You use library A that is compatible with MSL "3.2.1" and "3.3" and version "2" or "1" of library B where version "1" of library B is compatible with MSL "3.2.1" and "3.2", etc; yes - that is a straightforward graph-problem, of course, but currently it would require reading many files and if no good version is found we need to present this to the user.) If the goal is just to be able to send library "A" to someone that only has either MSL 3.2.1 or MSL 3.3 it is, obviously, easier to implement.

modelica-trac-importer avatar Nov 04 '18 01:11 modelica-trac-importer

Modified by otter on 4 Jun 2013 16:14 UTC

modelica-trac-importer avatar Nov 04 '18 01:11 modelica-trac-importer

Comment by hansolsson on 4 Jun 2013 16:41 UTC Conclusion:

  • Should test-implement the new feature.
  • Add to 3.3rev1 or 3.4 - and release that version quite soon.

modelica-trac-importer avatar Nov 04 '18 01:11 modelica-trac-importer

Comment by dietmarw on 15 Nov 2013 13:30 UTC 80th Design Meeting is long over ... closing that milestone and still open tickets set back to *undecided*.

modelica-trac-importer avatar Nov 04 '18 01:11 modelica-trac-importer

Comment by dietmarw on 16 Nov 2014 00:26 UTC Looking at MLS 3.3rev1 I could not find this being implemented.

modelica-trac-importer avatar Nov 04 '18 01:11 modelica-trac-importer

Comment by dietmarw on 19 Dec 2014 07:01 UTC Ticket retargeted after milestone closed

modelica-trac-importer avatar Nov 04 '18 01:11 modelica-trac-importer

Comment by dhedberg on 11 Mar 2016 10:43 UTC In SystemModeler we treat the case when a uses annotation contains several sub-entries with the same identifier as valid and that it means either version works.

Example: uses(Modelica(version = "3.2.1"), Modelica(version = "3.2.2"))

modelica-trac-importer avatar Nov 04 '18 01:11 modelica-trac-importer

Comment by dietmarw on 11 Mar 2016 12:17 UTC So which version does SystemModeler choose if both versions of MSL are available (as in MODELICAPATH)?

modelica-trac-importer avatar Nov 04 '18 01:11 modelica-trac-importer

Comment by dhedberg on 14 Mar 2016 08:49 UTC Hmmm, does it matter? Any of them will work. If one of the versions declared compatible is currently loaded, it will be used. Otherwise it is ultimately up to the user which one to load, but it would not matter.

modelica-trac-importer avatar Nov 04 '18 01:11 modelica-trac-importer

Comment by sjoelund.se on 14 Mar 2016 08:53 UTC It comes back to comment:1 though. It's not a valid modification and it's desirable for tools that you could query the modifications to change them in a nice way. If you would set annotation uses.Modelica.version := "3.2.3", you don't really know what to do if you have the structure in comment:9.

modelica-trac-importer avatar Nov 04 '18 01:11 modelica-trac-importer

Comment by dhedberg on 15 Mar 2016 07:45 UTC I guess you would have to query the user to know for sure. Has the user made changes so that his model is compatible with 3.2.3 only, or does it work for all 3.2.1 - 3.2.3? This seems like a tool issue which can certainly be solved. The problem with the uses annotation as of today is that it does not allow you to express that a model is compatible with two different versions of a library. I consider that to be a much bigger problem, and a limitation which we have been forced to work around by allowing multiple sub-entries with the same identifier as described.

modelica-trac-importer avatar Nov 04 '18 01:11 modelica-trac-importer

I suggest to adopt the proven Version Specifier for Python packages as format for the version modifier of the using annotation , e.g.

// works with MSL >= 4.1, but < 5.0
uses(Modelica(version="~=4.1"))

t-sommer avatar Jun 10 '25 14:06 t-sommer

This looks like a simple solution to a recurring problem. The specification can be lifted from Python. Many Modelica libraries are only lightly connected. Many old libraries from 3.x only needed the update of the path to units to be functional in Modelica 4.x. It would resolve many supposed version incompatibilities as actually not a problem.

hubertus65 avatar Jun 10 '25 15:06 hubertus65

I suggest to adopt the proven Version Specifier for Python packages as format for the version modifier of the using annotation , e.g.

// works with MSL >= 4.1, but < 5.0 uses(Modelica(version="~=4.1"))

We could add something like that, but:

  1. It shouldn't be needed (explained below).
  2. We have a different version syntax in Modelica. E.g., we specifically released MSL 4.1.0 not 4.1, whereas those are the same version in Python (as in the link). (The reason it was named 4.1.0 instead of 4.1 is that someone likes the consistency with three digits). Obviously those differences can be handled, but we need to analyze it.

Why it isn't needed: We already know that there are no conversions from MSL 4.0.0 to MSL 4.1.0 (since MSL clearly states that), and none planned until 5.0.0 (even if you remove a broken model there should at least be a conversion-message explaining that).

So, just stating uses(Modelica(version="4.1.0")) would do the same without introducing a new syntax. But we could make that clearer.

As I recall many of the complaint centered around the use-case of opening a model using MSL 4.0.0 with MSL 4.1.0 (or similarly with earlier versions) and the users were needlessly prompted to update (when nothing had changed in MSL; or if there were changes but they didn't impact your library). That is a tool-specific issue and tools can (and have) been improved to delay/avoid that, although we might add something more to help with that.

If we want to go beyond stating that there's no conversion so it should work, and actually test the combinations then an open-ended version interval is problematic (as we haven't tested with the unreleased 4.2.0 and unplanned 4.1.1).

Note that this is when using the library - when updating a library it is hard to ensure that it is compatible with all versions of other libraries. Without a lot of tool support the simplest solution seems to be to develop for the earliest version - and only have uses for that one, and then rely on the non-conversion as above.

Added: It took me some reading and analyzing, but then I realized that the different syntax is an actual issue, beyond the obvious that 4.1.0 and 4.1 are different versions in Modelica.

Python regularly uses ~=4.1 but since MSL is called 4.1.0 and current uses has version=4.1.0 it seems likely that people will write ~=4.1.0 instead of ~=4.1, but that only matches 4.1.* not 4.2.0 (which will not be detected until 4.2.0 is released). Not hard to solve, but just an indication that we need to consider the differences.

HansOlsson avatar Jun 11 '25 08:06 HansOlsson

It shouldn't be needed (explained below).

So, how do you express that you depend on a model that has been introduced in MyLibrary 6.2, but might change in 7.0?

t-sommer avatar Jun 11 '25 08:06 t-sommer

It shouldn't be needed (explained below).

So, how do you express that you depend on a model that has been introduced in MyLibrary 6.2, but might change in 7.0?

Just use:

model MyModel
   MyLibrary.NewModel m;
   annotation(uses(MyLibrary(version="6.2"));
end MyModel;

And in MyLibrary version 6.3 (etc): annotation(conversion(noneFromVersion="6.2")); And in MyLibrary version 7.0:

  annotation(conversion(from (version = {"6.2", "6.3", ...} , to="7.0", 
                     change={convertClass("MyLibrary.NewModel","MyLibrary.OldModel") ,...

HansOlsson avatar Jun 11 '25 09:06 HansOlsson

Indeed that is the way to handle that case.

The only reason I see for having a uses annotation on multiple versions is the case where what you depend on from MyLibrary is the same in both version 6.2 and 7 (but 7 is not fully backwards-compatible with 6.2). You want your library to specify that either of those versions is OK.

sjoelund avatar Jun 11 '25 10:06 sjoelund

Indeed that is the way to handle that case.

The only reason I see for having a uses annotation on multiple versions is the case where what you depend on from MyLibrary is the same in both version 6.2 and 7 (but 7 is not fully backwards-compatible with 6.2). You want your library to specify that either of those versions is OK.

Agreed, but as far as I remember if you construct:

model MyModel2
   MyLibrary.OtherModel m;
   annotation(uses(MyLibrary(version="6.2"));
end MyModel2;

it is possible to detect that MyLibrary.OtherModel wasn't changed even in MyLibrary 7.0, and thus MyModel2 is compatible with it. I'm not saying that we cannot add something more for this, just that many cases can already be handled automatically.

I believe tools will fine-tune this, due to the release of MSL 4.1.0.

HansOlsson avatar Jun 11 '25 10:06 HansOlsson

For a PR, which of the following would you prefer?

t-sommer avatar Jun 12 '25 08:06 t-sommer

I would prefer:

copy and adapt it entirely in the MLS

Introducing dependencies to an external spec seems messy, and raises questions about:

  • which version
  • what happens if the external spec changes (new version)
  • what happens if we point to an old spec which may stop being published
  • exactly which parts of the external spec is relevant
  • ...

If it is brought into the MLS, it can be clearer exactly which parts are relevant, and we can even adapt or clarify details that may be specific to Modelica (if we find any).

maltelenz avatar Jun 12 '25 08:06 maltelenz

I would prefer:

copy and adapt it entirely in the MLS

Introducing dependencies to an external spec seems messy, and raises questions about:

  • which version
  • what happens if the external spec changes (new version)
  • what happens if we point to an old spec which may stop being published
  • exactly which parts of the external spec is relevant
  • ...

If it is brought into the MLS, it can be clearer exactly which parts are valid, and we can even adapt or clarify details that may be specific to Modelica (if we find any).

All valid points, and additionally we don't want to invalidate the existing syntax for specifying versions of libraries just to support an extension for specifying a range of uses-annotations (which means we need to adapt it).

However, as noted it is not clear exactly what is needed, since tools already have the information to see whether it is compatible (as noted above) - and we might also get a more detailed push for this with MSL 4.1.0.

HansOlsson avatar Jun 12 '25 09:06 HansOlsson

and we might also get a more detailed push for this with MSL 4.1.0.

Could you expand on what is new with 4.1.0, and what changes you expect in tools because of it? There seems to be some insight you have that I'm missing.

maltelenz avatar Jun 12 '25 09:06 maltelenz

and we might also get a more detailed push for this with MSL 4.1.0.

Could you expand on what is new with 4.1.0, and what changes you expect in tools because of it? There seems to be some insight you have that I'm missing.

No deep insight: just the fact that MSL 4.1.0 is a new release that is supposed to be (trivially) compatible with the previous one, and used by many other libraries - i.e., a case where functionality like this might be useful. That last happened in 2019 for MSL (for other libraries it is more complicated - many of them really want their users to upgrade when a new version is released and similarly many of them regularly have major version, and it's harder to discuss non-public libraries).

As for tools I know that some have they have gotten better at handling this since 2019, so this will be a better stress-test.

HansOlsson avatar Jun 12 '25 09:06 HansOlsson