Bad and incomplete text output when using getInstanceName()
Description and Steps to Reproduce
Consider the following code:
package RW
model W2root "OM does not write nameShort"
W2 w2;
end W2root;
model W2 "does not write nameShort"
final parameter String name = getInstanceName();
String nameShort;
Integer index;
algorithm
when initial() then
index := Modelica.Utilities.Strings.findLast(name, ".");
nameShort := Modelica.Utilities.Strings.substring(name, index + 1, Modelica.Utilities.Strings.length(name));
end when;
equation
when initial() then
Modelica.Utilities.Streams.print("### model full path: '" + name + ".mat" + "'");
Modelica.Utilities.Streams.print("### model short name: '" + nameShort + ".mat" + "'");
end when;
annotation (
experiment(StartTime = 0, StopTime = 2, Tolerance = 1e-6, Interval = 0.04));
end W2;
end RW;
When I run W2root, the expected output in message window, and the actual output obtained from Dymola is:
### model full path: 'W2root.w2.mat'
### model short name: 'w2.mat'
And this is what I read when I run it from Dymola. If I run W2root from OM 1.19.0, instead, I read:
### model full path: 'RW.W2root.w2.mat'
Here I see two issues:
- The text I get as full path is 'RW.W2root.w2.mat' instead of 'W2root.w2.mat' (see MS 3.7.2.6)
- The second output row, containing the short name, is missing
Expected Behavior
I expect to read the following rows in the log:
### model full path: 'W2root.w2.mat'
### model short name: 'w2.mat'
Screenshots
Version and OS
OM 1.19.2 Win10 64bit
- OpenModelica Version: [e.g.
omc --versionorHelp->About OMEditfrom OMEdit] - OS: [e.g. Windows 10, 64 bit]
- Versions of used Modelica libraries if applicable
Additional Context
See also #9301 and #9303
The getInstanceName issue might be fixed in #9307, if it doesn't break anything (in which case I'll just have to add a special case for getInstanceName).
The issue that the short name isn't printed is not solved though, but doesn't have anything to do with getInstanceName. I'm not sure if it's well defined to have a when-equation that depends on a when-algorithm like that, that might possibly lead to suprising behaviour. @kabdelhak or maybe @casella probably knows more.
@max-privato please check with the next nightly and close this if fixed.
The issue that the short name isn't printed is not solved though, but doesn't have anything to do with
getInstanceName. I'm not sure if it's well defined to have awhen-equation that depends on awhen-algorithm like that, that might possibly lead to suprising behaviour. @kabdelhak or maybe @casella probably knows more.
@perost, which code are you referring to here?
The issue that the short name isn't printed is not solved though, but doesn't have anything to do with
getInstanceName. I'm not sure if it's well defined to have awhen-equation that depends on awhen-algorithm like that, that might possibly lead to suprising behaviour. @kabdelhak or maybe @casella probably knows more.@perost, which code are you referring to here?
There are two print statements in the when-equation, but only one is actually printed when simulating the model. The when-equation depends on the when-algorithm to be executed first in order to give a value to nameShort, but I'm not sure if that's something one can actually rely on. But even then it's a bit weird that nothing is printed from the second print statement.
@max-privato please check with the next nightly and close this if fixed.
I've checked with 1.20.0-dev-259. Now I receive:
### model full path: 'W2root.w2.mat'
So, the first row is now ok. However, the seond row is still missing
@max-privato, simple function calls in equation sections are not forbidden by the specification, but they are a bit fishy, because equations can be re-ordered based on dependencies, and it's not too clear what exactly must be done with them.
Is there a reason why you used an algorithm to set the variables and an equation to print them? What about putting the two print statements in the algorithm?
@max-privato, simple function calls in equation sections are not forbidden by the specification, but they are a bit fishy, because equations can be re-ordered based on dependencies, and it's not too clear what exactly must be done with them.
I'd be curious why that is considered "fishy". Does a function call not also have a straightforward dependency relationship: depends on its arguments? So, it would be reordered to be called when its dependencies/arguments are fully known?
See modelica/ModelicaSpecification#3227.
Given that the print functions are impure and are called within a when statement, this should actually work as you expect.
I understand that the "print" directives are very special equations (they could be used in imperative languages as statements instead of equations). I did not think much about choosing an equation or algorithm action for them, but if they are allowed as I propose, they should work. I also understand that the order of equations within an equation section is not mandatory (the tool can reorder). But we expect that all the content of the when section is run, whatever the order of the two "equations". So, at most, the tool can reverse the order of the two print statements, but not eliminate one of them. If I used an algorithm section, instead, I would have guaranteed that the execution order would be kept.
I tried to flatten RW.W2root, this is the outcome:
class RW.W2root "OM does not write nameShort"
final parameter String w2.name = "W2root.w2";
String w2.nameShort;
Integer w2.index;
equation
when initial() then
Modelica.Utilities.Streams.print("### model full path: '" + w2.name + ".mat" + "'", "");
Modelica.Utilities.Streams.print("### model short name: '" + w2.nameShort + ".mat" + "'", "");
end when;
algorithm
when initial() then
w2.index := Modelica.Utilities.Strings.findLast(w2.name, ".", 0, true);
w2.nameShort := Modelica.Utilities.Strings.substring(w2.name, w2.index + 1, Modelica.Utilities.Strings.length(w2.name));
end when;
end RW.W2root;
name is constant-evaluated by the frontend (because it is a final parameter), and this leads to generated code that produces the intended outcome. nameShort isn't, and this leads to the following generated code:
/*
equation index: 4
type: WHEN
when {} then
noReturnCall(Modelica.Utilities.Streams.print("### model short name: '" + w2.nameShort + ".mat" + "'", ""))%>);
end when;
*/
void W2root_eqFunction_4(DATA *data, threadData_t *threadData)
{
TRACE_PUSH
const int equationIndexes[2] = {1,4};
static const MMC_DEFSTRINGLIT(tmp3,23,"### model short name: '");
modelica_metatype tmpMeta4;
static const MMC_DEFSTRINGLIT(tmp5,4,".mat");
modelica_metatype tmpMeta6;
modelica_metatype tmpMeta7;
if(0)
{
tmpMeta4 = stringAppend(MMC_REFSTRINGLIT(tmp3),(data->localData[0]->stringVars[0] /* w2.nameShort DISCRETE */));
tmpMeta6 = stringAppend(tmpMeta4,MMC_REFSTRINGLIT(tmp5));
tmpMeta7 = stringAppend(tmpMeta6,(modelica_string) mmc_strings_len1[39]);
omc_Modelica_Utilities_Streams_print(threadData, tmpMeta7, (modelica_string) mmc_emptystring);
}
TRACE_POP
}
Obviously the statement following if(0) is never executed 😅.
See #10763.
@max-privato as a workaround for the time being you should avoid String variables corresponding to String equations that are solved at runtime. Only use String parameters and encapsulate the former when initial algorithm in a function:
package RWNew
model W2root "OM does not write nameShort"
W2 w2;
end W2root;
model W2 "does not write nameShort"
final parameter String name = getInstanceName();
final parameter String nameShort = getShortName(name);
function getShortName
input String name;
output String nameShort;
protected
Integer index;
algorithm
index := Modelica.Utilities.Strings.findLast(name, ".");
nameShort := Modelica.Utilities.Strings.substring(name, index + 1, Modelica.Utilities.Strings.length(name));
end getShortName;
equation
when initial() then
Modelica.Utilities.Streams.print("### model full path: '" + name + ".mat" + "'");
Modelica.Utilities.Streams.print("### model short name: '" + nameShort + ".mat" + "'");
end when;
annotation (
experiment(StartTime = 0, StopTime = 2, Tolerance = 1e-6, Interval = 0.04));
end W2;
end RWNew;
Good to have a work around. Thank you