@@ -194,10 +194,15 @@ protected
194194 HashTableCG . HashTable outerOutputCrefToSMCompCref "Table to map outer outputs to corresponding state" ;
195195 HashTableCG . HashTable outerOutputCrefToInnerCref "Table to map outer output to corresponding inners" ;
196196 HashTable3 . HashTable innerCrefToOuterOutputCrefs "Kind of \" inverse \" of outerOutputCrefToInnerCref" ;
197- List < tuple< DAE . ComponentRef , DAE . ComponentRef >> hashEntries;
198- List < DAE . ComponentRef > uniqueHashValues;
197+ List < tuple< DAE . ComponentRef , DAE . ComponentRef >> hashEntries_outerOutputCrefToInnerCref;
198+ List < tuple< DAE . ComponentRef , list< DAE . ComponentRef >>> innerCrefToOuterOutputCrefs_der = {} "Extracted part in which at least one of the output crefs appears in a der(..)" ;
199+ List < tuple< DAE . ComponentRef , list< DAE . ComponentRef >>> innerCrefToOuterOutputCrefs_nonDer = {} "The non-der(..) rest" ;
200+ List < DAE . ComponentRef > uniqueHashValues, crefs, derCrefsAcc = {}, outerOutputCrefs;
201+ HashSet . HashSet derCrefsSet;
199202 DAE . FunctionTree emptyTree;
200- list< DAE . Element > dAElistNew, mergeEqns;
203+ list< DAE . Element > dAElistNew, mergeEqns, mergeEqns_der, aliasEqns_der;
204+ Integer nOfHits;
205+ Boolean hasDer;
201206 // FLAT_SM
202207 DAE . Ident ident;
203208 list< DAE . Element > dAElist "The states/modes within the the flat state machine" ;
@@ -206,49 +211,195 @@ algorithm
206211
207212 // Create table that maps outer outputs to corresponding state
208213 outerOutputCrefToSMCompCref := List . fold(dAElist, collectOuterOutputs, HashTableCG . emptyHashTable());
209- // print("InstStateMachineUtil.mergeVariableDefinitions OuterToSTATE:\n"); BaseHashTable.dumpHashTable(outerOutputCrefToSMCompCref);
214+ // print("InstStateMachineUtil.mergeVariableDefinitions OuterToSTATE:\n"); BaseHashTable.dumpHashTable(outerOutputCrefToSMCompCref);
210215
211216 // Create table that maps outer outputs crefs to corresponding inner crefs
212217 outerOutputCrefToInnerCref := List . fold1(BaseHashTable . hashTableKeyList(outerOutputCrefToSMCompCref), matchOuterWithInner, inIH, HashTableCG . emptyHashTable());
213- // print("InstStateMachineUtil.mergeVariableDefinitions OuterToINNER:\n"); BaseHashTable.dumpHashTable(outerOutputCrefToInnerCref);
218+ // print("InstStateMachineUtil.mergeVariableDefinitions OuterToINNER:\n"); BaseHashTable.dumpHashTable(outerOutputCrefToInnerCref);
214219
215220 // Create table that maps inner crefs from above to a list of corresponding outer crefs
216- hashEntries := BaseHashTable . hashTableList(outerOutputCrefToInnerCref);
221+ hashEntries_outerOutputCrefToInnerCref := BaseHashTable . hashTableList(outerOutputCrefToInnerCref);
217222 uniqueHashValues := List . unique(BaseHashTable . hashTableValueList(outerOutputCrefToInnerCref));
218- // print("InstStateMachineUtil.mergeVariableDefinitions uniqueHashValues: (" + stringDelimitList(List.map(uniqueHashValues, ComponentReference.crefStr), ",") + ")\n");
219- innerCrefToOuterOutputCrefs := List . fold1(uniqueHashValues, collectCorrespondingKeys, hashEntries , HashTable3 . emptyHashTable());
220- // print("InstStateMachineUtil.mergeVariableDefinitions: innerCrefToOuterOutputCrefs:\n"); BaseHashTable.dumpHashTable(innerCrefToOuterOutputCrefs);
223+ // print("InstStateMachineUtil.mergeVariableDefinitions uniqueHashValues: (" + stringDelimitList(List.map(uniqueHashValues, ComponentReference.crefStr), ",") + ")\n");
224+ innerCrefToOuterOutputCrefs := List . fold1(uniqueHashValues, collectCorrespondingKeys, hashEntries_outerOutputCrefToInnerCref , HashTable3 . emptyHashTable());
225+ // print("InstStateMachineUtil.mergeVariableDefinitions: innerCrefToOuterOutputCrefs:\n"); BaseHashTable.dumpHashTable(innerCrefToOuterOutputCrefs);
221226
222227 // Substitute occurrences of previous(outerCref) by previous(innerCref)
223228 emptyTree := DAE . AvlTreePathFunction . Tree . EMPTY ();
224229 (DAE . DAE (dAElist), _, _) := DAEUtil . traverseDAE(DAE . DAE (dAElist), emptyTree, traverserHelperSubsOuterByInnerExp, outerOutputCrefToInnerCref);
225230
226- // FIXME add support for outers that don't have "inner outer" or "inner" at closest instance level (requires to introduce a fresh intermediate variable)
227- mergeEqns := List . map1(BaseHashTable . hashTableKeyList(innerCrefToOuterOutputCrefs), freshMergingEqn, innerCrefToOuterOutputCrefs);
231+ if Flags . getConfigBool(Flags . CT_STATE_MACHINES ) then
232+ // == HACK Let's deal with continuous-time ==
233+ crefs := BaseHashTable . hashTableKeyList(outerOutputCrefToSMCompCref);
234+ for cref in crefs loop
235+ nOfHits := 0 ;
236+ // traverse dae expressions and search for der(cref) occurances
237+ (_, _, (_,(_, nOfHits))) := DAEUtil . traverseDAE(DAE . DAE (dAElist), emptyTree, Expression . traverseSubexpressionsHelper, (traversingCountDer, (cref, 0 )));
238+ if nOfHits > 0 then
239+ derCrefsAcc := cref :: derCrefsAcc;
240+ end if ;
241+ end for ;
242+ // print("InstStateMachineUtil.mergeVariableDefinitions derCrefsAcc:\n" + stringDelimitList(List.map(derCrefsAcc, ComponentReference.crefStr), ", ") + "\n");
243+ derCrefsSet := HashSet . emptyHashSetSized(listLength(derCrefsAcc));
244+ derCrefsSet := List . fold(derCrefsAcc, BaseHashSet . add, derCrefsSet);
245+ // Split the mapping from inner crefs to outer output crefs in a "continuous" part and the rest
246+ for hashEntry in BaseHashTable . hashTableList(innerCrefToOuterOutputCrefs) loop
247+ (_, outerOutputCrefs) := hashEntry;
248+ hasDer := List . exist(outerOutputCrefs, function BaseHashSet . has(hashSet= derCrefsSet));
249+ if hasDer then
250+ innerCrefToOuterOutputCrefs_der := hashEntry :: innerCrefToOuterOutputCrefs_der;
251+ else
252+ innerCrefToOuterOutputCrefs_nonDer := hashEntry :: innerCrefToOuterOutputCrefs_nonDer;
253+ end if ;
254+ end for ;
255+ // Create aliases between inner and outer of 'der' entries, e.g., a tuple (x -> {a.x, b.x}) will be transformed to alias equations {x = a.x, x = b.x}
256+ aliasEqns_der := List . flatten( List . map(innerCrefToOuterOutputCrefs_der, freshAliasEqn_der) );
257+ // Create merging equations for 'der' entries
258+ mergeEqns_der := listAppend(List . map(innerCrefToOuterOutputCrefs_der, freshMergingEqn_der), aliasEqns_der);
259+ // Create merging equations for 'nonDer' entries
260+ mergeEqns := listAppend(List . map(innerCrefToOuterOutputCrefs_nonDer, freshMergingEqn), mergeEqns_der);
261+ else
262+ // FIXME add support for outers that don't have "inner outer" or "inner" at closest instance level (requires to introduce a fresh intermediate variable)
263+ mergeEqns := List . map(BaseHashTable . hashTableList(innerCrefToOuterOutputCrefs), freshMergingEqn);
264+ end if ;
228265
229266 // add processed flat state machine and corresponding merging equations to the dae element list
230267 // outElementLst := listAppend(outElementLst, {DAE.FLAT_SM(ident=ident, dAElist=listAppend(dAElist, mergeEqns))}); // put merge equations in FLAT_SM element
231268 outElementLst := listAppend(inStartElementLst, DAE . FLAT_SM (ident= ident, dAElist= dAElist) :: mergeEqns); // put equations after FLAT_SM element
232269end mergeVariableDefinitions;
233270
271+ protected function freshAliasEqn_der "
272+ Author: BTH
273+ Helper function to mergeVariableDefinition.
274+ Create a fresh alias equation between inners and their corresponding outer output variable defintions
275+ "
276+ input tuple< DAE . ComponentRef , list< DAE . ComponentRef >> inInnerCrefToOuterOutputCrefs "tuple relating the inner cref to respective outer crefs" ;
277+ output list< DAE . Element > outEqns;
278+ protected
279+ DAE . ComponentRef innerCref;
280+ List < DAE . ComponentRef > outerCrefs;
281+ DAE . Type ty;
282+ algorithm
283+ (innerCref, outerCrefs) := inInnerCrefToOuterOutputCrefs;
284+ // FIXME use instead 'ty := ComponentReference.crefTypeConsiderSubs(innerCref);'?
285+ ty := ComponentReference . crefLastType(innerCref);
286+ // Alias equations
287+ outEqns := list(DAE . EQUATION (DAE . CREF (innerCref, ty), DAE . CREF (outerCref, ty), DAE . emptyElementSource) for outerCref in outerCrefs);
288+ end freshAliasEqn_der;
289+
290+ protected function freshMergingEqn_der "
291+ Author: BTH
292+ Helper function to mergeVariableDefinition.
293+ Create a fresh equation for merging outer output variable defintions of equations involving der(..)
294+ "
295+ input tuple< DAE . ComponentRef , list< DAE . ComponentRef >> inInnerCrefToOuterOutputCrefs "tuple relating the inner cref to respective outer crefs" ;
296+ output DAE . Element outEqn;
297+ protected
298+ DAE . ComponentRef innerCref;
299+ List < DAE . ComponentRef > outerCrefs, outerCrefsStripped, outerCrefDers;
300+ DAE . Type ty;
301+ DAE . Exp exp;
302+ algorithm
303+ (innerCref, outerCrefs) := inInnerCrefToOuterOutputCrefs;
304+
305+ // FIXME use instead 'ty := ComponentReference.crefTypeConsiderSubs(innerCref);'?
306+ ty := ComponentReference . crefLastType(innerCref);
307+ outerCrefsStripped := List . map(outerCrefs, ComponentReference . crefStripLastIdent);
308+
309+ // FIXME this variables are generated in StateMachineFlatten.addStateActivationAndReset(..) which is UGLY
310+ outerCrefDers := List . map(outerCrefs, function ComponentReference . appendStringLastIdent(inString = "_der$" ));
311+
312+ // der(x)
313+ exp := DAE . CALL (Absyn . IDENT ("der" ), {DAE . CREF (innerCref, ty)}, DAE . callAttrBuiltinReal);
314+ // der(x) = ...
315+ outEqn := DAE . EQUATION (exp, mergingRhs_der(outerCrefDers, innerCref, ty), DAE . emptyElementSource);
316+ end freshMergingEqn_der;
317+
318+ protected function mergingRhs_der "
319+ Author: BTH
320+ Helper function to freshMergingEqn_der.
321+ Create RHS expression of merging equation.
322+ "
323+ input List < DAE . ComponentRef > inOuterCrefs "List of the crefs of the outer variables" ;
324+ input DAE . ComponentRef inInnerCref;
325+ input DAE . Type ty "type of inner cref (inner cref type expected to the same as outer crefs type)" ;
326+ output DAE . Exp res;
327+ protected
328+ DAE . CallAttributes callAttributes = DAE . CALL_ATTR (ty,false ,true ,false ,false ,DAE . NO_INLINE (),DAE . NO_TAIL ());
329+ algorithm
330+ res := match (inOuterCrefs)
331+ local
332+ DAE . ComponentRef outerCref, crefState;
333+ List < DAE . ComponentRef > rest;
334+ DAE . Exp outerCrefExp, innerCrefExp, crefStateExp, ifExp, expCond, expElse;
335+ case (outerCref::{})
336+ equation
337+ outerCrefExp = DAE . CREF (outerCref, ty);
338+ innerCrefExp = DAE . CREF (inInnerCref, ty);
339+ crefState = ComponentReference . crefStripLastIdent(outerCref);
340+ crefStateExp = DAE . CREF (crefState, ty);
341+ expCond = DAE . CALL (Absyn . IDENT ("activeState" ), {crefStateExp}, callAttributes);
342+ expElse = DAE . RCONST (0 );
343+ ifExp = DAE . IFEXP (expCond, outerCrefExp, expElse);
344+ then ifExp;
345+ case (outerCref::rest)
346+ equation
347+ outerCrefExp = DAE . CREF (outerCref, ty);
348+ crefState = ComponentReference . crefStripLastIdent(outerCref);
349+ crefStateExp = DAE . CREF (crefState, ty);
350+ expCond = DAE . CALL (Absyn . IDENT ("activeState" ), {crefStateExp}, callAttributes);
351+ expElse = mergingRhs_der(rest, inInnerCref, ty);
352+ ifExp = DAE . IFEXP (expCond, outerCrefExp, expElse);
353+ then ifExp;
354+ end match;
355+
356+ end mergingRhs_der;
357+
358+ protected function traversingCountDer "
359+ Author: BTH
360+ Helper function to traverse subexpressions
361+ Counts occurances of 'der(cref)'
362+ "
363+ input DAE . Exp inExp;
364+ input tuple< DAE . ComponentRef , Integer > inCref_HitCount "tuple of x and counter for hits of der(x)" ;
365+ output DAE . Exp outExp;
366+ output tuple< DAE . ComponentRef , Integer > outCref_HitCount;
367+ protected
368+ DAE . ComponentRef cref;
369+ Integer hitCount;
370+ algorithm
371+ (cref, hitCount) := inCref_HitCount;
372+ (outExp,outCref_HitCount) := match inExp
373+ local
374+ DAE . ComponentRef componentRef;
375+ list< DAE . Exp > expLst;
376+ DAE . CallAttributes attr;
377+ case DAE . CALL (path= Absyn . IDENT ("der" ), expLst= {DAE . CREF (componentRef= componentRef)})
378+ guard ComponentReference . crefEqual(componentRef, cref)
379+ then (inExp, (cref, hitCount + 1 ));
380+ else (inExp,inCref_HitCount);
381+ end match;
382+ end traversingCountDer;
383+
234384protected function freshMergingEqn "
235385Author: BTH
236386Helper function to mergeVariableDefinition.
237387Create a fresh equation for merging outer output variable defintions
238388"
239- input DAE . ComponentRef inInnerCref;
240- input HashTable3 . HashTable inInnerCrefToOuterOutputCrefs;
389+ input tuple< DAE . ComponentRef , list< DAE . ComponentRef >> inInnerCrefToOuterOutputCrefs "tuple relating the inner cref to respective outer crefs" ;
241390 output DAE . Element outEqn;
242391protected
392+ DAE . ComponentRef innerCref;
243393 List < DAE . ComponentRef > outerCrefs, outerCrefsStripped;
244394 DAE . Type ty;
245395algorithm
246- ty := ComponentReference . crefLastType(inInnerCref);
247- // FIXME use instead 'ty := ComponentReference.crefTypeConsiderSubs(inInnerCref);'?
248- outerCrefs := BaseHashTable . get(inInnerCref, inInnerCrefToOuterOutputCrefs);
396+ (innerCref, outerCrefs) := inInnerCrefToOuterOutputCrefs;
397+
398+ // FIXME BTH use instead 'ty := ComponentReference.crefTypeConsiderSubs(innerCref);'?
399+ ty := ComponentReference . crefLastType(innerCref);
249400 outerCrefsStripped := List . map(outerCrefs, ComponentReference . crefStripLastIdent);
250401
251- outEqn := DAE . EQUATION (DAE . CREF (inInnerCref , ty), mergingRhs(outerCrefs, inInnerCref , ty), DAE . emptyElementSource);
402+ outEqn := DAE . EQUATION (DAE . CREF (innerCref , ty), mergingRhs(outerCrefs, innerCref , ty), DAE . emptyElementSource);
252403end freshMergingEqn;
253404
254405protected function mergingRhs "
0 commit comments