Skip to content

Commit a16e62b

Browse files
author
Jens Frenkel
committed
- fix #2095 handle valid circular equalities
git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@15999 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
1 parent c94cd58 commit a16e62b

File tree

1 file changed

+138
-30
lines changed

1 file changed

+138
-30
lines changed

Compiler/BackEnd/RemoveSimpleEquations.mo

Lines changed: 138 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ protected import HashSet;
7373
protected import Inline;
7474
protected import List;
7575
protected import Util;
76+
protected import Types;
7677

7778
protected type EquationAttributes = tuple<DAE.ElementSource,Boolean> "eqnAttributes";
7879

@@ -1555,7 +1556,7 @@ algorithm
15551556
case (_,_,_,_,_,_,_,_,_)
15561557
equation
15571558
// collect set
1558-
(rmax,smax,unremovable,const,_) = getAlias({index},NONE(),mark,simpleeqnsarr,iMT,iVars,unreplacable,NONE(),NONE(),NONE(),NONE());
1559+
(rmax,smax,unremovable,const,_) = getAlias({index},NONE(),mark,simpleeqnsarr,iMT,iVars,unreplacable,false,{},NONE(),NONE(),NONE(),NONE());
15591560
// traverse set and add replacements, move vars, ...
15601561
(vars,eqnslst,shared,repl) = handleSet(rmax,smax,unremovable,const,mark+1,simpleeqnsarr,iMT,unreplacable,iVars,iEqnslst,ishared,iRepl);
15611562
// next
@@ -1576,6 +1577,8 @@ protected function getAlias
15761577
input array<list<Integer>> iMT;
15771578
input BackendDAE.Variables vars;
15781579
input HashSet.HashSet unreplacable;
1580+
input Boolean negate;
1581+
input list<Integer> stack;
15791582
input Option<tuple<Integer,Integer>> iRmax;
15801583
input Option<tuple<Integer,Integer>> iSmax;
15811584
input Option<Integer> iUnremovable;
@@ -1586,20 +1589,20 @@ protected function getAlias
15861589
output Option<Integer> oConst;
15871590
output Boolean oContinue;
15881591
algorithm
1589-
(oRmax,oSmax,oUnremovable,oConst,oContinue) := match(rows,i,mark,simpleeqnsarr,iMT,vars,unreplacable,iRmax,iSmax,iUnremovable,iConst)
1592+
(oRmax,oSmax,oUnremovable,oConst,oContinue) := match(rows,i,mark,simpleeqnsarr,iMT,vars,unreplacable,negate,stack,iRmax,iSmax,iUnremovable,iConst)
15901593
local
15911594
Integer r;
15921595
list<Integer> rest;
15931596
SimpleContainer s;
15941597
Option<tuple<Integer,Integer>> rmax,smax;
15951598
Option<Integer> unremovable,const;
15961599
Boolean b,continue;
1597-
case ({},_,_,_,_,_,_,_,_,_,_) then (iRmax,iSmax,iUnremovable,iConst,true);
1598-
case (r::rest,_,_,_,_,_,_,_,_,_,_)
1600+
case ({},_,_,_,_,_,_,_,_,_,_,_,_) then (iRmax,iSmax,iUnremovable,iConst,true);
1601+
case (r::rest,_,_,_,_,_,_,_,_,_,_,_,_)
15991602
equation
16001603
s = simpleeqnsarr[r];
16011604
b = isVisited(mark,s);
1602-
(rmax,smax,unremovable,const,continue) = getAlias1(b,s,r,rest,i,mark,simpleeqnsarr,iMT,vars,unreplacable,iRmax,iSmax,iUnremovable,iConst);
1605+
(rmax,smax,unremovable,const,continue) = getAlias1(b,s,r,rest,i,mark,simpleeqnsarr,iMT,vars,unreplacable,negate,stack,iRmax,iSmax,iUnremovable,iConst);
16031606
then
16041607
(rmax,smax,unremovable,const,continue);
16051608
end match;
@@ -1618,6 +1621,8 @@ protected function getAlias1
16181621
input array<list<Integer>> iMT;
16191622
input BackendDAE.Variables vars;
16201623
input HashSet.HashSet unreplacable;
1624+
input Boolean negate;
1625+
input list<Integer> stack;
16211626
input Option<tuple<Integer,Integer>> iRmax;
16221627
input Option<tuple<Integer,Integer>> iSmax;
16231628
input Option<Integer> iUnremovable;
@@ -1629,30 +1634,103 @@ protected function getAlias1
16291634
output Boolean oContinue;
16301635
algorithm
16311636
(oRmax,oSmax,oUnremovable,oConst,oContinue) :=
1632-
match(visited,s,r,rows,i,mark,simpleeqnsarr,iMT,vars,unreplacable,iRmax,iSmax,iUnremovable,iConst)
1637+
matchcontinue(visited,s,r,rows,i,mark,simpleeqnsarr,iMT,vars,unreplacable,negate,stack,iRmax,iSmax,iUnremovable,iConst)
16331638
local
16341639
Option<tuple<Integer,Integer>> rmax,smax;
16351640
Option<Integer> unremovable,const;
16361641
Boolean continue;
1637-
case (true,_,_,_,_,_,_,_,_,_,_,_,_,_)
1638-
equation
1639-
// report error
1640-
Error.addMessage(Error.INTERNAL_ERROR, {"Circular Equalities Detected"});
1641-
then
1642-
fail();
1643-
case (false,_,_,_,_,_,_,_,_,_,_,_,_,_)
1642+
String msg;
1643+
DAE.ComponentRef cr;
1644+
case (false,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_)
16441645
equation
16451646
// set visited
16461647
_= arrayUpdate(simpleeqnsarr,r,setVisited(mark,s));
16471648
// check alias connection
1648-
(rmax,smax,unremovable,const,continue) = getAlias2(s,r,i,mark,simpleeqnsarr,iMT,vars,unreplacable,iRmax,iSmax,iUnremovable,iConst);
1649+
(rmax,smax,unremovable,const,continue) = getAlias2(s,r,i,mark,simpleeqnsarr,iMT,vars,unreplacable,negate,r::stack,iRmax,iSmax,iUnremovable,iConst);
16491650
// next arm
1650-
(rmax,smax,unremovable,const,continue) = getAliasContinue(continue,rows,i,mark,simpleeqnsarr,iMT,vars,unreplacable,rmax,smax,unremovable,const);
1651+
(rmax,smax,unremovable,const,continue) = getAliasContinue(continue,rows,i,mark,simpleeqnsarr,iMT,vars,unreplacable,negate,stack,rmax,smax,unremovable,const);
16511652
then
16521653
(rmax,smax,unremovable,const,continue);
1653-
end match;
1654+
// valid circular equality
1655+
case (true,_,_,_,_,_,_,_,_,_,true,_,_,_,SOME(_),_)
1656+
equation
1657+
// is only valid for real or int
1658+
ALIAS(cr1=cr) = simpleeqnsarr[r];
1659+
true = Types.isIntegerOrRealOrSubTypeOfEither(ComponentReference.crefLastType(cr));
1660+
then
1661+
(NONE(),NONE(),NONE(),iUnremovable,false);
1662+
case (true,_,_,_,_,_,_,_,_,_,true,_,_,_,_,_)
1663+
equation
1664+
// is only valid for real or int
1665+
ALIAS(cr1=cr) = simpleeqnsarr[r];
1666+
true = Types.isIntegerOrRealOrSubTypeOfEither(ComponentReference.crefLastType(cr));
1667+
then
1668+
(NONE(),NONE(),NONE(),SOME(r),false);
1669+
case (true,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_)
1670+
equation
1671+
msg = "Circular Equalities Detected for Variables:\n";
1672+
msg = circularEqualityMsg(stack,r,simpleeqnsarr,msg);
1673+
// report error
1674+
Error.addMessage(Error.INTERNAL_ERROR, {msg});
1675+
then
1676+
fail();
1677+
end matchcontinue;
16541678
end getAlias1;
16551679

