Skip to content
This repository was archived by the owner on May 18, 2019. It is now read-only.

Commit a4417ed

Browse files
perostOpenModelica-Hudson
authored andcommitted
NFInst improvements.
- Move if equation branch selection and for loop unrolling to NFFlatten, so it's done before resolving connections. - Check that connect isn't used in an if equation with non-parameter condition. - Move NFConnectionSets.Connection to its own file. Belonging to [master]: - #2022 - OpenModelica/OpenModelica-testsuite#782
1 parent 517bf93 commit a4417ed

File tree

12 files changed

+427
-139
lines changed

12 files changed

+427
-139
lines changed

Compiler/NFFrontEnd/NFComponentRef.mo

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -542,5 +542,28 @@ public
542542
end match;
543543
end stripSubscriptsAll;
544544

545+
function simplifySubscripts
546+
input output ComponentRef cref;
547+
algorithm
548+
cref := match cref
549+
local
550+
list<Subscript> subs;
551+
552+
case CREF(subscripts = {})
553+
algorithm
554+
cref.restCref := simplifySubscripts(cref.restCref);
555+
then
556+
cref;
557+
558+
case CREF()
559+
algorithm
560+
subs := list(Subscript.simplify(s) for s in cref.subscripts);
561+
then
562+
CREF(cref.node, subs, cref.ty, cref.origin, simplifySubscripts(cref.restCref));
563+
564+
else cref;
565+
end match;
566+
end simplifySubscripts;
567+
545568
annotation(__OpenModelica_Interface="frontend");
546569
end NFComponentRef;

Compiler/NFFrontEnd/NFConnectionSets.mo

Lines changed: 1 addition & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -33,37 +33,13 @@ encapsulated package NFConnectionSets
3333
import DisjointSets;
3434
import Connector = NFConnector;
3535
import Connection = NFConnection;
36+
import Connections = NFConnections;
3637

3738
protected
3839
import Flags;
3940
import List;
4041

4142
public
42-
uniontype Connections
43-
record CONNECTIONS
44-
list<Connection> connections;
45-
list<Connector> flows;
46-
end CONNECTIONS;
47-
48-
function new
49-
output Connections conns = CONNECTIONS({}, {});
50-
end new;
51-
52-
function addConnection
53-
input Connection conn;
54-
input output Connections conns;
55-
algorithm
56-
conns.connections := conn :: conns.connections;
57-
end addConnection;
58-
59-
function addFlow
60-
input Connector conn;
61-
input output Connections conns;
62-
algorithm
63-
conns.flows := conn :: conns.flows;
64-
end addFlow;
65-
end Connections;
66-
6743
package ConnectionSets
6844
extends DisjointSets(redeclare type Entry = Connector);
6945

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
/*
2+
* This file is part of OpenModelica.
3+
*
4+
* Copyright (c) 1998-CurrentYear, Linköping University,
5+
* Department of Computer and Information Science,
6+
* SE-58183 Linköping, Sweden.
7+
*
8+
* All rights reserved.
9+
*
10+
* THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3
11+
* AND THIS OSMC PUBLIC LICENSE (OSMC-PL).
12+
* ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES RECIPIENT'S
13+
* ACCEPTANCE OF THE OSMC PUBLIC LICENSE.
14+
*
15+
* The OpenModelica software and the Open Source Modelica
16+
* Consortium (OSMC) Public License (OSMC-PL) are obtained
17+
* from Linköping University, either from the above address,
18+
* from the URLs: http://www.ida.liu.se/projects/OpenModelica or
19+
* http://www.openmodelica.org, and in the OpenModelica distribution.
20+
* GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html.
21+
*
22+
* This program is distributed WITHOUT ANY WARRANTY; without
23+
* even the implied warranty of MERCHANTABILITY or FITNESS
24+
* FOR A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH
25+
* IN THE BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS
26+
* OF OSMC-PL.
27+
*
28+
* See the full OSMC Public License conditions for more details.
29+
*
30+
*/
31+
32+
encapsulated uniontype NFConnections
33+
import Connection = NFConnection;
34+
import Connector = NFConnector;
35+
import NFFlatten.Elements;
36+
37+
protected
38+
import Equation = NFEquation;
39+
import ComponentRef = NFComponentRef;
40+
import Connections = NFConnections;
41+
import NFComponent.Component;
42+
import NFInstNode.InstNode;
43+
import Expression = NFExpression;
44+
import Type = NFType;
45+
import MetaModelica.Dangerous.listReverseInPlace;
46+
47+
public
48+
record CONNECTIONS
49+
list<Connection> connections;
50+
list<Connector> flows;
51+
end CONNECTIONS;
52+
53+
function new
54+
output Connections conns = CONNECTIONS({}, {});
55+
end new;
56+
57+
function addConnection
58+
input Connection conn;
59+
input output Connections conns;
60+
algorithm
61+
conns.connections := conn :: conns.connections;
62+
end addConnection;
63+
64+
function addFlow
65+
input Connector conn;
66+
input output Connections conns;
67+
algorithm
68+
conns.flows := conn :: conns.flows;
69+
end addFlow;
70+
71+
function collect
72+
input output Elements elements;
73+
output Connections conns = new();
74+
protected
75+
Component comp;
76+
ComponentRef cr, lhs, rhs;
77+
Connector c1, c2;
78+
Type ty1, ty2;
79+
SourceInfo info;
80+
list<Equation> eql = {};
81+
algorithm
82+
// Collect all flow variables.
83+
for c in elements.components loop
84+
() := match c
85+
case (cr, _)
86+
algorithm
87+
comp := InstNode.component(ComponentRef.node(cr));
88+
89+
if Component.isFlow(comp) then
90+
c1 := Connector.fromFacedCref(cr, Component.getType(comp),
91+
NFConnector.Face.INSIDE, Component.info(comp));
92+
conns := addFlow(c1, conns);
93+
end if;
94+
then
95+
();
96+
97+
else ();
98+
end match;
99+
end for;
100+
101+
// Collect all connects.
102+
for eq in elements.equations loop
103+
eql := match eq
104+
case Equation.CONNECT(lhs = Expression.CREF(cref = lhs, ty = ty1),
105+
rhs = Expression.CREF(cref = rhs, ty = ty2), info = info)
106+
algorithm
107+
c1 := Connector.fromCref(lhs, ty1, info);
108+
c2 := Connector.fromCref(rhs, ty2, info);
109+
conns := addConnection(Connection.CONNECTION(c1, c2), conns);
110+
then
111+
eql;
112+
113+
else eq :: eql;
114+
end match;
115+
end for;
116+
117+
if not listEmpty(conns.connections) then
118+
elements.equations := listReverseInPlace(eql);
119+
end if;
120+
end collect;
121+
122+
annotation(__OpenModelica_Interface="frontend");
123+
end NFConnections;

