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

Commit 582a038

Browse files
perostOpenModelica-Hudson
authored andcommitted
[NF] Implement evaluation of cardinality.
Belonging to [master]: - #2549 - OpenModelica/OpenModelica-testsuite#994
1 parent 6ec2d31 commit 582a038

File tree

5 files changed

+173
-12
lines changed

5 files changed

+173
-12
lines changed

Compiler/NFFrontEnd/NFBuiltinCall.mo

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ protected
6060
import Util;
6161
import ExpandExp = NFExpandExp;
6262
import Operator = NFOperator;
63+
import NFComponent.Component;
6364

6465
public
6566
function needSpecialHandling
@@ -1259,6 +1260,7 @@ protected
12591260
list<NamedArg> named_args;
12601261
Expression arg;
12611262
Function fn;
1263+
InstNode node;
12621264
algorithm
12631265
Call.UNTYPED_CALL(ref = fn_ref, arguments = args, named_args = named_args) := call;
12641266
assertNoNamedParams("cardinality", named_args, info);
@@ -1280,7 +1282,9 @@ protected
12801282
{"First", ComponentRef.toString(fn_ref), "<REMOVE ME>"}, info);
12811283
end if;
12821284

1283-
if not Type.isConnector(ty) then
1285+
node := ComponentRef.node(Expression.toCref(arg));
1286+
1287+
if not (Type.isScalar(ty) and InstNode.isComponent(node) and Component.isConnector(InstNode.component(node))) then
12841288
Error.addSourceMessageAndFail(Error.ARG_TYPE_MISMATCH,
12851289
{"1", ComponentRef.toString(fn_ref), "",
12861290
Expression.toString(arg), Type.toString(ty), "connector"}, info);
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
/*
2+
* This file is part of OpenModelica.
3+
*
4+
* Copyright (c) 1998-2014, Open Source Modelica Consortium (OSMC),
5+
* c/o Linköpings universitet, 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 LICENSE OR
11+
* THIS OSMC PUBLIC LICENSE (OSMC-PL) VERSION 1.2.
12+
* ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES
13+
* RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL VERSION 3,
14+
* ACCORDING TO RECIPIENTS CHOICE.
15+
*
16+
* The OpenModelica software and the Open Source Modelica
17+
* Consortium (OSMC) Public License (OSMC-PL) are obtained
18+
* from OSMC, either from the above address,
19+
* from the URLs: http://www.ida.liu.se/projects/OpenModelica or
20+
* http://www.openmodelica.org, and in the OpenModelica distribution.
21+
* GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html.
22+
*
23+
* This program is distributed WITHOUT ANY WARRANTY; without
24+
* even the implied warranty of MERCHANTABILITY or FITNESS
25+
* FOR A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH
26+
* IN THE BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF OSMC-PL.
27+
*
28+
* See the full OSMC Public License conditions for more details.
29+
*
30+
*/
31+
32+
encapsulated package NFCardinalityTable
33+
import BaseHashTable;
34+
import System;
35+
import Connections = NFConnections;
36+
import Connection = NFConnection;
37+
import Connector = NFConnector;
38+
import Expression = NFExpression;
39+
import Util;
40+
41+
type Key = String;
42+
type Value = Integer;
43+
type Table = tuple<
44+
array<list<tuple<Key, Integer>>>,
45+
tuple<Integer, Integer, array<Option<tuple<Key, Value>>>>,
46+
Integer,
47+
tuple<FuncHash, FuncEq, FuncKeyStr, FuncValueStr>>;
48+
49+
partial function FuncHash
50+
input Key key;
51+
input Integer mod;
52+
output Integer res;
53+
end FuncHash;
54+
55+
partial function FuncEq
56+
input Key key1;
57+
input Key key2;
58+
output Boolean res;
59+
end FuncEq;
60+
61+
partial function FuncKeyStr
62+
input Key key;
63+
output String res;
64+
end FuncKeyStr;
65+
66+
partial function FuncValueStr
67+
input Value value;
68+
output String res;
69+
end FuncValueStr;
70+
71+
function emptyCardinalityTable
72+
input Integer size;
73+
output Table table;
74+
algorithm
75+
table := BaseHashTable.emptyHashTableWork(size, (System.stringHashDjb2Mod, stringEq, Util.id, intString));
76+
end emptyCardinalityTable;
77+
78+
function fromConnections
79+
input Connections conns;
80+
output Table table;
81+
algorithm
82+
if System.getUsesCardinality() then
83+
// Use the number of connections as the bucket size. The worst case is
84+
// that each connector in the connections is unique, which would result in
85+
// twice as many entries in the hash table as buckets. That should be
86+
// fine, and real models usually have a higher degree of connectivity.
87+
table := emptyCardinalityTable(max(1, Util.nextPrime(listLength(conns.connections))));
88+
89+
for conn in conns.connections loop
90+
table := addConnector(conn.lhs, table);
91+
table := addConnector(conn.rhs, table);
92+
end for;
93+
else
94+
table := emptyCardinalityTable(1);
95+
end if;
96+
end fromConnections;
97+
98+
function addConnector
99+
input Connector conn;
100+
input output Table table;
101+
protected
102+
String conn_str;
103+
Integer count;
104+
algorithm
105+
conn_str := Connector.toString(conn);
106+
107+
try
108+
count := BaseHashTable.get(conn_str, table);
109+
BaseHashTable.update((conn_str, count + 1), table);
110+
else
111+
table := BaseHashTable.add((conn_str, 1), table);
112+
end try;
113+
end addConnector;
114+
115+
function evaluateCardinality
116+
input Expression arg;
117+
input Table table;
118+
output Expression res;
119+
protected
120+
Integer count;
121+
algorithm
122+
try
123+
count := BaseHashTable.get(Expression.toString(arg), table);
124+
else
125+
count := 0;
126+
end try;
127+
128+
res := Expression.INTEGER(count);
129+
end evaluateCardinality;
130+
131+
function print
132+
input Table table;
133+
algorithm
134+
for e in BaseHashTable.hashTableList(table) loop
135+
print(Util.tuple21(e) + ": " + String(Util.tuple22(e)) + "\n");
136+
end for;
137+
end print;
138+
139+
annotation(__OpenModelica_Interface="frontend");
140+
end NFCardinalityTable;
141+

