Skip to content

Commit

Permalink
NFInst improvements.
Browse files Browse the repository at this point in the history
- 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]:
  - OpenModelica/OMCompiler#2022
  - OpenModelica/OpenModelica-testsuite#782
  • Loading branch information
perost authored and OpenModelica-Hudson committed Nov 15, 2017
1 parent 517bf93 commit a4417ed
Show file tree
Hide file tree
Showing 12 changed files with 427 additions and 139 deletions.
23 changes: 23 additions & 0 deletions Compiler/NFFrontEnd/NFComponentRef.mo
Expand Up @@ -542,5 +542,28 @@ public
end match;
end stripSubscriptsAll;

function simplifySubscripts
input output ComponentRef cref;
algorithm
cref := match cref
local
list<Subscript> subs;

case CREF(subscripts = {})
algorithm
cref.restCref := simplifySubscripts(cref.restCref);
then
cref;

case CREF()
algorithm
subs := list(Subscript.simplify(s) for s in cref.subscripts);
then
CREF(cref.node, subs, cref.ty, cref.origin, simplifySubscripts(cref.restCref));

else cref;
end match;
end simplifySubscripts;

annotation(__OpenModelica_Interface="frontend");
end NFComponentRef;
26 changes: 1 addition & 25 deletions Compiler/NFFrontEnd/NFConnectionSets.mo
Expand Up @@ -33,37 +33,13 @@ encapsulated package NFConnectionSets
import DisjointSets;
import Connector = NFConnector;
import Connection = NFConnection;
import Connections = NFConnections;

protected
import Flags;
import List;

public
uniontype Connections
record CONNECTIONS
list<Connection> connections;
list<Connector> flows;
end CONNECTIONS;

function new
output Connections conns = CONNECTIONS({}, {});
end new;

function addConnection
input Connection conn;
input output Connections conns;
algorithm
conns.connections := conn :: conns.connections;
end addConnection;

function addFlow
input Connector conn;
input output Connections conns;
algorithm
conns.flows := conn :: conns.flows;
end addFlow;
end Connections;

package ConnectionSets
extends DisjointSets(redeclare type Entry = Connector);

Expand Down
123 changes: 123 additions & 0 deletions Compiler/NFFrontEnd/NFConnections.mo
@@ -0,0 +1,123 @@
/*
* This file is part of OpenModelica.
*
* Copyright (c) 1998-CurrentYear, Linköping University,
* Department of Computer and Information Science,
* SE-58183 Linköping, Sweden.
*
* All rights reserved.
*
* THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3
* AND THIS OSMC PUBLIC LICENSE (OSMC-PL).
* ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES RECIPIENT'S
* ACCEPTANCE OF THE OSMC PUBLIC LICENSE.
*
* The OpenModelica software and the Open Source Modelica
* Consortium (OSMC) Public License (OSMC-PL) are obtained
* from Linköping University, either from the above address,
* from the URLs: http://www.ida.liu.se/projects/OpenModelica or
* http://www.openmodelica.org, and in the OpenModelica distribution.
* GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html.
*
* This program is distributed WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH
* IN THE BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS
* OF OSMC-PL.
*
* See the full OSMC Public License conditions for more details.
*
*/

encapsulated uniontype NFConnections
import Connection = NFConnection;
import Connector = NFConnector;
import NFFlatten.Elements;

protected
import Equation = NFEquation;
import ComponentRef = NFComponentRef;
import Connections = NFConnections;
import NFComponent.Component;
import NFInstNode.InstNode;
import Expression = NFExpression;
import Type = NFType;
import MetaModelica.Dangerous.listReverseInPlace;

public
record CONNECTIONS
list<Connection> connections;
list<Connector> flows;
end CONNECTIONS;

function new
output Connections conns = CONNECTIONS({}, {});
end new;

function addConnection
input Connection conn;
input output Connections conns;
algorithm
conns.connections := conn :: conns.connections;
end addConnection;

function addFlow
input Connector conn;
input output Connections conns;
algorithm
conns.flows := conn :: conns.flows;
end addFlow;

function collect
input output Elements elements;
output Connections conns = new();
protected
Component comp;
ComponentRef cr, lhs, rhs;
Connector c1, c2;
Type ty1, ty2;
SourceInfo info;
list<Equation> eql = {};
algorithm
// Collect all flow variables.
for c in elements.components loop
() := match c
case (cr, _)
algorithm
comp := InstNode.component(ComponentRef.node(cr));

if Component.isFlow(comp) then
c1 := Connector.fromFacedCref(cr, Component.getType(comp),
NFConnector.Face.INSIDE, Component.info(comp));
conns := addFlow(c1, conns);
end if;
then
();

else ();
end match;
end for;

// Collect all connects.
for eq in elements.equations loop
eql := match eq
case Equation.CONNECT(lhs = Expression.CREF(cref = lhs, ty = ty1),
rhs = Expression.CREF(cref = rhs, ty = ty2), info = info)
algorithm
c1 := Connector.fromCref(lhs, ty1, info);
c2 := Connector.fromCref(rhs, ty2, info);
conns := addConnection(Connection.CONNECTION(c1, c2), conns);
then
eql;

else eq :: eql;
end match;
end for;

if not listEmpty(conns.connections) then
elements.equations := listReverseInPlace(eql);
end if;
end collect;

