Skip to content

Commit

Permalink
Collecting outgoing transitions of a mode/state in MODE data structure
Browse files Browse the repository at this point in the history
git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@23191 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
bernhard-thiele committed Nov 4, 2014
1 parent 42e7722 commit dc16af3
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 39 deletions.
13 changes: 8 additions & 5 deletions Compiler/BackEnd/HashTableSM.mo
Expand Up @@ -70,20 +70,23 @@ protected
String name;
Boolean isInitial;
HashSet.HashSet edges;
BackendDAE.EquationArray eqs;
BackendDAE.EquationArray eqs, outgoing;
list<DAE.ComponentRef> crefs;
list<BackendDAE.Equation> eqsList;
list<BackendDAE.Equation> eqsList, outgoingList;
list<String> paths;
list<String> eqsDump;
list<String> eqsDump, outgoingDump;
algorithm
StateMachineFeatures.MODE(name=name, isInitial=isInitial, edges=edges, eqs=eqs) := mode;
StateMachineFeatures.MODE(name=name, isInitial=isInitial, edges=edges, eqs=eqs, outgoing=outgoing) := mode;
crefs := BaseHashSet.hashSetList(edges);
paths := List.map(crefs, ComponentReference.printComponentRefStr);
eqsList := BackendEquation.equationList(eqs);
outgoingList := BackendEquation.equationList(outgoing);
eqsDump := List.map(eqsList, BackendDump.equationString);
outgoingDump := List.map(outgoingList, BackendDump.equationString);
s := "MODE(" + stringDelimitList({name,boolString(isInitial)}, ",") + "), "
+ "EDGES(" + stringDelimitList(paths, ", ") +"), "
+ "Equations( "+ stringDelimitList(eqsDump, ";\n\t") +")";
+ "Equations( "+ stringDelimitList(eqsDump, ";\n\t") +"), "
+ "OutgoingTransitions( "+ stringDelimitList(outgoingDump, ";\n\t") +")\n";
end modeToString;

annotation(__OpenModelica_Interface="backend");
Expand Down
130 changes: 96 additions & 34 deletions Compiler/BackEnd/StateMachineFeatures.mo
Expand Up @@ -85,9 +85,9 @@ Tbd"
record MODE
String name;
Boolean isInitial;
HashSet.HashSet edges; // needed?
BackendDAE.EquationArray eqs;
// list<Automaton> refinement;
HashSet.HashSet edges "relations to other modes due to in- and out-going transitions";
BackendDAE.EquationArray eqs "equations defined in the mode instance"; // Better use list<BackendDAE.Equation> eqs;?
BackendDAE.EquationArray outgoing "outgoing transitions";
end MODE;
end Mode;

Expand All @@ -107,6 +107,7 @@ uniontype FlatAutomaton
record FLAT_AUTOMATON
DAE.ComponentRef initialState;
HashSet.HashSet states;
list<BackendDAE.Equation> transitions;
end FLAT_AUTOMATON;
end FlatAutomaton;

Expand All @@ -118,6 +119,14 @@ uniontype Composition
end COMPOSITION;
end Composition;

public
uniontype TransitionType
record TRANSITION "transtion(..) statement"
end TRANSITION;
record INITIAL_STATE "initialState(..) statement"
end INITIAL_STATE;
end TransitionType;


public function stateMachineElab
"Elaborate state machines and transform them in data-flow equations."
Expand All @@ -136,6 +145,9 @@ protected
BackendDAE.EqSystem syst, systNew;
BackendDAE.Shared shared, sharedNew;
algorithm

//BackendDump.printBackendDAE(inDAE);

(syst, shared) := match inDAE
local
BackendDAE.EqSystem syst1;
Expand All @@ -149,37 +161,39 @@ algorithm
// Identify modes in the system
modes := identifyModes(shared);
names := List.map(BaseHashTable.hashTableKeyList(modes), ComponentReference.crefLastIdent);
print("SMF-stateMachineElab States: " + stringDelimitList(names, ",") + "\n");
print("SMF-stateMachineElab ModeTable:\n");
print("***** SMF-stateMachineElab States: ***** \n" + stringDelimitList(names, ",") + "\n");
print("***** SMF-stateMachineElab ModeTable: ***** \n");
BaseHashTable.dumpHashTable(modes);
nModes := BaseHashTable.hashTableCurrentSize(modes);