Compiler/NFFrontEnd/NFConnectEquations.mo

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import Connector = NFConnector;
4141
import DAE;
4242
import ConnectionSets = NFConnectionSets.ConnectionSets;
4343
import Equation = NFEquation;
44+
import CardinalityTable = NFCardinalityTable;
4445

4546
protected
4647
import ComponentReference;
@@ -102,8 +103,10 @@ function evaluateOperators
102103
input output Expression exp;
103104
input ConnectionSets.Sets sets;
104105
input array<list<Connector>> setsArray;
106+
input CardinalityTable.Table ctable;
105107
algorithm
106-
exp := Expression.map(exp, function evaluateOperatorExp(sets = sets, setsArray = setsArray));
108+
exp := Expression.map(exp,
109+
function evaluateOperatorExp(sets = sets, setsArray = setsArray, ctable = ctable));
107110
end evaluateOperators;
108111

109112
protected
@@ -545,6 +548,7 @@ function evaluateOperatorExp
545548
input Expression exp;
546549
input ConnectionSets.Sets sets;
547550
input array<list<Connector>> setsArray;
551+
input CardinalityTable.Table ctable;
548552
output Expression evalExp;
549553
algorithm
550554
evalExp := match exp
@@ -554,9 +558,11 @@ algorithm
554558
case Expression.CALL(call = call as Call.TYPED_CALL())
555559
then match Function.name(call.fn)
556560
case Absyn.IDENT("inStream")
557-
then evaluateInStream(Expression.toCref(listHead(call.arguments)), sets, setsArray);
561+
then evaluateInStream(Expression.toCref(listHead(call.arguments)), sets, setsArray, ctable);
558562
//case Absyn.IDENT("actualStream")
559563
// then evaluateActualStream(Expression.toCref(listHead(call.arguments)), sets, setsArray);
564+
case Absyn.IDENT("cardinality")
565+
then CardinalityTable.evaluateCardinality(listHead(call.arguments), ctable);
560566
else exp;
561567
end match;
562568

@@ -569,6 +575,7 @@ function evaluateInStream
569575
input ComponentRef cref;
570576
input ConnectionSets.Sets sets;
571577
input array<list<Connector>> setsArray;
578+
input CardinalityTable.Table ctable;
572579
output Expression exp;
573580
protected
574581
Connector c;
@@ -585,7 +592,7 @@ algorithm
585592
sl := {c};
586593
end try;
587594