annotation(__OpenModelica_Interface="frontend");
end NFConnections;
2 changes: 1 addition & 1 deletion Compiler/NFFrontEnd/NFConnector.mo
Expand Up @@ -77,7 +77,7 @@ public
protected
InstNode node = ComponentRef.node(cref);
algorithm
conn := CONNECTOR(cref, ty, face,
conn := CONNECTOR(ComponentRef.simplifySubscripts(cref), ty, face,
Component.connectorType(InstNode.component(node)), NONE(),
ElementSource.createElementSource(InstNode.info(node)));
end fromFacedCref;
Expand Down
39 changes: 6 additions & 33 deletions Compiler/NFFrontEnd/NFConvertDAE.mo
Expand Up @@ -503,11 +503,12 @@ algorithm
then
DAE.Element.ARRAY_EQUATION(dims, e1, e2, src) :: elements;

// For equations should have been unrolled here.
case Equation.FOR()
algorithm
body := convertEquations(eq.body);
assert(false, getInstanceName() + " got a for equation");
then
unrollForLoop(eq.iterator, body, elements);
fail();

case Equation.IF()
then convertIfEquation(eq.branches, eq.info, isInitial = false) :: elements;
Expand Down Expand Up @@ -550,35 +551,6 @@ algorithm
end match;
end convertEquation;

function unrollForLoop
input InstNode iterator;
input list<DAE.Element> forBody;
input output list<DAE.Element> elements;
protected
Binding binding;
Expression range;
list<DAE.Element> body;
RangeIterator range_iter;
list<DAE.Exp> values;
DAE.ComponentRef iter_cr;
algorithm
// Get the range to iterate over.
Component.ITERATOR(binding = binding) := InstNode.component(iterator);
SOME(range) := Binding.typedExp(binding);
range_iter := RangeIterator.fromExp(range);
values := list(Expression.toDAE(e) for e in RangeIterator.toListReverse(range_iter));

// Create a DAE.ComponentRef for the replace function. The type doesn't matter
// here, only the name is used when replacing.
iter_cr := DAE.CREF_IDENT(InstNode.name(iterator), DAE.Type.T_UNKNOWN(), {});

// Unroll the loop by iterating over the body and replacing the iterator with its value.
for v in values loop
body := DAEUtil.replaceCrefInDAEElements(forBody, iter_cr, v);
elements := listAppend(body, elements);
end for;
end unrollForLoop;

function convertIfEquation
input list<tuple<Expression, list<Equation>>> ifBranches;
input SourceInfo info;
Expand Down Expand Up @@ -670,11 +642,12 @@ algorithm
then
DAE.Element.INITIAL_ARRAY_EQUATION(dims, e1, e2, src) :: elements;

// For equations should have been unrolled here.
case Equation.FOR()
algorithm
body := convertInitialEquations(eq.body);
assert(false, getInstanceName() + " got a for equation");
then
unrollForLoop(eq.iterator, body, elements);
fail();

case Equation.IF()
then convertIfEquation(eq.branches, eq.info, isInitial = true) :: elements;
Expand Down
103 changes: 103 additions & 0 deletions Compiler/NFFrontEnd/NFEquation.mo
Expand Up @@ -108,5 +108,108 @@ public
SourceInfo info;
end NORETCALL;

function mapExp
input output Equation eq;
input MapFn func;

partial function MapFn
input output Expression exp;
end MapFn;
algorithm
eq := match eq
local
Expression e1, e2, e3;

case EQUALITY()
algorithm
e1 := func(eq.lhs);
e2 := func(eq.rhs);
then
if referenceEq(e1, eq.lhs) and referenceEq(e2, eq.rhs)
then eq else EQUALITY(e1, e2, eq.ty, eq.info);

case ARRAY_EQUALITY()
algorithm
e1 := func(eq.lhs);
e2 := func(eq.rhs);
then
if referenceEq(e1, eq.lhs) and referenceEq(e2, eq.rhs)
then eq else ARRAY_EQUALITY(e1, e2, eq.ty, eq.info);

case CONNECT()
algorithm
e1 := func(eq.lhs);
e2 := func(eq.rhs);
then
if referenceEq(e1, eq.lhs) and referenceEq(e2, eq.rhs)
then eq else CONNECT(e1, e2, eq.info);

case FOR()
algorithm
eq.body := list(mapExp(e, func) for e in eq.body);
then
eq;

case IF()
algorithm
eq.branches := list(mapExpBranch(b, func) for b in eq.branches);
then
eq;

case WHEN()
algorithm
eq.branches := list(mapExpBranch(b, func) for b in eq.branches);
then
eq;

case ASSERT()
algorithm
e1 := func(eq.condition);
e2 := func(eq.message);
e3 := func(eq.level);
then
if referenceEq(e1, eq.condition) and referenceEq(e2, eq.message) and
referenceEq(e3, eq.level) then eq else ASSERT(e1, e2, e3, eq.info);

case TERMINATE()
algorithm
e1 := func(eq.message);
then
if referenceEq(e1, eq.message) then eq else TERMINATE(e1, eq.info);

case REINIT()
algorithm
e1 := func(eq.cref);
e2 := func(eq.reinitExp);
then
if referenceEq(e1, eq.cref) and referenceEq(e2, eq.reinitExp) then
eq else REINIT(e1, e2, eq.info);

case NORETCALL()
algorithm
e1 := func(eq.exp);
then
if referenceEq(e1, eq.exp) then eq else NORETCALL(e1, eq.info);

end match;
end mapExp;

function mapExpBranch
input output tuple<Expression, list<Equation>> branch;
input MapFn func;

partial function MapFn
input output Expression exp;
end MapFn;
protected
Expression cond;
list<Equation> eql;
algorithm
(cond, eql) := branch;
cond := func(cond);
eql := list(mapExp(e, func) for e in eql);
branch := (cond, eql);
end mapExpBranch;

annotation(__OpenModelica_Interface="frontend");
end NFEquation;

0 comments on commit a4417ed

Please sign in to comment.