print("SMF-stateMachineElab: Incidence matrix:\n");
print("***** SMF-stateMachineElab: Incidence matrix: ***** \n");
iTable := createIncidenceTable(modes, nModes);
printIncidenceTable(iTable, nModes);

print("SMF-stateMachineElab: Transitive closure:\n");
print("***** SMF-stateMachineElab: Transitive closure: ***** \n");
transClosure := transitiveClosure(iTable, nModes);
printIncidenceTable(transClosure, nModes);

print("SMF-stateMachineElab: Initial States:\n");
print("***** SMF-stateMachineElab: Initial States: ***** \n");
initialStates := extractInitialStates(modes);
print( stringDelimitList(List.map(initialStates, ComponentReference.printComponentRefStr), ", ") + "\n");

print("SMF-stateMachineElab: Flat Automata:\n");
print("***** SMF-stateMachineElab: Flat Automata: ***** \n");
flatAutomata := extractFlatAutomata(initialStates, transClosure, nModes);
printFlatAutomata(flatAutomata);

print("SMF-stateMachineElab: Composition:\n");
print("***** SMF-stateMachineElab: Composition: ***** \n");
//compositions := getComposition(flatAutomata, {});
compositions := getComposition(flatAutomata);
ss := List.map(compositions, dumpCompositionStr);
print(stringDelimitList(ss, ",\n") + "\n");

print("SMF-stateMachineElab: annotate modes with additional information\n");
print("***** SMF-stateMachineElab: annotate modes with additional information ***** \n");
(modes, systNew, sharedNew) := annotateModes(modes, syst, shared);
BaseHashTable.dumpHashTable(modes);

//outDAE := BackendDAE.DAE({systNew}, sharedNew);
//BackendDump.printBackendDAE(outDAE);
outDAE := BackendDAE.DAE({syst}, shared); // dummy assignment as long as elabortion is not implemented

end stateMachineElab;
Expand Down Expand Up @@ -235,12 +249,10 @@ algorithm
(orderedEquOptArr, modesOut) := Array.mapNoCopy_1(orderedEquOptArr, annotateMode, modesIn);
(removedEquOptArr, modesOut) := Array.mapNoCopy_1(removedEquOptArr, annotateMode, modesOut);

// New equation arrays (equations assigned to modes are replaced by NONE())
orderedEqsNew := BackendDAE.EQUATION_ARRAY(orderedSize, orderedNumberOfElement, orderedArrSize, orderedEquOptArr);
removedEqsNew := BackendDAE.EQUATION_ARRAY(removedSize, removedNumberOfElement, removedArrSize, removedEquOptArr);

//(orderedEqsNew, modesOut) := BackendEquation.traverseBackendDAEEqnsWithUpdate(orderedEqs, annotateMode, modesIn);
//(removedEqsNew, modesOut) := BackendEquation.traverseBackendDAEEqnsWithUpdate(removedEqs, annotateMode, modesOut);