588-
exp := generateInStreamExp(cref, sl, sets, setsArray,
595+
exp := generateInStreamExp(cref, sl, sets, setsArray, ctable,
589596
Flags.getConfigReal(Flags.FLOW_THRESHOLD));
590597
end evaluateInStream;
591598

@@ -596,6 +603,7 @@ function generateInStreamExp
596603
input list<Connector> streams;
597604
input ConnectionSets.Sets sets;
598605
input array<list<Connector>> setsArray;
606+
input CardinalityTable.Table ctable;
599607
input Real flowThreshold;
600608
output Expression exp;
601609
protected
@@ -630,7 +638,7 @@ algorithm
630638
{Connector.CONNECTOR(name = cr)} :=
631639
removeStreamSetElement(streamCref, reducedStreams);
632640
then
633-
evaluateInStream(cr, sets, setsArray);
641+
evaluateInStream(cr, sets, setsArray, ctable);
634642

635643
// The general case:
636644
else
@@ -639,7 +647,7 @@ algorithm
639647
inside := removeStreamSetElement(streamCref, inside);
640648
exp := streamSumEquationExp(outside, inside, Expression.REAL(flowThreshold));
641649
// Evaluate any inStream calls that were generated.
642-
exp := evaluateOperatorExp(exp, sets, setsArray);
650+
exp := evaluateOperatorExp(exp, sets, setsArray, ctable);
643651
then
644652
exp;
645653

Compiler/NFFrontEnd/NFFlatten.mo

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ import Statement = NFStatement;
4646
import FlatModel = NFFlatModel;
4747
import Prefix;
4848
import Algorithm = NFAlgorithm;
49+
import CardinalityTable = NFCardinalityTable;
4950

5051
protected
5152
import ComponentRef = NFComponentRef;
@@ -876,17 +877,19 @@ protected
876877
list<Equation> conn_eql;
877878
ConnectionSets.Sets csets;
878879
array<list<Connector>> csets_array;
880+
CardinalityTable.Table ctable;
879881
algorithm
880882
// Generate the connect equations and add them to the equation list.
881883
(flatModel, conns) := Connections.collect(flatModel);
882884
csets := ConnectionSets.fromConnections(conns);
883885
csets_array := ConnectionSets.extractSets(csets);
884886
conn_eql := ConnectEquations.generateEquations(csets_array);
885887
flatModel.equations := listAppend(conn_eql, flatModel.equations);
888+
ctable := CardinalityTable.fromConnections(conns);
886889

887890
// Evaluate any connection operators if they're used.
888891
if System.getHasStreamConnectors() or System.getUsesCardinality() then
889-
flatModel := evaluateConnectionOperators(flatModel, csets, csets_array);
892+
flatModel := evaluateConnectionOperators(flatModel, csets, csets_array, ctable);
890893
end if;
891894

892895
execStat(getInstanceName() + "(" + name + ")");
@@ -896,25 +899,27 @@ function evaluateConnectionOperators
896899
input output FlatModel flatModel;
897900
input ConnectionSets.Sets sets;
898901
input array<list<Connector>> setsArray;
902+
input CardinalityTable.Table ctable;
899903
algorithm
900-
flatModel.variables := list(evaluateBindingConnOp(c, sets, setsArray) for c in flatModel.variables);
901-
flatModel.equations := evaluateEquationsConnOp(flatModel.equations, sets, setsArray);
902-
flatModel.initialEquations := evaluateEquationsConnOp(flatModel.initialEquations, sets, setsArray);
904+
flatModel.variables := list(evaluateBindingConnOp(c, sets, setsArray, ctable) for c in flatModel.variables);
905+
flatModel.equations := evaluateEquationsConnOp(flatModel.equations, sets, setsArray, ctable);
906+
flatModel.initialEquations := evaluateEquationsConnOp(flatModel.initialEquations, sets, setsArray, ctable);
903907
// TODO: Implement evaluation for algorithm sections.
904908
end evaluateConnectionOperators;
905909

906910
function evaluateBindingConnOp
907911
input output Variable var;
908912
input ConnectionSets.Sets sets;
909913
input array<list<Connector>> setsArray;
914+
input CardinalityTable.Table ctable;
910915
protected
911916
Binding binding;
912917
Expression exp, eval_exp;
913918
algorithm
914919
() := match var
915920
case Variable.VARIABLE(binding = binding as Binding.TYPED_BINDING(bindingExp = exp))
916921
algorithm
917-
eval_exp := ConnectEquations.evaluateOperators(exp, sets, setsArray);
922+
eval_exp := ConnectEquations.evaluateOperators(exp, sets, setsArray, ctable);
918923

919924
if not referenceEq(exp, eval_exp) then
920925
binding.bindingExp := eval_exp;
@@ -931,9 +936,11 @@ function evaluateEquationsConnOp
931936
input output list<Equation> equations;
932937
input ConnectionSets.Sets sets;
933938
input array<list<Connector>> setsArray;
939+
input CardinalityTable.Table ctable;
934940
algorithm
935941
equations := list(
936-
Equation.mapExp(eq, function ConnectEquations.evaluateOperators(sets = sets, setsArray = setsArray))
942+
Equation.mapExp(eq,
943+
function ConnectEquations.evaluateOperators(sets = sets, setsArray = setsArray, ctable = ctable))
937944
for eq in equations);
938945
end evaluateEquationsConnOp;
939946

Compiler/boot/LoadCompilerSources.mos

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,7 @@ if true then /* Suppress output */
294294
"../NFFrontEnd/NFBuiltinCall.mo",
295295
"../NFFrontEnd/NFBuiltinFuncs.mo",
296296
"../NFFrontEnd/NFCall.mo",
297+
"../NFFrontEnd/NFCardinalityTable.mo",
297298
"../NFFrontEnd/NFCeval.mo",
298299
"../NFFrontEnd/NFComplexType.mo",
299300
"../NFFrontEnd/NFComponent.mo",

0 commit comments

Comments
 (0)