Connecting declared variables in expandable connectors
Reported by eshmoylova on 28 Mar 2017 18:11 UTC Resolution of ticket #428 changed the text of specification for elaborating expandable connectors in 9.1.3 to: "One connector in the connect equation must reference a declared component, and if the other connector is an undeclared element in a declared expandable connector it is handled as follows (elements that are only potentially present are not seen as declared)"
Does it mean the following example is illegal?
expandable connector A
end A;
expandable connector B
input Real x;
end B;
connector RealInput = input Real;
model M
A a;
B b;
RealInput ri;
...
equation
...
connect(a.x,b.x);
end M
According to the new text, the connect equation should not be allowed because a.x is not seen as declared because it is only potentially existing. What would happen if there was instead a pair of connect equations?
connect(a.x,ri);
connect(a.x,b.x);
After the first connect equation a.x is no longer only potentially existing, and it is declared. So is it considered as declared when we process the second equation? I think it should not be because that would make the result dependent on the order of processing. But the specification does not say so explicitly.
Is the paragraph about connecting two expandable connectors correct? "When two expandable connectors are connected, each is augmented with the variables that are only declared in the other expandable connector (the new variables are neither input nor output). This is repeated until all connected expandable connector instances have matching variables [i.e. each of the connector instances is expanded to be the union of all connector variables.]"
It talks only about variables that are declared. What about the variables that are added to a connector as a result of connection?
Migrated-From: https://trac.modelica.org/Modelica/ticket/2172
Comment by jmattsson on 3 Apr 2017 13:03 UTC Replying to [ticket:2172 Elena Shmoylova]:
After the first connect equation
a.xis no longer only potentially existing, and it is declared. So is it considered as declared when we process the second equation? I think it should not be because that would make the result dependent on the order of processing. But the specification does not say so explicitly.
I think you may have switched around your example. Did you mean to declare x in A rather than in B?
Even with that change, I disagree. x does not become declared after processing the first connect. It's status doesn't change at that point other than that we note down that it will be present in the flattened model.
It talks only about variables that are declared. What about the variables that are added to a connector as a result of connection?
This should probably be fixed.
Comment by eshmoylova on 4 Apr 2017 14:06 UTC Replying to [comment:1 Jesper Mattsson]:
Replying to [ticket:2172 Elena Shmoylova]:
After the first connect equation
a.xis no longer only potentially existing, and it is declared. So is it considered as declared when we process the second equation? I think it should not be because that would make the result dependent on the order of processing. But the specification does not say so explicitly. I think you may have switched around your example. Did you mean to declare x in A rather than in B?
You are right. With A and B as written, I should have wrote:
connect(b.x,ri);
connect(a.x,b.x);
And the comment above should refer to b.x.
Even with that change, I disagree. x does not become declared after processing the first connect. It's status doesn't change at that point other than that we note down that it will be present in the flattened model.
Sorry, I just want to make sure I understood your comment correctly. You disagree that x is considered declared after the first connect, right? Does it mean you agree that the example is illegal, that we cannot connect a.x and b.x?
If that's the case I think there might be existing models and libraries out there that would become illegal. I think there should be an explicit example of this illegal case in the Specification, so that it would be easier to understand for the users what has changed.
Comment by kurzbach on 7 Apr 2017 05:25 UTC In the example above b.x is declared so the second connect is valid. But what about
model M
expandable connector C
Real r;
end C;
C c1;
C c2;
C c3;
equation
connect(c1.r,c2.a);
connect(c2.a,c3.b);
end M;
c2.a ist introduced by the first connect statement (c.r is declared), but is not declared (as I understand the spec). That way, the second connect is illegal, but a prominent Modelica tool accepts it. What is the correct interpretation?
Such an example is missing in the specification.
Comment by eshmoylova on 12 Apr 2017 15:33 UTC Replying to [comment:3 Gerd Kurzbach]:
In the example above b.x is declared so the second connect is valid.
The way I understand the new wording quoted in the description b.x is not considered declared. Non-parameter elements declared in expandable connectors are marked as potentially present (this has not changed). What's new is "elements that are only potentially present are not seen as declared" when elaborating connections containing expandable connectors. This is essentially what this ticket is about - with the new warding what was declared is no longer declared. Another problem with this section is that we do not define when potentially present elements become present elements, and how that affects whether we consider them declared or not.
Comment by jmattsson on 18 Apr 2017 09:27 UTC Replying to [comment:2 Elena Shmoylova]:
Replying to [comment:1 Jesper Mattsson]:
Replying to [ticket:2172 Elena Shmoylova]: Even with that change, I disagree. x does not become declared after processing the first connect. It's status doesn't change at that point other than that we note down that it will be present in the flattened model.
Sorry, I just want to make sure I understood your comment correctly. You disagree that x is considered declared after the first connect, right? Does it mean you agree that the example is illegal, that we cannot connect a.x and b.x?
No, my point was that its status doesn't change when you encounter connect(a.x, b.x);. Either it is considered declared both before and after, or it is considered not declared both before and after.
However, that sentence from the spec does seem to make it illegal. I don't find that bad - I think the case where you have connect(a.x, b.x);, but not connect(b.x, ri); becomes a bit ambiguous and hard to diagnose for the user otherwise.
Replying to [comment:2 Elena Shmoylova]:
If that's the case I think there might be existing models and libraries out there that would become illegal. I think there should be an explicit example of this illegal case in the Specification, so that it would be easier to understand for the users what has changed.
Considering how unclear expandable connectors are in general, I'm not sure that "become" is the right word here either. ;)
Comment by hansolsson on 11 May 2017 13:26 UTC Using new version to mark these as reported defects for Modelica 3.4 Specification.
Modified by eshmoylova on 5 Mar 2018 19:24 UTC
Comment by eshmoylova on 5 Mar 2018 20:06 UTC The question of the legality of the first example in the description was still not answered. Here is another example of the clash between the current definition of "declared" and "potentially present".
Consider the following example.
expandable connector B
Real x;
end B
connector RealInput = input Real;
model M
B b;
RealInput ri;
...
equation
connect(b.x[2],ri); // Is it legal?
...
end M;
The relevant specification text (Section 9.1.3 from Spec 3.4, the emphasis is mine): Before generating connection equations non-parameter scalar variables and non-parameter array elements declared in expandable connectors are marked as only being potentially present. ... One connector in the connect equation must reference a declared component, and if the other connector is an undeclared element in a declared expandable connector it is handled as follows (elements that are only potentially present are not seen as declared): ...
- If the undeclared component is subscripted, an array variable is created, and a connection to the specific array element is performed. The variable x is declared as a scalar in the connector B but is considered to be only potentially present in M.b, so for the purpose of the elaboration of connections containing expandable connectors it is not declared, and the rule about the subscript should be applied. Does it mean the example is legal?
Comment by hansolsson on 21 Mar 2018 09:32 UTC Language group: Two issues:
- Terminology (declared, potentially present etc) - need better names.
- The declarations in the expandable connector should be seen as a constraint (i.e. if it exists it should be of that type - and consistent sizes; but ignoring input/output).
Terminology: Declared and used as constraint, but ignored during expandable connector handling.
Variable declarations in expandable connectors are ignored, except as constraint for the deduced variables.
Variable declarations in expandable connectors are only used as constraint and ignored during expandable connector handling.
Variable declarations in expandable connectors are only used as type constraints for the deduced variables and otherwise ignored.
Comment by eshmoylova on 21 Mar 2018 14:32 UTC What does "ignored" mean? In particular, does it mean the following example is not allowed?
model M
expandable connector E1
Real x;
end E1;
expandable connector E2
end E2;
connector RealInput = input Real;
connector RealOutput = output Real;
E1 e1;
E2 e2;
RealInput u;
RealOutput y;
equation
connect(e1.x,e2.x);
connect(e1.x,u);
connect(e2.x,y);
end M;
Right now this model simulates in three different tools that I have tried. Since the models like that are currently allowed by the tools there is a strong possibility that there are user models like that.
Comment by hansolsson on 22 Mar 2018 09:15 UTC Language group: 1: Forbid connect(e1.x, e2.x) as discussed yesterday. However, bad to break user-models for language purity.
2: Idea: If a potentially present variable is explicitly referenced it is present, so connect(e1.x, e2.x); is allowed since e1.x was declared in the expandable connector.
3: Other option: delay handling connect(e1.x, e2.x); until after other normal connections (as part of elaboration) - since in itself it does nothing. Does not require that either e1.x, e2.x exists or are declared. If neither e1.x nor e2.x are declared on connected to (and not part of any elaboration) then e1.x and e2.x don't exist, and it is not an error.
4: Same as 3 but an error if e1.x and e2.x don't exist after elaboration.
Poll: 1: 0 2: 4 3: 2 4: 4 Might be that 2 and 4 behave the same in practice. Should test before next meeting. Advantage of 4 over 2 is that we can ignore declarations in expandable connectors.
Modified by beutlich on 23 Mar 2018 08:05 UTC
If we are thinking of considering declaration inside expandable connectors as constraints and allow some intermediate notion between declared and virtual. I think it is worth considering the following example:
model PotentialExpandableConnector
expandable connector EC0
end EC0;
expandable connector EC1
EC0 ec;
end EC1;
connector RealInput = input Real;
RealInput ri = 0;
EC1 ec;
equation
connect(ri, ec.ec.foo);
end PotentialExpandableConnector;
I think this could be valid, but I figured it was worth having other people considering that case too.
We have discussed what @qlambert-pro asked before. I think that the decision then was that to be able to have a connect like that one, the inner "ec" either has to be declared exactly as you have there. Maybe it was also allowed if you had a connection to it instead (i.e. to "ec.ec")?
I think that was in #428, but the result of that issue was the text quoted in the first post if this one, and that seems to say that you need both. Does anyone else remember our intent in that one?
Since we said in the last meeting that making concrete proposal may help moving tickets forward:
I propose that we remove the text between parenthesis in Section 9.1.3:
"One connector in the connect equation must reference a declared component, and if the other connector is an undeclared element in a declared expandable connector it is handled as follows (elements that are only potentially present are not seen as declared)"
This would mean accepting the models discussed in this ticket while still addressing the question asked in #428.
Discussed at phone meeting, and it would help with more realistic examples, in particular regarding:
- Would it make sense to remove these elements of an expandable connector if they are connected together without any normal connector?
- Why is there a connection between those two elements without any normal connector?
- Would a sub-bus (using a protected extra element) be an alternative?
Discussed at phone meeting, and it would help with more realistic examples, in particular regarding:
- Would it make sense to remove these elements of an expandable connector if they are connected together without any normal connector?
- Why is there a connection between those two elements without any normal connector?
- Would a sub-bus (using a protected extra element) be an alternative?
Realistic examples are still missing.
The following example may be a little contrived, but ultimately it comes down to being able to create name aliasing within buses:
model Example
expandable connector TXBus
Real tSignal;
end TXBus;
expandable connector RXBus
Real rSignal;
end RXBus;
connector RealInput = input Real;
connector RealOutput = output Real;
model B
RealInput ri;
Real x = ri;
end B;
model RX
RXBus rxb;
B b;
equation
connect(rxb.rSignal, b.ri);
end RX;
model A
RealOutput ro = 0;
end A;
model TX
TXBus txb;
A a;
equation
connect(txb.tSignal, a.ro);
end TX;
RX rx;
RXBus rxb;
TX tx;
TXBus txb;
equation
connect(rx.rxb, rxb);
connect(tx.txb, txb);
connect(rxb.rSignal, rxb.tSignal);
end Example;
You could also imagine having a single bus and wanting to easily connect two of its signals.