1680+
protected function circularEqualityMsg
1681+
"function circularEqualityMsg
1682+
author: Frenkel TUD 2013-05"
1683+
input list<Integer> stack;
1684+
input Integer iR;
1685+
input array<SimpleContainer> simpleeqnsarr;
1686+
input String iMsg;
1687+
output String oMsg;
1688+
algorithm
1689+
oMsg := matchcontinue(stack,iR,simpleeqnsarr,iMsg)
1690+
local
1691+
Integer r;
1692+
list<Integer> rest;
1693+
String msg;
1694+
list<DAE.ComponentRef> names;
1695+
list<String> slst;
1696+
case ({},_,_,_) then iMsg;
1697+
case (r::rest,_,_,_)
1698+
equation
1699+
false = intEq(r,iR);
1700+
names = getVarsNames(simpleeqnsarr[r]);
1701+
slst = List.map(names,ComponentReference.crefStr);
1702+
msg = stringDelimitList(slst,"\n");
1703+
msg = stringAppendList({iMsg,msg,"\n"});
1704+
then
1705+
circularEqualityMsg(rest,iR,simpleeqnsarr,msg);
1706+
case (r::rest,_,_,_)
1707+
equation
1708+
true = intEq(r,iR);
1709+
then
1710+
iMsg;
1711+
end matchcontinue;
1712+
end circularEqualityMsg;
1713+
1714+
protected function getVarsNames
1715+
"function: getVarsNames
1716+
author: Frenkel TUD 2013-05"
1717+
input SimpleContainer iS;
1718+
output list<DAE.ComponentRef> names;
1719+
algorithm
1720+
names := match(iS)
1721+
local
1722+
DAE.ComponentRef cr1,cr2;
1723+
Integer i1,i2;
1724+
EquationAttributes eqnAttributes;
1725+
Boolean negate;
1726+
DAE.Exp exp;
1727+
case (ALIAS(cr1=cr1,cr2=cr2)) then {cr1,cr2};
1728+
case (PARAMETERALIAS(cr=cr1,paramcr=cr2)) then {cr1,cr2};
1729+
case (TIMEALIAS(cr=cr1)) equation then {cr1,DAE.crefTime};
1730+
case (TIMEINDEPENTVAR(cr=cr1)) then {cr1};
1731+
end match;
1732+
end getVarsNames;
1733+
16561734
protected function getAlias2
16571735
"function: getAlias2
16581736
author: Frenkel TUD 2012-12"
@@ -1664,6 +1742,8 @@ protected function getAlias2
16641742
input array<list<Integer>> iMT;
16651743
input BackendDAE.Variables vars;
16661744
input HashSet.HashSet unreplacable;
1745+
input Boolean negate;
1746+
input list<Integer> stack;
16671747
input Option<tuple<Integer,Integer>> iRmax;
16681748
input Option<tuple<Integer,Integer>> iSmax;
16691749
input Option<Integer> iUnremovable;
@@ -1675,15 +1755,15 @@ protected function getAlias2
16751755
output Boolean oContinue;
16761756
algorithm
16771757
(oRmax,oSmax,oUnremovable,oConst,oContinue) :=
1678-
match(s,r,oi,mark,simpleeqnsarr,iMT,vars,unreplacable,iRmax,iSmax,iUnremovable,iConst)
1758+
match(s,r,oi,mark,simpleeqnsarr,iMT,vars,unreplacable,negate,stack,iRmax,iSmax,iUnremovable,iConst)
16791759
local
16801760
list<Integer> next;
16811761
Option<tuple<Integer,Integer>> rmax,smax;
16821762
Option<Integer> unremovable,const;
16831763
BackendDAE.Var v;
16841764
Integer i1,i2,i;
1685-
Boolean state,replacable,continue,replaceble1;
1686-
case (ALIAS(i1=i1,i2=i2),_,NONE(),_,_,_,_,_,_,_,_,_)
1765+
Boolean state,replacable,continue,replaceble1,neg;
1766+
case (ALIAS(i1=i1,i2=i2,negate=neg),_,NONE(),_,_,_,_,_,_,_,_,_,_,_)
16871767
equation
16881768
// collect next rows
16891769
next = List.removeOnTrue(r,intEq,iMT[i1]);
@@ -1693,7 +1773,8 @@ algorithm
16931773
state = BackendVariable.isStateVar(v);
16941774
(rmax,smax,unremovable) = getAlias3(v,i1,state,replacable and replaceble1,r,iRmax,iSmax,iUnremovable);
16951775
// go deeper
1696-
(rmax,smax,unremovable,const,continue) = getAlias(next,SOME(i1),mark,simpleeqnsarr,iMT,vars,unreplacable,rmax,smax,unremovable,iConst);
1776+
neg = Util.if_(neg,not negate,negate);
1777+
(rmax,smax,unremovable,const,continue) = getAlias(next,SOME(i1),mark,simpleeqnsarr,iMT,vars,unreplacable,neg,stack,rmax,smax,unremovable,iConst);
16971778
// collect next rows
16981779
next = List.removeOnTrue(r,intEq,iMT[i2]);
16991780
v = BackendVariable.getVarAt(vars,i2);
@@ -1702,10 +1783,10 @@ algorithm
17021783
state = BackendVariable.isStateVar(v);
17031784
(rmax,smax,unremovable) = getAlias3(v,i2,state,replacable and replaceble1,r,rmax,smax,unremovable);
17041785
// go deeper
1705-
(rmax,smax,unremovable,const,continue) = getAliasContinue(continue,next,SOME(i2),mark,simpleeqnsarr,iMT,vars,unreplacable,rmax,smax,unremovable,const);
1786+
(rmax,smax,unremovable,const,continue) = getAliasContinue(continue,next,SOME(i2),mark,simpleeqnsarr,iMT,vars,unreplacable,neg,stack,rmax,smax,unremovable,const);
17061787
then
17071788
(rmax,smax,unremovable,const,continue);
1708-
case (ALIAS(i1=i1,i2=i2),_,SOME(i),_,_,_,_,_,_,_,_,_)
1789+
case (ALIAS(i1=i1,i2=i2,negate=neg),_,SOME(i),_,_,_,_,_,_,_,_,_,_,_)
17091790
equation
17101791
i = Util.if_(intEq(i,i1),i2,i1);
17111792
// collect next rows
@@ -1716,16 +1797,17 @@ algorithm
17161797
state = BackendVariable.isStateVar(v);
17171798
(rmax,smax,unremovable) = getAlias3(v,i,state,replacable and replaceble1,r,iRmax,iSmax,iUnremovable);
17181799
// go deeper
1719-
(rmax,smax,unremovable,const,continue) = getAlias(next,SOME(i),mark,simpleeqnsarr,iMT,vars,unreplacable,rmax,smax,unremovable,iConst);
1800+
neg = Util.if_(neg,not negate,negate);
1801+
(rmax,smax,unremovable,const,continue) = getAlias(next,SOME(i),mark,simpleeqnsarr,iMT,vars,unreplacable,neg,stack,rmax,smax,unremovable,iConst);
17201802
then
17211803
(rmax,smax,unremovable,const,continue);
1722-
case (PARAMETERALIAS(visited=_),_,_,_,_,_,_,_,_,_,_,_)
1804+
case (PARAMETERALIAS(visited=_),_,_,_,_,_,_,_,_,_,_,_,_,_)
17231805
then
17241806
(NONE(),NONE(),NONE(),SOME(r),false);
1725-
case (TIMEALIAS(visited=_),_,_,_,_,_,_,_,_,_,_,_)
1807+
case (TIMEALIAS(visited=_),_,_,_,_,_,_,_,_,_,_,_,_,_)
17261808
then
17271809
(NONE(),NONE(),NONE(),SOME(r),false);
1728-
case (TIMEINDEPENTVAR(visited=_),_,_,_,_,_,_,_,_,_,_,_)
1810+
case (TIMEINDEPENTVAR(visited=_),_,_,_,_,_,_,_,_,_,_,_,_,_)
17291811
then
17301812
(NONE(),NONE(),NONE(),SOME(r),false);
17311813
end match;
@@ -1796,6 +1878,8 @@ protected function getAliasContinue
17961878
input array<list<Integer>> iMT;
17971879
input BackendDAE.Variables vars;
17981880
input HashSet.HashSet unreplacable;
1881+
input Boolean negate;
1882+
input list<Integer> stack;
17991883
input Option<tuple<Integer,Integer>> iRmax;
18001884
input Option<tuple<Integer,Integer>> iSmax;
18011885
input Option<Integer> iUnremovable;
@@ -1807,18 +1891,18 @@ protected function getAliasContinue
18071891
output Boolean oContinue;
18081892
algorithm
18091893
(oRmax,oSmax,oUnremovable,oConst,oContinue) :=
1810-
match(iContinue,rows,i,mark,simpleeqnsarr,iMT,vars,unreplacable,iRmax,iSmax,iUnremovable,iConst)
1894+
match(iContinue,rows,i,mark,simpleeqnsarr,iMT,vars,unreplacable,negate,stack,iRmax,iSmax,iUnremovable,iConst)
18111895
local
18121896
Option<tuple<Integer,Integer>> rmax,smax;
18131897
Option<Integer> unremovable,const;
18141898
Boolean continue;
1815-
case (true,_,_,_,_,_,_,_,_,_,_,_)
1899+
case (true,_,_,_,_,_,_,_,_,_,_,_,_,_)
18161900
equation
18171901
// update candidates
1818-
(rmax,smax,unremovable,const,continue) = getAlias(rows,i,mark,simpleeqnsarr,iMT,vars,unreplacable,iRmax,iSmax,iUnremovable,iConst);
1902+
(rmax,smax,unremovable,const,continue) = getAlias(rows,i,mark,simpleeqnsarr,iMT,vars,unreplacable,negate,stack,iRmax,iSmax,iUnremovable,iConst);
18191903
then
18201904
(rmax,smax,unremovable,const,continue);
1821-
case (false,_,_,_,_,_,_,_,_,_,_,_)
1905+
case (false,_,_,_,_,_,_,_,_,_,_,_,_,_)
18221906
then
18231907
(iRmax,iSmax,iUnremovable,iConst,iContinue);
18241908
end match;
@@ -2011,6 +2095,30 @@ algorithm
20112095
(vars,eqnslst,shared,repl,vsattr) = traverseAliasTree(rows,i,exp,NONE(),false,SOME(DAE.RCONST(0.0)),mark,simpleeqnsarr,iMT,unreplacable,vars,eqnslst,shared,repl,vsattr);
20122096
then
20132097
(vars,eqnslst,shared,repl);
2098+
// valid circular equality
2099+
case (_,_,_,SOME(r),_,_,_,_,_,_,_,_)
2100+
equation
2101+
s = simpleeqnsarr[r];
2102+
ALIAS(i1=i,i2=i2,eqnAttributes=eqnAttributes) = s;
2103+
_= arrayUpdate(simpleeqnsarr,r,setVisited(mark,s));
2104+
(v as BackendDAE.VAR(varName=cr)) = BackendVariable.getVarAt(iVars,i);
2105+
exp = Util.if_(Types.isRealOrSubTypeReal(ComponentReference.crefLastType(cr)),DAE.RCONST(0.0),DAE.ICONST(0));
2106+
(replacable,replaceble1) = replaceableAlias(v,unreplacable);
2107+
(vars,shared,isState,eqnslst) = optMoveVarShared(replacable,v,i,eqnAttributes,exp,BackendVariable.addKnVarDAE,iMT,iVars,ishared,iEqnslst);
2108+
constExp = Expression.isConst(exp);
2109+
// add to replacements if constant
2110+
repl = Debug.bcallret4(replacable and constExp and replaceble1, BackendVarTransform.addReplacement,iRepl, cr, exp,SOME(BackendVarTransform.skipPreChangeEdgeOperator),iRepl);
2111+
// if state der(var) has to replaced to 0
2112+
repl = Debug.bcallret3(isState,BackendVarTransform.addDerConstRepl, cr, DAE.RCONST(0.0), repl, repl);
2113+
exp = Expression.crefExp(cr);
2114+
vsattr = addVarSetAttributes(v,false,mark,simpleeqnsarr,EMPTYVARSETATTRIBUTES);
2115+
rows = List.removeOnTrue(r,intEq,iMT[i2]);
2116+
_ = arrayUpdate(iMT,i2,rows);
2117+
rows = List.removeOnTrue(r,intEq,iMT[i]);
2118+
_ = arrayUpdate(iMT,i,{});
2119+
(vars,eqnslst,shared,repl,vsattr) = traverseAliasTree(rows,i,exp,NONE(),false,SOME(DAE.RCONST(0.0)),mark,simpleeqnsarr,iMT,unreplacable,vars,eqnslst,shared,repl,vsattr);
2120+
then
2121+
(vars,eqnslst,shared,repl);
20142122
// variable set state
20152123
case (_,SOME((i,_)),_,NONE(),_,_,_,_,_,_,_,_)
20162124
equation

0 commit comments

Comments
 (0)