@@ -94,6 +94,7 @@ import Global;
9494import Graph;
9595import HashSet;
9696import HashSetExp;
97+ import HashTableSimCodeEqCache;
9798import HpcOmSimCode;
9899import Inline;
99100import List;
@@ -141,6 +142,42 @@ algorithm
141142 // ((i, ht, literals)) := BackendDAEUtil.traverseBackendDAEExpsNoCopyWithUpdate(dae, findLiteralsHelper, (i, ht, literals));
142143end simulationFindLiterals;
143144
145+ public function hashEqSystemMod
146+ input SimCode.SimEqSystem eq;
147+ input Integer mod;
148+ output Integer hash;
149+ algorithm
150+ hash := match eq
151+ local
152+ DAE.Statement stmt;
153+ case SimCode.SES_RESIDUAL() then Expression.hashExpMod(eq.exp, mod);
154+ case SimCode.SES_SIMPLE_ASSIGN() then intMod(ComponentReference.hashComponentRefMod(eq.cref,mod)+7*Expression.hashExpMod(eq.exp, mod), mod);
155+ case SimCode.SES_SIMPLE_ASSIGN_CONSTRAINTS() then intMod(ComponentReference.hashComponentRefMod(eq.cref,mod)+7*Expression.hashExpMod(eq.exp, mod), mod);
156+ case SimCode.SES_ARRAY_CALL_ASSIGN() then intMod(Expression.hashExpMod(eq.lhs, mod)+7*Expression.hashExpMod(eq.exp, mod), mod);
157+ case SimCode.SES_ALGORITHM(statements={stmt as DAE.STMT_ASSERT()}) then intMod(Expression.hashExpMod(stmt.cond, mod)+7*Expression.hashExpMod(stmt.msg, mod)+49*Expression.hashExpMod(stmt.level, mod), mod);
158+ // Whatever; we're not caching these values anyway
159+ else intMod(valueConstructor(eq), mod);
160+ end match;
161+ end hashEqSystemMod;
162+
163+ public function compareEqSystemsEquality "Is true if the equations are the same except the index. If false they might still be the same."
164+ input SimCode.SimEqSystem eq1;
165+ input SimCode.SimEqSystem eq2;
166+ output Boolean b;
167+ algorithm
168+ b := match (eq1,eq2)
169+ local
170+ DAE.Statement stmt1,stmt2;
171+ case (SimCode.SES_SIMPLE_ASSIGN(),SimCode.SES_SIMPLE_ASSIGN())
172+ then if 0==ComponentReference.crefCompareGeneric(eq1.cref, eq2.cref) then Expression.expEqual(eq1.exp, eq2.exp) else false;
173+ case (SimCode.SES_ARRAY_CALL_ASSIGN(),SimCode.SES_ARRAY_CALL_ASSIGN())
174+ then if Expression.expEqual(eq1.lhs, eq2.lhs) then Expression.expEqual(eq1.exp, eq2.exp) else false;
175+ case (SimCode.SES_ALGORITHM(statements={stmt1 as DAE.STMT_ASSERT()}),SimCode.SES_ALGORITHM(statements={stmt2 as DAE.STMT_ASSERT()}))
176+ then if Expression.expEqual(stmt1.cond, stmt2.cond) then (if Expression.expEqual(stmt1.msg, stmt2.msg) then Expression.expEqual(stmt1.level, stmt2.level) else false) else false;
177+ else false;
178+ end match;
179+ end compareEqSystemsEquality;
180+
144181// =============================================================================
145182// section to create SimCode from BackendDAE
146183//
@@ -182,7 +219,7 @@ protected
182219 HashTableCrIListArray.HashTable varToArrayIndexMapping "maps each array-variable to a array of positions";
183220 HashTableCrILst.HashTable varToIndexMapping "maps each variable to an array position";
184221 Integer maxDelayedExpIndex, uniqueEqIndex, numberofEqns, numStateSets, numberOfJacobians, sccOffset;
185- Integer numberofLinearSys, numberofNonLinearSys, numberofMixedSys, numberofFixedParameters;
222+ Integer numberofLinearSys, numberofNonLinearSys, numberofMixedSys, numberofFixedParameters, reasonableSize ;
186223 Option<SimCode.FmiModelStructure> modelStructure = NONE();
187224 SimCode.BackendMapping backendMapping;
188225 SimCode.ExtObjInfo extObjInfo;
@@ -237,6 +274,7 @@ protected
237274 Integer SymEuler_help = 0;
238275 SimCodeVar.SimVar dtSimVar;
239276 BackendDAE.Var dtVar;
277+ HashTableSimCodeEqCache.HashTable eqCache;
240278
241279 constant Boolean debug = false;
242280algorithm
@@ -490,7 +528,6 @@ algorithm
490528 if Flags.isSet(Flags.EXEC_HASH) then
491529 print("*** SimCode -> generate cref2simVar hashtable done!: " + realString(clock()) + "\n");
492530 end if;
493-
494531 // add known inline vars to simVarHT
495532 if (Flags.getConfigEnum(Flags.SYM_SOLVER) > 0) then
496533 SOME(inlineData) := inInlineData;
@@ -526,6 +563,20 @@ algorithm
526563
527564 (crefToClockIndexHT, _) := List.fold(listReverse(inBackendDAE.eqs), collectClockedVars, (HashTable.emptyHashTable(), 1));
528565
566+ reasonableSize := Util.nextPrime(10+2*listLength(allEquations));
567+ eqCache := HashTableSimCodeEqCache.emptyHashTableSized(reasonableSize);
568+
569+ (allEquations, eqCache) := aliasSimEqs(allEquations, eqCache);
570+ (odeEquations, eqCache) := aliasSimEqSystems(odeEquations, eqCache);
571+ (algebraicEquations, eqCache) := aliasSimEqSystems(algebraicEquations, eqCache);
572+ (initialEquations, eqCache) := aliasSimEqs(initialEquations, eqCache);
573+ (initialEquations_lambda0, eqCache) := aliasSimEqs(initialEquations_lambda0, eqCache);
574+ (removedEquations, eqCache) := aliasSimEqs(removedEquations, eqCache);
575+ (removedInitialEquations, eqCache) := aliasSimEqs(removedInitialEquations, eqCache);
576+ (algorithmAndEquationAsserts, eqCache) := aliasSimEqs(algorithmAndEquationAsserts, eqCache);
577+ (jacobianEquations, eqCache) := aliasSimEqs(jacobianEquations, eqCache);
578+ (parameterEquations, eqCache) := aliasSimEqs(parameterEquations, eqCache);
579+
529580 simCode := SimCode.SIMCODE(modelInfo,
530581 {}, // Set by the traversal below...
531582 recordDecls,
@@ -1503,7 +1554,6 @@ algorithm
15031554 BackendDump.dumpEquationList(eqnlst,"Equations:");
15041555 BackendDump.dumpVarList(varlst,"Variables:");
15051556 end if;
1506-
15071557 // skip is when equations
15081558 skip := List.mapBoolAnd(eqnlst, BackendEquation.isWhenEquation);
15091559 // skip is discrete
@@ -1694,7 +1744,7 @@ protected function appendSccIdxRange
16941744 input Integer iCurrentIdxStop;
16951745 input Integer iSccIdx;
16961746 input list<tuple<Integer,Integer>> iSccIdc;
1697- output list<tuple<Integer,Integer>> oSccIdc;
1747+ output list<tuple<Integer,Integer>> oSccIdc = iSccIdc ;
16981748algorithm
16991749 for i in iCurrentIdxStop:-1:iCurrentIdxStart loop
17001750 oSccIdc := ((i,iSccIdx))::iSccIdc;
@@ -2021,16 +2071,24 @@ protected
20212071 BackendDAE.Variables vars;
20222072 BackendDAE.EquationArray eqns;
20232073 BackendDAE.Equation eqn;
2074+ BackendDAE.Var v;
20242075algorithm
20252076 BackendDAE.EQSYSTEM(orderedVars=vars, orderedEqs=eqns) := syst;
20262077 eqn := BackendEquation.get(eqns, eqNum);
2078+ _ := match eqn
2079+ case BackendDAE.WHEN_EQUATION() then ();
2080+ else
2081+ algorithm
2082+ v := BackendVariable.getVarAt(vars, varNum);
2083+ then ();
2084+ end match;
2085+
20272086 (equation_, ouniqueEqIndex, otempvars) := match eqn
20282087 local
20292088 DAE.ComponentRef cr;
20302089 BackendDAE.VarKind kind;
20312090 Option<DAE.VariableAttributes> values;
2032- BackendDAE.Var v;
2033- Integer uniqueEqIndex;
2091+ Integer uniqueEqIndex1, uniqueEqIndex;
20342092 list<DAE.Statement> algStatements;
20352093 list<DAE.ComponentRef> conditions, solveCr;
20362094 list<SimCode.SimEqSystem> resEqs;
@@ -2057,10 +2115,10 @@ algorithm
20572115
20582116 // solved equation
20592117 case BackendDAE.SOLVED_EQUATION(exp=e2, source=source, attr=eqAttr)
2060- equation
2061- (v as BackendDAE.VAR(varName = cr)) = BackendVariable.getVarAt(vars, varNum) ;
2062- varexp = Expression.crefExp(cr);
2063- varexp = if BackendVariable.isStateVar(v) then Expression.expDer(varexp) else varexp;
2118+ algorithm
2119+ cr := v.varName ;
2120+ varexp : = Expression.crefExp(cr);
2121+ varexp : = if BackendVariable.isStateVar(v) then Expression.expDer(varexp) else varexp;
20642122 then
20652123 ({SimCode.SES_SIMPLE_ASSIGN(iuniqueEqIndex, cr, e2, source, eqAttr)}, iuniqueEqIndex+1, itempvars);
20662124
@@ -2083,7 +2141,7 @@ algorithm
20832141 // single equation
20842142 case BackendDAE.EQUATION(exp=e1, scalar=e2, source=source, attr=eqAttr)
20852143 algorithm
2086- (v as BackendDAE.VAR(varName = cr)) := BackendVariable.getVarAt(vars, varNum) ;
2144+ cr := v.varName ;
20872145 varexp := Expression.crefExp(cr);
20882146 varexp := if BackendVariable.isStateVar(v) then Expression.expDer(varexp) else varexp;
20892147 BackendDAE.SHARED(functionTree = funcs) := shared;
@@ -2098,11 +2156,11 @@ algorithm
20982156 solveCr := listReverse(solveCr);
20992157 cr := if BackendVariable.isStateVar(v) then ComponentReference.crefPrefixDer(cr) else cr;
21002158 source := ElementSource.addSymbolicTransformationSolve(true, source, cr, e1, e2, exp_, asserts);
2101- (eqSystlst, uniqueEqIndex ) := List.mapFold(solveEqns, makeSolved_SES_SIMPLE_ASSIGN, iuniqueEqIndex);
2159+ (eqSystlst, uniqueEqIndex1 ) := List.mapFold(solveEqns, makeSolved_SES_SIMPLE_ASSIGN, iuniqueEqIndex);
21022160 if listEmpty(cons) then
2103- (resEqs, uniqueEqIndex) := addAssertEqn(asserts, {SimCode.SES_SIMPLE_ASSIGN(uniqueEqIndex , cr, exp_, source, eqAttr)}, uniqueEqIndex +1);
2161+ (resEqs, uniqueEqIndex) := addAssertEqn(asserts, {SimCode.SES_SIMPLE_ASSIGN(uniqueEqIndex1 , cr, exp_, source, eqAttr)}, uniqueEqIndex1 +1);
21042162 else
2105- (resEqs, uniqueEqIndex) := addAssertEqn(asserts, {SimCode.SES_SIMPLE_ASSIGN_CONSTRAINTS(uniqueEqIndex , cr, exp_, source, cons, eqAttr)}, uniqueEqIndex +1);
2163+ (resEqs, uniqueEqIndex) := addAssertEqn(asserts, {SimCode.SES_SIMPLE_ASSIGN_CONSTRAINTS(uniqueEqIndex1 , cr, exp_, source, cons, eqAttr)}, uniqueEqIndex1 +1);
21062164 end if;
21072165 eqSystlst := listAppend(eqSystlst,resEqs);
21082166 tempvars := createTempVarsforCrefs(List.map(solveCr, Expression.crefExp),itempvars);
@@ -2141,7 +2199,6 @@ algorithm
21412199 case BackendDAE.ALGORITHM(alg=alg, source=source, expand=crefExpand, attr=eqAttr)
21422200 algorithm
21432201 varOutput::{} := CheckModel.checkAndGetAlgorithmOutputs(alg, source, crefExpand);
2144- v := BackendVariable.getVarAt(vars, varNum);
21452202 // The output variable of the algorithm must be the variable solved
21462203 // for, otherwise we need to solve an inverse problem of an algorithm
21472204 // section.
@@ -7290,7 +7347,7 @@ algorithm
72907347end dumpSimEqSystemLst;
72917348
72927349
7293- protected function simEqSystemString
7350+ public function simEqSystemString
72947351"outputs a string representation of the given SimEqSystem.
72957352author:Waurich TUD 2016-04"
72967353 input SimCode.SimEqSystem eqSysIn;
@@ -7422,6 +7479,11 @@ algorithm
74227479 s = s+"end for;";
74237480 then s;
74247481
7482+ case SimCode.SES_ALIAS()
7483+ equation
7484+ s = String(eqSysIn.index) +": alias of "+ String(eqSysIn.aliasOf);
7485+ then s;
7486+
74257487 else
74267488 then
74277489 "SOMETHING DIFFERENT\n";
@@ -8889,6 +8951,7 @@ algorithm
88898951 case SimCode.SES_MIXED(index=index) then index;
88908952 case SimCode.SES_WHEN(index=index) then index;
88918953 case SimCode.SES_FOR_LOOP(index=index) then index;
8954+ case SimCode.SES_ALIAS(index=index) then index;
88928955 else
88938956 equation
88948957 Error.addMessage(Error.INTERNAL_ERROR,{"SimCodeUtil.simEqSystemIndex failed"});
@@ -10379,6 +10442,14 @@ algorithm
1037910442 case (SimCode.SES_FOR_LOOP(), _, a)
1038010443 /* TODO: Me */
1038110444 then (eq, a);
10445+
10446+ case (SimCode.SES_ALIAS(), _, a)
10447+ then (eq, a);
10448+
10449+ else
10450+ algorithm
10451+ Error.addInternalError(getInstanceName() + " got unknown equation", sourceInfo());
10452+ then fail();
1038210453 end match;
1038310454end traverseExpsEqSystem;
1038410455
@@ -13061,5 +13132,44 @@ algorithm
1306113132 end match;
1306213133end findResources;
1306313134
13135+ function aliasSimEqSystems
13136+ input output list<list<SimCode.SimEqSystem>> eqs;
13137+ input output HashTableSimCodeEqCache.HashTable cache;
13138+ algorithm
13139+ (eqs, cache) := List.mapFold(eqs, aliasSimEqs, cache);
13140+ end aliasSimEqSystems;
13141+
13142+ function aliasSimEqs
13143+ input output list<SimCode.SimEqSystem> eqs;
13144+ input output HashTableSimCodeEqCache.HashTable cache;
13145+ algorithm
13146+ (eqs, cache) := List.mapFold(eqs, aliasSimEq, cache);
13147+ end aliasSimEqs;
13148+
13149+ function aliasSimEq
13150+ input output SimCode.SimEqSystem eq;
13151+ input output HashTableSimCodeEqCache.HashTable cache;
13152+ protected
13153+ Integer ix, aliasOf;
13154+ algorithm
13155+ ix := simEqSystemIndex(eq);
13156+ if BaseHashTable.hasKey(eq,cache) then
13157+ aliasOf := BaseHashTable.get(eq,cache);
13158+ if aliasOf <> ix then
13159+ eq := SimCode.SES_ALIAS(ix, BaseHashTable.get(eq,cache));
13160+ end if;
13161+ return;
13162+ end if;
13163+ if match eq
13164+ case SimCode.SES_SIMPLE_ASSIGN() then true;
13165+ case SimCode.SES_ARRAY_CALL_ASSIGN() then true;
13166+ case SimCode.SES_ALGORITHM(statements={DAE.STMT_NORETCALL()}) then true;
13167+ // TODO: Check if LS / NLS are equal and alias the whole systems?
13168+ else false;
13169+ end match then
13170+ cache := BaseHashTable.add((eq,ix), cache);
13171+ end if;
13172+ end aliasSimEq;
13173+
1306413174annotation(__OpenModelica_Interface="backend");
1306513175end SimCodeUtil;
0 commit comments