Compiler/NFFrontEnd/NFConnector.mo

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ public
7777
protected
7878
InstNode node = ComponentRef.node(cref);
7979
algorithm
80-
conn := CONNECTOR(cref, ty, face,
80+
conn := CONNECTOR(ComponentRef.simplifySubscripts(cref), ty, face,
8181
Component.connectorType(InstNode.component(node)), NONE(),
8282
ElementSource.createElementSource(InstNode.info(node)));
8383
end fromFacedCref;

Compiler/NFFrontEnd/NFConvertDAE.mo

Lines changed: 6 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -503,11 +503,12 @@ algorithm
503503
then
504504
DAE.Element.ARRAY_EQUATION(dims, e1, e2, src) :: elements;
505505

506+
// For equations should have been unrolled here.
506507
case Equation.FOR()
507508
algorithm
508-
body := convertEquations(eq.body);
509+
assert(false, getInstanceName() + " got a for equation");
509510
then
510-
unrollForLoop(eq.iterator, body, elements);
511+
fail();
511512

512513
case Equation.IF()
513514
then convertIfEquation(eq.branches, eq.info, isInitial = false) :: elements;
@@ -550,35 +551,6 @@ algorithm
550551
end match;
551552
end convertEquation;
552553

553-
function unrollForLoop
554-
input InstNode iterator;
555-
input list<DAE.Element> forBody;
556-
input output list<DAE.Element> elements;
557-
protected
558-
Binding binding;
559-
Expression range;
560-
list<DAE.Element> body;
561-
RangeIterator range_iter;
562-
list<DAE.Exp> values;
563-
DAE.ComponentRef iter_cr;
564-
algorithm
565-
// Get the range to iterate over.
566-
Component.ITERATOR(binding = binding) := InstNode.component(iterator);
567-
SOME(range) := Binding.typedExp(binding);
568-
range_iter := RangeIterator.fromExp(range);
569-
values := list(Expression.toDAE(e) for e in RangeIterator.toListReverse(range_iter));
570-
571-
// Create a DAE.ComponentRef for the replace function. The type doesn't matter
572-
// here, only the name is used when replacing.
573-
iter_cr := DAE.CREF_IDENT(InstNode.name(iterator), DAE.Type.T_UNKNOWN(), {});
574-
575-
// Unroll the loop by iterating over the body and replacing the iterator with its value.
576-
for v in values loop
577-
body := DAEUtil.replaceCrefInDAEElements(forBody, iter_cr, v);
578-
elements := listAppend(body, elements);
579-
end for;
580-
end unrollForLoop;
581-
582554
function convertIfEquation
583555
input list<tuple<Expression, list<Equation>>> ifBranches;
584556
input SourceInfo info;
@@ -670,11 +642,12 @@ algorithm
670642
then
671643
DAE.Element.INITIAL_ARRAY_EQUATION(dims, e1, e2, src) :: elements;
672644

645+
// For equations should have been unrolled here.
673646
case Equation.FOR()
674647
algorithm
675-
body := convertInitialEquations(eq.body);
648+
assert(false, getInstanceName() + " got a for equation");
676649
then
677-
unrollForLoop(eq.iterator, body, elements);
650+
fail();
678651

679652
case Equation.IF()
680653
then convertIfEquation(eq.branches, eq.info, isInitial = true) :: elements;

Compiler/NFFrontEnd/NFEquation.mo

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,5 +108,108 @@ public
108108
SourceInfo info;
109109
end NORETCALL;
110110

111+
function mapExp
112+
input output Equation eq;
113+
input MapFn func;
114+
115+
partial function MapFn
116+
input output Expression exp;
117+
end MapFn;
118+
algorithm
119+
eq := match eq
120+
local
121+
Expression e1, e2, e3;
122+
123+
case EQUALITY()
124+
algorithm
125+
e1 := func(eq.lhs);
126+
e2 := func(eq.rhs);
127+
then
128+
if referenceEq(e1, eq.lhs) and referenceEq(e2, eq.rhs)
129+
then eq else EQUALITY(e1, e2, eq.ty, eq.info);
130+
131+
case ARRAY_EQUALITY()
132+
algorithm
133+
e1 := func(eq.lhs);
134+
e2 := func(eq.rhs);
135+
then
136+
if referenceEq(e1, eq.lhs) and referenceEq(e2, eq.rhs)
137+
then eq else ARRAY_EQUALITY(e1, e2, eq.ty, eq.info);
138+
139+
case CONNECT()
140+
algorithm
141+
e1 := func(eq.lhs);
142+
e2 := func(eq.rhs);
143+
then
144+
if referenceEq(e1, eq.lhs) and referenceEq(e2, eq.rhs)
145+
then eq else CONNECT(e1, e2, eq.info);
146+
147+
case FOR()
148+
algorithm
149+
eq.body := list(mapExp(e, func) for e in eq.body);
150+
then
151+
eq;
152+
153+
case IF()
154+
algorithm
155+
eq.branches := list(mapExpBranch(b, func) for b in eq.branches);
156+
then
157+
eq;
158+
159+
case WHEN()
160+
algorithm
161+
eq.branches := list(mapExpBranch(b, func) for b in eq.branches);
162+
then
163+
eq;
164+
165+
case ASSERT()
166+
algorithm
167+
e1 := func(eq.condition);
168+
e2 := func(eq.message);
169+
e3 := func(eq.level);
170+
then
171+
if referenceEq(e1, eq.condition) and referenceEq(e2, eq.message) and
172+
referenceEq(e3, eq.level) then eq else ASSERT(e1, e2, e3, eq.info);
173+
174+
case TERMINATE()
175+
algorithm
176+
e1 := func(eq.message);
177+
then
178+
if referenceEq(e1, eq.message) then eq else TERMINATE(e1, eq.info);
179+
180+
case REINIT()
181+
algorithm
182+
e1 := func(eq.cref);
183+
e2 := func(eq.reinitExp);
184+
then
185+
if referenceEq(e1, eq.cref) and referenceEq(e2, eq.reinitExp) then
186+
eq else REINIT(e1, e2, eq.info);
187+
188+
case NORETCALL()
189+
algorithm
190+
e1 := func(eq.exp);
191+
then
192+
if referenceEq(e1, eq.exp) then eq else NORETCALL(e1, eq.info);
193+
194+
end match;
195+
end mapExp;
196+
197+
function mapExpBranch
198+
input output tuple<Expression, list<Equation>> branch;
199+
input MapFn func;
200+
201+
partial function MapFn
202+
input output Expression exp;
203+
end MapFn;
204+
protected
205+
Expression cond;
206+
list<Equation> eql;
207+
algorithm
208+
(cond, eql) := branch;
209+
cond := func(cond);
210+
eql := list(mapExp(e, func) for e in eql);
211+
branch := (cond, eql);
212+
end mapExpBranch;
213+
111214
annotation(__OpenModelica_Interface="frontend");
112215
end NFEquation;

0 commit comments

Comments
 (0)