#2965 closed discussion (fixed)
Information about "outer output" declarations needed in backend for variable merging in state machines
Reported by: | Bernhard Thiele | Owned by: | Bernhard Thiele |
---|---|---|---|
Priority: | high | Milestone: | 1.9.4 |
Component: | Frontend | Version: | trunk |
Keywords: | state machines | Cc: | Per Östlund, Adrian Pop |
Description
MLS 3.3, "17.3.5 Merging Variable Definitions" requires to merge variables in states that have been declared as outer output. However, in the backend that information is lost, thus it can't be implemented.
Quoting from the spec:
In each state, the outer output variables are solved for and for each such variable a single definition is formed:
v := if activeState(state1) then expre1 elseif activeState(state2 ) then expre2 elseif ... else last(v)
I tried to recover the needed pieces from what is available in the backend, but didn't succeed so far. Consider example:
model ConferenceTut1Modified inner Integer i(start=0); Integer j(start=0), y; model State1 outer output Integer i; input Integer j; Integer k; equation i = previous(i) + 2 - k; j = k; end State1; State1 state1(j=j); model State2 outer output Integer i; input Integer j; Integer k; equation i = previous(i) - 1- k; j = k; end State2; State2 state2(j=j); equation 2 = j; y = i; initialState(state1); transition(state1, state2, i > 10, immediate=false); transition(state2,state1, i < 1, immediate=false); end ConferenceTut1Modified;
The model flattens to:
class ConferenceTut1Modified Integer i(start = 0); Integer j(start = 0); Integer y; Integer state1.i = i; Integer state1.j = j; Integer state1.k; Integer state2.i = i; Integer state2.j = j; Integer state2.k; equation state1.i = 2 + previous(state1.i) - state1.k; state1.j = state1.k; state2.i = -1 + previous(state2.i) - state2.k; state2.j = state2.k; 2 = j; y = i; initialState(state1); transition(state1, state2, i > 10, false, true, false, 1); transition(state2, state1, i < 1, false, true, false, 1); end ConferenceTut1Modified;
Variable i
needs to be merged, but variable j
not. So i
should get merged like
i = if activeState(state1) then 2 + previous(i) - state1.k else -1 + previous(i) - state2.k;
If we could assume that all models are "correct", one might be able to figure out that the only way that the model could be correct is that i
is a "shared" variable, but j
is not. However, one can not safely make that assumption. Hence, additional information about i
needs to be passed from the frontend to the backend. Or do I miss s.th.?
(Note that #2806 is vaguely related to this ticket, but had the opposite intention of dropping certain information...)
Attachments (1)
Change History (8)
comment:1 by , 10 years ago
comment:2 by , 10 years ago
Hm. The inner outer attributes are lost in the backend (BackendDAECreate.lower
), they are available in the frontend DAE. The direction is available in frontend until it is stripped away for all non-toplevel instances in InstVar.instScalar
attr = stripVarAttrDirection(cr, attr, inState);
which I suppose is due to #2806.
It seems however, that I need both information, because in state machines "outer output Real x
" needs merging "outer input Real x
" is only reading. And we have "inner outer output Real x
" which, in state machines also has a different semantics than the usual "inner outer
". In state machines that means that lower level outer
may write directly to the highest level inner
(so inner outer output
is used in intermediate levels for "shared" variables.
Actually, I don't understand why the spec requires this intermediate level construct "inner outer output
". For me it seems that reusing "outer output
" at the intermediate levels should be sufficient to declare s.th. as a "shared" variable. But may be I start understanding the reason during the implementation ;-).
comment:3 by , 10 years ago
I have now a prototype implementation for state machines in source:/branches/StateMachines@24335 .
Compared to the trunk version there are two important differences.
Change 1: Include information about "inner outer" in BackendDAE.Var
BackEnd/BackendDAE.mo
- add .DAE.VarInnerOuter innerOuter
to VAR
:
public uniontype Var "variables" record VAR // ... .DAE.VarDirection varDirection "input, output or bidirectional"; // ... .DAE.VarInnerOuter innerOuter "inner, outer, inner outer or unspecified"; end VAR; end Var;
FrontEnd/DAE.mo
- Add new uniontype:
public uniontype VarInnerOuter record INNER "an inner prefix" end INNER; record OUTER "an outer prefix" end OUTER; record INNER_OUTER "an inner outer prefix" end INNER_OUTER; record NOT_INNER_OUTER "no inner outer prefix" end NOT_INNER_OUTER; end VarInnerOuter;
Change 2: Pass information about variable causality from the front-end to the back-end
I commented out line
attr = stripVarAttrDirection(cr, attr, inState);
from InstVar.instScalar
(see previous comment).
Change 3: Special rules for instantiation of variables appearing in state machines
I changed function InstVar.instVar
and added special rules for instantiating variables that are part of a state machine, so that I can identify them later in the back-end and treat them special.
Problem: How to get "Change 2" into development trunk without breaking #2806
It is possible to merge Change 1 and Change 3 back into the trunk, however merging Change 2 will break #2806.
Note that as background information I will attach my presentation that gives an overview about the current state machine implementation approach. Moving parts of the state machine implementation from the back-end to the front-end could also be an alternative (for more reasons than just the problem at hand, but it might introduce other difficulties...).
Any ideas?
by , 10 years ago
Attachment: | 2015_OM Workshop_State Machines_Bernhard Thiele.pdf added |
---|
comment:4 by , 10 years ago
I think I partially fixed the issue in source:/branches/StateMachines@24659
I changed the function call
attr = stripVarAttrDirection(cr, attr, inState);
to
attr = stripVarAttrDirection(cr, ih, inState, inPrefix, attr);
and implemented an additional check in the function whether a component with inner/outer prefix is part of a state machine component. If this is the case I don't strip that information, otherwise it is stripped.
comment:5 by , 10 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
Merged branch into source:/trunk@24709.
comment:6 by , 9 years ago
Milestone: | Future → pre1.9.4 |
---|
It doesn't make sense to keep closed ticket in the "Future" milestone that were simply forgotten to assign to the correct milestone in the past.
comment:7 by , 7 years ago
Milestone: | pre1.9.4 → 1.9.4 |
---|
Removing the pre1.9.4 milestone in favor of 1.9.4.
Can't you just add this information to the DAE.Var in InstDAE.daeDeclare?