// A lot of code bloat just for updating fields "orderedEqs" and "removedEqs" in "EQSYSTEM" and "SHARED" ...
outSyst := BackendDAE.EQSYSTEM(orderedVars, orderedEqsNew, m, mT, matching, stateSets, partitionKind);
outShared := BackendDAE.SHARED(knownVars, externalObjects, aliasVars, initialEqs, removedEqsNew, constraints,
Expand All @@ -265,11 +277,12 @@ protected
ModeTable modeTable;
Option<DAE.ElementSource> sourceOpt "origin of equation";
Option<DAE.ComponentRef> instanceOpt "the instance(s) this element is part of";
Option<tuple<DAE.ComponentRef,TransitionType>> transitionOpt "transition statement";
Option<Mode> optMode;
algorithm
(eqOpt, modeTable) := inEqModeTable;
// Just match any possible Equation type and extract the source field.
// TODO More specific handling with error handling (e.g., WHEN_EQUATION not allowed in a state)

// Match any possible Equation type and extract the source field.
sourceOpt := match (eqOpt)
local
DAE.ElementSource source1;
Expand All @@ -284,10 +297,41 @@ algorithm
else NONE();
end match;

instanceOpt := match (sourceOpt)
// Check whether equation is a transition(cref, ..) or initialState(cref) statement and extract first argument.
transitionOpt := match (eqOpt)
local
String name;
list<DAE.Exp> expLst;
tuple<DAE.ComponentRef,TransitionType> transition;
DAE.ComponentRef cref;
case (SOME(
BackendDAE.ALGORITHM(alg = DAE.ALGORITHM_STMTS(
statementLst = {
DAE.STMT_NORETCALL(
exp = DAE.CALL(
path = Absyn.IDENT(name = name),
expLst = DAE.CREF(componentRef=cref)::_
)
)
}
))
)) guard (name == "transition" or name == "initialState")
equation
transition = if (name == "transition") then (cref, TRANSITION()) else (cref, INITIAL_STATE());
then
SOME(transition);
else then NONE();
end match;


// If we had a transition statement, extract the instance of its first argument,
// if not, check if source refers to a "parent" instance
instanceOpt := match (sourceOpt, transitionOpt)
local
Option<DAE.ComponentRef> crefOpt;
case SOME(DAE.SOURCE(instanceOpt=crefOpt)) then crefOpt;
DAE.ComponentRef cref;
case (_, SOME((cref,_))) then SOME(cref);
case (SOME(DAE.SOURCE(instanceOpt=crefOpt)), NONE()) then crefOpt;
else NONE();
end match;

Expand All @@ -300,20 +344,38 @@ algorithm
else NONE();
end match;

outEqModeTable := match (optMode, instanceOpt, eqOpt)
// Remove equations that correspond to a mode/state from the DAE equation array (replace by NONE())
// and move them to the corresponding modes
outEqModeTable := match (optMode, instanceOpt, transitionOpt, eqOpt)
local
DAE.ComponentRef cref;
BackendDAE.Equation eq;
ModeTable modeTableNew;
String name;
Boolean isInitial;
HashSet.HashSet edges;
BackendDAE.EquationArray eqs;
case (SOME(MODE(name,isInitial,edges,eqs)), SOME(cref), SOME(eq))
BackendDAE.EquationArray eqs, outgoing;
//Option<tuple<DAE.ComponentRef,TransitionType>> transOpt;

// Move equation to "parent" mode/state instance
case (SOME(MODE(name,isInitial,edges,eqs,outgoing)), SOME(cref), NONE(), SOME(eq))
equation
eqs = BackendEquation.addEquation(eq, eqs);
modeTableNew = BaseHashTable.update((cref, MODE(name,isInitial,edges,eqs)), modeTable);
modeTableNew = BaseHashTable.update((cref, MODE(name,isInitial,edges,eqs,outgoing)), modeTable);
then (NONE(), modeTableNew);

// Move transtion(..) statement to mode/state where it is the outgoing transition
case (SOME(MODE(name,isInitial,edges,eqs,outgoing)), SOME(cref), SOME((_,TRANSITION())), SOME(eq))
equation
outgoing = BackendEquation.addEquation(eq, outgoing);
modeTableNew = BaseHashTable.update((cref, MODE(name,isInitial,edges,eqs,outgoing)), modeTable);
then (NONE(), modeTableNew);

// Remove initialState(..) statement
case (SOME(MODE(name,isInitial,edges,eqs,outgoing)), _, SOME((_,INITIAL_STATE())), SOME(eq))
then (NONE(), modeTable);

// return structures without any modifications
else (eqOpt, modeTable);
end match;

Expand Down Expand Up @@ -513,7 +575,7 @@ algorithm
end for;
memberSet := HashSet.emptyHashSetSized(listLength(members));
memberSet := List.fold(members, BaseHashSet.add, memberSet);
flatAutomata := FLAT_AUTOMATON(cref, memberSet)::flatAutomata;
flatAutomata := FLAT_AUTOMATON(cref, memberSet, {})::flatAutomata;
end for;

end extractFlatAutomata;
Expand Down Expand Up @@ -738,7 +800,7 @@ algorithm
equation
//print("SMF-extractStates: NO MATCH\n");
then
(inEq, HashTableSM.emptyHashTable());
(inEq, inA);
end match;
end extractStates;

Expand All @@ -760,17 +822,17 @@ algorithm
String name1,name2;
Boolean isInitial1,isInitial2;
HashSet.HashSet edges1,edges2;
BackendDAE.EquationArray eqs1,eqs2;
BackendDAE.EquationArray eqs1,eqs2,outgoing1,outgoing2;
//array<Option<BackendDAE.Equation>> equOptArr;
case ("initialState", {DAE.CREF(componentRef=cstate1)})
equation
//print("SMF-printEq2: "+anyString(cstate1)+"\n");
mode1 = if BaseHashTable.hasKey(cstate1, inA)
then BaseHashTable.get(cstate1, inA)
else MODE(ComponentReference.crefLastIdent(cstate1), true, HashSet.emptyHashSet(),
BackendDAE.EQUATION_ARRAY(0,0,0,arrayCreate(0,NONE())));
MODE(name1,isInitial1,edges1,eqs1) = mode1;
mode1 = MODE(name1,true,edges1,eqs1);
BackendEquation.emptyEqns(), BackendEquation.emptyEqns());
MODE(name1,isInitial1,edges1,eqs1,outgoing1) = mode1;
mode1 = MODE(name1,true,edges1,eqs1,outgoing1);
modes = BaseHashTable.add((cstate1, mode1), inA);
then modes;
case ("transition", DAE.CREF(componentRef=cstate1)::DAE.CREF(componentRef=cstate2)::_)
Expand All @@ -781,21 +843,21 @@ algorithm
mode1 = if BaseHashTable.hasKey(cstate1, inA)
then BaseHashTable.get(cstate1, inA)
else MODE(ComponentReference.crefLastIdent(cstate1), false, HashSet.emptyHashSet(),
BackendDAE.EQUATION_ARRAY(0,0,0,arrayCreate(0,NONE())));
MODE(name1, isInitial1, edges1, eqs1) = mode1;
BackendEquation.emptyEqns(), BackendEquation.emptyEqns());
MODE(name1, isInitial1, edges1, eqs1,outgoing1) = mode1;
isInitial1 = isInitial1 or false;
edges1 = BaseHashSet.add(cstate2, edges1);
mode1 = MODE(name1, isInitial1, edges1, eqs1);
mode1 = MODE(name1, isInitial1, edges1, eqs1, outgoing1);
modes = BaseHashTable.add((cstate1, mode1), inA);

mode2 = if BaseHashTable.hasKey(cstate2, modes)
then BaseHashTable.get(cstate2, modes)
else MODE(ComponentReference.crefLastIdent(cstate1), false, HashSet.emptyHashSet(),
BackendDAE.EQUATION_ARRAY(0,0,0,arrayCreate(0,NONE())));
MODE(name2, isInitial2, edges2, eqs2) = mode2;
BackendEquation.emptyEqns(), BackendEquation.emptyEqns());
MODE(name2, isInitial2, edges2, eqs2, outgoing2) = mode2;
isInitial2 = isInitial2 or false;
edges2 = BaseHashSet.add(cstate1, edges2);
mode2 = MODE(name2, isInitial2, edges2, eqs2);
mode2 = MODE(name2, isInitial2, edges2, eqs2, outgoing2);
modes = BaseHashTable.add((cstate2, mode2), modes);
then modes;
end match;
Expand Down

0 comments on commit dc16af3

Please sign in to comment.