From a611bef985fdf2a46d53c813dd2ecdcb33d56dcc Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Tue, 13 Apr 2010 03:17:04 +0000 Subject: [PATCH] - overconstrained connection graph improvements and fixes. + the graph changes generated by disabled components ( Type comp if false ) should be discarded (created problems for ForceAndTorque.mos) + delete the branch edges, roots and connects from the connection graph when they lead to a disabled component. git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@5298 f25d12d1-65f4-0310-ae8a-bbce733d8d8e --- Compiler/ConnectUtil.mo | 60 ++- Compiler/ConnectionGraph.mo | 748 +++++++++++++++++++++++++++++++++--- Compiler/Inst.mo | 67 ++-- Compiler/Util.mo | 6 +- 4 files changed, 774 insertions(+), 107 deletions(-) diff --git a/Compiler/ConnectUtil.mo b/Compiler/ConnectUtil.mo index 6e3f22658b6..4f123838279 100644 --- a/Compiler/ConnectUtil.mo +++ b/Compiler/ConnectUtil.mo @@ -51,7 +51,8 @@ public import DAE; public import Env; public import InnerOuter; public import Prefix; -public import ClassInf; +public import ClassInf; +public import ConnectionGraph; protected import Exp; protected import DAEUtil; @@ -505,30 +506,45 @@ public function equations " Equation generation From a number of connection sets, this function generates a list of equations." input Connect.Sets sets; - input Prefix.Prefix pre "prefix required for checking deleted components"; - output DAE.DAElist dae; + input Prefix.Prefix pre "prefix required for checking deleted components"; + input Boolean isTopScope "this is true if we are in a top scope class!"; + input ConnectionGraph.ConnectionGraph inConnectionGraph; + output DAE.DAElist outDAE; + output ConnectionGraph.ConnectionGraph outConnectionGraph; algorithm - dae := matchcontinue(sets,pre) + (outDAE, outConnectionGraph) := matchcontinue(sets,pre,isTopScope,inConnectionGraph) local list s; list crs,deletedComps; DAE.ComponentRef cr,deletedComp; - list outerConn; + list outerConn; + ConnectionGraph.ConnectionGraph graph; + DAE.DAElist dae; + list daeElements, daeEqualityConstraint; + DAE.FunctionTree functions; + // no deleted components - case(sets as Connect.SETS(s,crs,{},outerConn),pre) - equation - //print(printSetsStr(sets)); - then equations2(sets); + case(sets as Connect.SETS(s,crs,{},outerConn),pre,isTopScope,graph) + equation + dae = equations2(sets); + then + (dae, graph); + // handle deleted components - case(Connect.SETS(s,crs,deletedComp::deletedComps,outerConn),pre) + case(Connect.SETS(s,crs,deletedComp::deletedComps,outerConn),pre,isTopScope,graph) equation cr = deletedComp; - s = removeComponentInSets(cr,s); - then - equations(Connect.SETS(s,crs,deletedComps,outerConn),pre); + s = removeComponentInSets(cr,s); + // remove all branches/connections/roots in the connection graph leading to the deleted components + graph = ConnectionGraph.removeDeletedComponentsFromCG(graph, cr); + // recursive call with all the rest of deleted components. + (dae, graph) = equations(Connect.SETS(s,crs,deletedComps,outerConn),pre,isTopScope,graph); + then + (dae, graph); + // failure - case(_,_) equation - Debug.fprint("failtrace","Connect.equations failed\n"); + case(_,_,_,_) equation + Debug.fprint("failtrace", "Connect.equations failed\n"); then fail(); end matchcontinue; end equations; @@ -683,13 +699,19 @@ algorithm DAE.ComponentRef x,y; list> cs; DAE.ElementSource src,src1,src2; - DAE.FunctionTree funcs; + DAE.FunctionTree funcs; + list partOfLst; + list> instanceOptLst; + list>> connectEquationOptLst; + list typeLst; case {_} then DAEUtil.emptyDae; case ((x,src1) :: ((y,src2) :: cs)) equation DAE.DAE(eq,funcs) = equEquations(((y,src2) :: cs)); - src = DAEUtil.mergeSources(src1,src2); + DAE.SOURCE(partOfLst, instanceOptLst, connectEquationOptLst, typeLst) = DAEUtil.mergeSources(src1,src2); + // do not propagate connects from different sources! use the crefs directly! + src = DAE.SOURCE(partOfLst, instanceOptLst, {SOME((x,y))}, typeLst); then (DAE.DAE(DAE.EQUEQUATION(x,y,src) :: eq,funcs)); case(_) equation print(" FAILURE IN CONNECT \n"); then fail(); @@ -1782,7 +1804,9 @@ algorithm s2 = printSetCrsStr(crs); s3 = Util.stringDelimitList(Util.listMap(dc,Exp.printComponentRefStr),","); s4 = printOuterConnectsStr(outerConn); - res = Util.stringAppendList({"Connect.SETS(",s1_1,", ",s2,", deleted comps: ",s3,", outer connections:",s4,")\n"}); + res = Util.stringAppendList({"Connect.SETS(\n\t", + s1_1,", \n\t", + s2,", \n\tdeleted comps: ",s3,", \n\touter connections:",s4,")\n"}); then res; end matchcontinue; diff --git a/Compiler/ConnectionGraph.mo b/Compiler/ConnectionGraph.mo index b2dbeb3fccc..4fdba1b990b 100644 --- a/Compiler/ConnectionGraph.mo +++ b/Compiler/ConnectionGraph.mo @@ -60,16 +60,18 @@ public import DAE; public import DAEUtil; public import HashTableCG; public import Util; +public import Connect; /* A list of edges */ -type Edges = list>; +public type Edges = list>; /* A list of edges, each edge associated with two lists of DAE elements * (these elements represent equations to be added if the edge * is preserved or broken) */ -type DaeEdges = list>>; +public type DaeEdges = list>>; +public uniontype ConnectionGraph "Input structure for connection breaking algorithm. It is collected during instantiation phase." record GRAPH Boolean updateGraph; @@ -106,22 +108,21 @@ algorithm DAE.AvlTree funcs; list roots; DAE.DAElist dae; + list> broken; // empty graph gives you the same dae case (GRAPH(_, {}, {}, {}, {}), dae) then dae; // no dae - case (graph, DAE.DAE({},_)) then DAEUtil.emptyDae; + // case (graph, DAE.DAE({},_)) then DAEUtil.emptyDae; // handle the connection braking case (graph, DAE.DAE(elts,funcs)) equation - (roots,daeConnections) = findResultGraph(graph); - Debug.fprintln("cgraph", "Extra equations from connection graph: " +& intString(listLength(daeConnections))); - Debug.fprintln("cgraph", "Roots:\n" +& Util.stringDelimitList(Util.listMap(roots, Exp.printComponentRefStr), ",\n")); - Debug.fcall("cgraph", DAEUtil.dumpElements, daeConnections); - Debug.fprintln("cgraph", Print.getString()); - Debug.fprintln("cgraph", "\n"); - elts= evalIsRoot(roots, elts); - elts = Util.listAppendNoCopy(elts, daeConnections); + (roots, elts, broken) = findResultGraph(graph, elts); + + Debug.fprintln("cgraph", "Roots: " +& Util.stringDelimitList(Util.listMap(roots, Exp.printComponentRefStr), ", ")); + Debug.fprintln("cgraph", "Broken connections: " +& Util.stringDelimitList(Util.listMap(broken, printConnectionStr), ", ")); + + elts = evalIsRoot(roots, elts); then DAE.DAE(elts,funcs); // handle the connection braking @@ -133,6 +134,138 @@ algorithm end matchcontinue; end handleOverconstrainedConnections; +public function handleOverconstrainedConnectionsInSets +"author: adrpo + this function gets the connection graph and adds the + new connections to the DAE given as input and returns + a new DAE" + input ConnectionGraph inGraph; + input Connect.Sets inSets; + input Boolean isTopScope; + output Connect.Sets outSets; + output list outDAEElements; +algorithm + outSets := matchcontinue(inGraph, inSets, isTopScope) + local + ConnectionGraph graph; + list elts; + DAE.AvlTree funcs; + list roots; + DAE.DAElist dae; + Connect.Sets sets; + list> broken; + + // if not top scope, do not do the connection graph! + case (graph, sets, false) then (sets, {}); + + // empty graph gives you the same connection graph! + case (GRAPH(_, {}, {}, {}, {}), sets, isTopScope) then (inSets, {}); + // handle the connection braking + case (graph, sets, isTopScope) + equation + (roots, elts, broken) = findResultGraph(graph, {}); + + Debug.fprintln("cgraph", "Roots: " +& Util.stringDelimitList(Util.listMap(roots, Exp.printComponentRefStr), ", ")); + Debug.fprintln("cgraph", "Broken connections: " +& Util.stringDelimitList(Util.listMap(broken, printConnectionStr), ", ")); + + // remove the broken connects from connection set! + sets = removeBrokenConnectionsFromSets(sets, broken); + + then + (sets,elts); + + // handle the connection braking + case (graph, sets, isTopScope) + equation + Debug.fprintln("cgraph", "- ConnectionGraph.handleOverconstrainedConnectionsInSets failed"); + then + fail(); + end matchcontinue; +end handleOverconstrainedConnectionsInSets; + +public function removeDeletedComponentsFromCG +"@author: adrpo + This function will remove all branches/connections/roots in the connection graph leading to the deleted component" + input ConnectionGraph inGraph; + input DAE.ComponentRef inDeletedComponent; + output ConnectionGraph outGraph; +algorithm + outGraph := matchcontinue(inGraph, inDeletedComponent) + local + Boolean updateGraph; + ConnectionGraph graph; + DAE.ComponentRef deletedComponentRef; + list definiteRoots; + list> potentialRoots; + Edges branches; + DaeEdges connections; + + case (GRAPH(updateGraph = updateGraph, + definiteRoots = definiteRoots, + potentialRoots = potentialRoots, + branches = branches, + connections = connections), deletedComponentRef) + equation + definiteRoots = Util.listSelect1R(definiteRoots,deletedComponentRef,Exp.crefNotPrefixOf); + potentialRoots = Util.listSelect1(potentialRoots,deletedComponentRef,crefTupleNotPrefixOf); + branches = Util.listSelect1(branches,deletedComponentRef,crefBranchNotPrefixOf); + connections = Util.listSelect1(connections,deletedComponentRef,crefConnectNotPrefixOf); + then + GRAPH(updateGraph, definiteRoots, potentialRoots, branches, connections); + end matchcontinue; +end removeDeletedComponentsFromCG; + +protected function crefTupleNotPrefixOf + input tuple inTuple; + input DAE.ComponentRef compName; + output Boolean selected; +algorithm + selected := matchcontinue(inTuple,compName) + local DAE.ComponentRef cr; + case((cr,_),compName) then Exp.crefNotPrefixOf(compName,cr); + end matchcontinue; +end crefTupleNotPrefixOf; + +protected function crefBranchNotPrefixOf + input tuple inTuple; + input DAE.ComponentRef compName; + output Boolean selected; +algorithm + selected := matchcontinue(inTuple,compName) + local + DAE.ComponentRef cr1, cr2; + Boolean b1, b2, b; + + case((cr1,cr2),compName) + equation + b1 = Exp.crefNotPrefixOf(compName,cr1); + b2 = Exp.crefNotPrefixOf(compName,cr2); + b = boolAnd(b1, b2); + then + b; + end matchcontinue; +end crefBranchNotPrefixOf; + +protected function crefConnectNotPrefixOf + input tuple> inTuple; + input DAE.ComponentRef compName; + output Boolean selected; +algorithm + selected := matchcontinue(inTuple,compName) + local + DAE.ComponentRef cr1, cr2; + Boolean b1, b2, b; + + case((cr1,cr2,_),compName) + equation + b1 = Exp.crefNotPrefixOf(compName,cr1); + b2 = Exp.crefNotPrefixOf(compName,cr2); + b = boolAnd(b1, b2); + then + b; + end matchcontinue; +end crefConnectNotPrefixOf; + public function addDefiniteRoot "Adds a new definite root to ConnectionGraph" input ConnectionGraph inGraph; @@ -262,6 +395,15 @@ algorithm end matchcontinue; end addConnection; +// ************************************* // +// ********* protected section ********* // +// ************************************* // + +protected import Exp; +protected import Debug; +protected import Print; +protected import System; + protected function canonical "Returns the canonical element of the component where input element belongs to. See explanation at the top of file." @@ -279,17 +421,17 @@ algorithm equation parent = HashTableCG.get(ref, partition); parentCanonical = canonical(partition, parent); - Debug.fprintln("cgraph", - "- ConnectionGraph.canonical_case1(" +& Exp.printComponentRefStr(ref) +& ") = " +& - Exp.printComponentRefStr(parentCanonical)); + //Debug.fprintln("cgraph", + // "- ConnectionGraph.canonical_case1(" +& Exp.printComponentRefStr(ref) +& ") = " +& + // Exp.printComponentRefStr(parentCanonical)); //partition2 = HashTableCG.add((ref, parentCanonical), partition); then parentCanonical; case (partition,ref) equation - Debug.fprintln("cgraph", - "- ConnectionGraph.canonical_case2(" +& Exp.printComponentRefStr(ref) +& ") = " +& - Exp.printComponentRefStr(ref)); + //Debug.fprintln("cgraph", + // "- ConnectionGraph.canonical_case2(" +& Exp.printComponentRefStr(ref) +& ") = " +& + // Exp.printComponentRefStr(ref)); then ref; end matchcontinue; end canonical; @@ -320,11 +462,42 @@ algorithm end matchcontinue; end areInSameComponent; + +protected function connectBranchComponents +"Tries to connect two components whose elements are given. Depending + on wheter the connection success or not (i.e are the components already + connected), adds either inConnectionDae or inBreakDae to the list of + DAE elements." + input HashTableCG.HashTable inPartition; + input DAE.ComponentRef inRef1; + input DAE.ComponentRef inRef2; + output HashTableCG.HashTable outPartition; +algorithm + outPartition := matchcontinue(inPartition,inRef1,inRef2) + local + HashTableCG.HashTable partition; + DAE.ComponentRef ref1, ref2, canon1, canon2; + + // can connect them + case(partition,ref1,ref2) + equation + canon1 = canonical(partition,ref1); + canon2 = canonical(partition,ref2); + (partition, true) = connectCanonicalComponents(partition,canon1,canon2); + then partition; + + // cannot connect them + case(partition,ref1,ref2) + equation + then partition; + end matchcontinue; +end connectBranchComponents; + protected function connectComponents - "Tries to connect two components whose elements are given. Depending - on wheter the connection success or not (i.e are the components already - connected), adds either inConnectionDae or inBreakDae to the list of - DAE elements." +"Tries to connect two components whose elements are given. Depending + on wheter the connection success or not (i.e are the components already + connected), adds either inConnectionDae or inBreakDae to the list of + DAE elements." input HashTableCG.HashTable inPartition; input DAE.ComponentRef inRef1; input DAE.ComponentRef inRef2; @@ -332,24 +505,28 @@ protected function connectComponents input list inFullDae; output HashTableCG.HashTable outPartition; output list outDae; + output list> outBrokenConnections; algorithm - (outPartition,outDae) := matchcontinue(inPartition,inRef1,inRef2,inBreakDae,inFullDae) + (outPartition,outDae,outBrokenConnections) := matchcontinue(inPartition,inRef1,inRef2,inBreakDae,inFullDae) local HashTableCG.HashTable partition; DAE.ComponentRef ref1, ref2, canon1, canon2; list dae, breakDAE; + // empty case! + // case(partition,ref1,ref2,{},dae as {}) then (partition, dae); + // leave the DAE as it is as we already added the equations from connect(ref1,ref2) case(partition,ref1,ref2,_,dae) equation failure(canon1 = canonical(partition,ref1)); // no parent - then (partition, dae); + then (partition, dae, {}); // leave the DAE as it is as we already added the equations from connect(ref1,ref2) case(partition,ref1,ref2,_,dae) equation failure(canon2 = canonical(partition,ref2)); // no parent - then (partition, dae); + then (partition, dae, {}); // leave the DAE as it is as we already added the equations from connect(ref1,ref2) case(partition,ref1,ref2,_,dae) @@ -365,19 +542,280 @@ algorithm //print(" -- "); //print(Exp.printComponentRefStr(ref2)); //print("\n"); - then (partition, dae); + then (partition, dae, {}); + + // remove the added equations from the DAE then add the breakDAE case(partition,ref1,ref2,breakDAE,dae) equation - // remove the added equations from the DAE then add the breakDAE - // dae = listAppend(dae, breakDAE); // removed for now as the algorithm doesn't work correctly. - //print(Exp.printComponentRefStr(ref1)); - //print(" -/- "); - //print(Exp.printComponentRefStr(ref2)); - //print("\n"); - then (partition, dae); + // debug print + Debug.fprintln("cgraph", "- ConnectionGraph.connectComponents: should remove equations generated from: connect(" +& + Exp.printComponentRefStr(ref1) +& ", " +& + Exp.printComponentRefStr(ref2) +& ") and add {0, ..., 0} = equalityConstraint(cr1, cr2) instead."); + // remove the added equations from the DAE + dae = removeEquationsWithOrigin(dae, ref1, ref2); + // then add the breakDAE which comes from {0} = equalityConstraint(A, B); + dae = listAppend(dae, breakDAE); + then (partition, dae, {(ref1,ref2)}); end matchcontinue; end connectComponents; +protected function removeEquationsWithOrigin +"@author: adrpo + this function *removes* the equations generated from + the connect component references given as input." + input list inFullDAE; + input DAE.ComponentRef left; + input DAE.ComponentRef right; + output list outDAE; +algorithm + outDAE := matchcontinue(inFullDAE, left, right) + local + list rest, elements; + DAE.Element el; + DAE.ComponentRef cr1, cr2; + + // handle the empty case + case ({}, cr1, cr2) then {}; + + // if this element came from this connect, remove it! + case (el::rest, cr1, cr2) + equation + true = originInConnect(el, cr1, cr2); + Debug.fprintln("cgraph", "- ConnectionGraph.removeEquationsWithOrigin: removed " +& + DAEUtil.dumpDAEElementsStr(DAE.DAE({el}, DAE.AVLTREENODE(NONE,0,NONE,NONE))) +& + "\t generated from: connect(" +& + Exp.printComponentRefStr(cr1) +& ", " +& + Exp.printComponentRefStr(cr2) +& ")"); + elements = removeEquationsWithOrigin(rest, cr1, cr2); + then + elements; + + // if this element DID NOT came from this connect, let it be! + case (el::rest, cr1, cr2) + local + String str1, str2, str3; + equation + false = originInConnect(el, cr1, cr2); + elements = removeEquationsWithOrigin(rest, cr1, cr2); + then + el::elements; + end matchcontinue; +end removeEquationsWithOrigin; + +protected function originInConnect +"@author: adrpo + this function returns true if the given element came from + the connect of the component references given as input" + input DAE.Element inElement; + input DAE.ComponentRef left; + input DAE.ComponentRef right; + output Boolean hasOriginInConnect; +algorithm + hasOriginInConnect := matchcontinue(inElement, left, right) + local + list>> connectOptLst; + Boolean b; + + // var + case (DAE.VAR(source = DAE.SOURCE(connectEquationOptLst = connectOptLst)), left, right) + equation + b = isInConnectionList(connectOptLst, left, right); + then + b; + // define + case (DAE.DEFINE(source = DAE.SOURCE(connectEquationOptLst = connectOptLst)), left, right) + equation + b = isInConnectionList(connectOptLst, left, right); + then + b; + // initial define + case (DAE.INITIALDEFINE(source = DAE.SOURCE(connectEquationOptLst = connectOptLst)), left, right) + equation + b = isInConnectionList(connectOptLst, left, right); + then + b; + // equation + case (DAE.EQUATION(source = DAE.SOURCE(connectEquationOptLst = connectOptLst)), left, right) + equation + b = isInConnectionList(connectOptLst, left, right); + then + b; + // initial equation + case (DAE.INITIALEQUATION(source = DAE.SOURCE(connectEquationOptLst = connectOptLst)), left, right) + equation + b = isInConnectionList(connectOptLst, left, right); + then + b; + // equequation + case (DAE.EQUEQUATION(source = DAE.SOURCE(connectEquationOptLst = connectOptLst)), left, right) + equation + b = isInConnectionList(connectOptLst, left, right); + then + b; + // array equation + case (DAE.ARRAY_EQUATION(source = DAE.SOURCE(connectEquationOptLst = connectOptLst)), left, right) + equation + b = isInConnectionList(connectOptLst, left, right); + then + b; + // initial array equation + case (DAE.INITIAL_ARRAY_EQUATION(source = DAE.SOURCE(connectEquationOptLst = connectOptLst)), left, right) + equation + b = isInConnectionList(connectOptLst, left, right); + then + b; + // complex equation + case (DAE.COMPLEX_EQUATION(source = DAE.SOURCE(connectEquationOptLst = connectOptLst)), left, right) + equation + b = isInConnectionList(connectOptLst, left, right); + then + b; + // initial complex equation + case (DAE.INITIAL_COMPLEX_EQUATION(source = DAE.SOURCE(connectEquationOptLst = connectOptLst)), left, right) + equation + b = isInConnectionList(connectOptLst, left, right); + then + b; + // when equation + case (DAE.WHEN_EQUATION(source = DAE.SOURCE(connectEquationOptLst = connectOptLst)), left, right) + equation + b = isInConnectionList(connectOptLst, left, right); + then + b; + // if equation + case (DAE.IF_EQUATION(source = DAE.SOURCE(connectEquationOptLst = connectOptLst)), left, right) + equation + b = isInConnectionList(connectOptLst, left, right); + then + b; + // initial if equation + case (DAE.INITIAL_IF_EQUATION(source = DAE.SOURCE(connectEquationOptLst = connectOptLst)), left, right) + equation + b = isInConnectionList(connectOptLst, left, right); + then + b; + // algorithm + case (DAE.ALGORITHM(source = DAE.SOURCE(connectEquationOptLst = connectOptLst)), left, right) + equation + b = isInConnectionList(connectOptLst, left, right); + then + b; + // initial algorithm + case (DAE.INITIALALGORITHM(source = DAE.SOURCE(connectEquationOptLst = connectOptLst)), left, right) + equation + b = isInConnectionList(connectOptLst, left, right); + then + b; + // a component + case (DAE.COMP(source = DAE.SOURCE(connectEquationOptLst = connectOptLst)), left, right) + equation + b = isInConnectionList(connectOptLst, left, right); + then + b; + // function + case (DAE.FUNCTION(source = DAE.SOURCE(connectEquationOptLst = connectOptLst)), left, right) + equation + b = isInConnectionList(connectOptLst, left, right); + then + b; + // record constructor + case (DAE.RECORD_CONSTRUCTOR(source = DAE.SOURCE(connectEquationOptLst = connectOptLst)), left, right) + equation + b = isInConnectionList(connectOptLst, left, right); + then + b; + // external object + case (DAE.EXTOBJECTCLASS(source = DAE.SOURCE(connectEquationOptLst = connectOptLst)), left, right) + equation + b = isInConnectionList(connectOptLst, left, right); + then + b; + // assert + case (DAE.ASSERT(source = DAE.SOURCE(connectEquationOptLst = connectOptLst)), left, right) + equation + b = isInConnectionList(connectOptLst, left, right); + then + b; + // terminate + case (DAE.TERMINATE(source = DAE.SOURCE(connectEquationOptLst = connectOptLst)), left, right) + equation + b = isInConnectionList(connectOptLst, left, right); + then + b; + // reinit + case (DAE.REINIT(source = DAE.SOURCE(connectEquationOptLst = connectOptLst)), left, right) + equation + b = isInConnectionList(connectOptLst, left, right); + then + b; + // no return call + case (DAE.NORETCALL(source = DAE.SOURCE(connectEquationOptLst = connectOptLst)), left, right) + equation + b = isInConnectionList(connectOptLst, left, right); + then + b; + // TODO! FIXME! CHECK THIS! anything else could not have come from a connect, ignore! + case (inElement, left, right) + equation + debug_print("element", inElement); + debug_print("left", left); + debug_print("right", right); + then false; + end matchcontinue; +end originInConnect; + +protected function isInConnectionList +"@author: adrpo + searches the given connect list for the matching connect given as component refence inputs" + input list>> inConnectEquationOptLst; + input DAE.ComponentRef left; + input DAE.ComponentRef right; + output Boolean isPresent; +algorithm + isPresent := matchcontinue(inConnectEquationOptLst, left, right) + local + list>> rest; + DAE.ComponentRef crLeft, crRight; + Boolean b, b1, b2; + + // handle empty case + case ({}, left, right) then false; + + // try direct match + case (SOME((crLeft, crRight))::rest, left, right) + equation + b1 = Exp.crefPrefixOf(left, crLeft); + b2 = Exp.crefPrefixOf(right, crRight); + true = boolAnd(b1, b2); + print("connect: " +& Exp.printComponentRefStr(left) +& ", " +& Exp.printComponentRefStr(right) +& "\n"); + print("origin: " +& Exp.printComponentRefStr(crLeft) +& ", " +& Exp.printComponentRefStr(crRight) +& "\n"); + then + true; + // try inverse match + case (SOME((crLeft, crRight))::rest, left, right) + equation + b1 = Exp.crefPrefixOf(right, crLeft); + b2 = Exp.crefPrefixOf(left, crRight); + true = boolAnd(b1, b2); + print("connect: " +& Exp.printComponentRefStr(left) +& ", " +& Exp.printComponentRefStr(right) +& "\n"); + print("origin: " +& Exp.printComponentRefStr(crRight) +& ", " +& Exp.printComponentRefStr(crLeft) +& "\n"); + then + true; + // try the rest + case (_::rest, left, right) + equation + b = isInConnectionList(rest, left, right); + then + b; + // failure + case (_, left, right) + equation + Debug.fprintln("cgraph", "- ConnectionGrap.isInConnectionList failed!"); + then + fail(); + end matchcontinue; +end isInConnectionList; + protected function connectCanonicalComponents "Tries to connect two components whose canonical elements are given. Helper function for connectionComponents." @@ -437,7 +875,7 @@ algorithm outTable := addRootsToTable(table0, roots, dummyRoot); end resultGraphWithRoots; -function addBranchesToTable +protected function addBranchesToTable "Adds all branches to the graph." input HashTableCG.HashTable inTable; input list> inBranches; @@ -451,7 +889,7 @@ algorithm case(table, ((ref1,ref2)::tail)) equation - (table1,_) = connectComponents(table, ref1, ref2, {}, {}); + table1 = connectBranchComponents(table, ref1, ref2); table2 = addBranchesToTable(table1, tail); then table2; case(table, {}) then table; @@ -509,20 +947,25 @@ protected function addConnections input list inDae; output HashTableCG.HashTable outTable; output list outDae; + output list> outBrokenConnections; algorithm - (outTable,outDae) := matchcontinue(inTable, inConnections, inDae) + (outTable,outDae,outBrokenConnections) := matchcontinue(inTable, inConnections, inDae) local HashTableCG.HashTable table; DAE.ComponentRef ref1, ref2; DaeEdges tail; list breakDAE, dae; + list> broken1,broken2,broken; - case(table, {}, dae) then (table, dae); + // empty case + case(table, {}, dae) then (table, dae, {}); + // normal case case(table, ((ref1,ref2,breakDAE)::tail), dae) - equation - (table,dae) = connectComponents(table, ref1, ref2, breakDAE, dae); - (table,dae) = addConnections(table, tail, dae); - then (table,dae); + equation + (table,dae,broken1) = connectComponents(table, ref1, ref2, breakDAE, dae); + (table,dae,broken2) = addConnections(table, tail, dae); + broken = listAppend(broken1, broken2); + then (table,dae,broken); end matchcontinue; end addConnections; @@ -530,10 +973,12 @@ protected function findResultGraph "Given ConnectionGraph structure, breaks all connections, determines roots and generates a list of dae elements." input ConnectionGraph inGraph; - output list outRoots; - output list outDae; + input list inDAE; + output list outRoots; + output list outDAE; + output list> outBrokenConnections; algorithm - (outRoots, outDae) := matchcontinue(inGraph) + (outRoots, outDAE, outBorkenConnections) := matchcontinue(inGraph, inDAE) local list definiteRoots, finalRoots; list> potentialRoots; @@ -544,23 +989,25 @@ algorithm DAE.ComponentRef dummyRoot; Edges brokenConnections, normalConnections; list dae; + list> broken; // deal with empty connection graph - case (GRAPH(_, definiteRoots = {}, potentialRoots = {}, branches = {}, connections = {})) then ({}, {}); + case (GRAPH(_, definiteRoots = {}, potentialRoots = {}, branches = {}, connections = {}), inDAE) + then ({}, inDAE, {}); // we have something in the connection graph case (GRAPH(_, definiteRoots = definiteRoots, potentialRoots = potentialRoots, - branches = branches, connections = connections)) + branches = branches, connections = connections), inDAE) equation table = resultGraphWithRoots(definiteRoots); table = addBranchesToTable(table, branches); orderedPotentialRoots = Util.sort(potentialRoots, ord); - Debug.fprintln("cgraph", "Ordered Potential Roots:\n" +& - Util.stringDelimitList(Util.listMap(orderedPotentialRoots, printPotentialRootTuple), ",\n")); + Debug.fprintln("cgraph", "Ordered Potential Roots: " +& + Util.stringDelimitList(Util.listMap(orderedPotentialRoots, printPotentialRootTuple), ", ")); dummyRoot = DAE.CREF_IDENT("__DUMMY_ROOT", DAE.ET_INT, {}); - (table, dae) = addConnections(table, connections, {}); + (table, dae, broken) = addConnections(table, connections, inDAE); (table, finalRoots) = addPotentialRootsToTable(table, orderedPotentialRoots, definiteRoots, dummyRoot); - then (finalRoots, dae); + then (finalRoots, dae, broken); end matchcontinue; end findResultGraph; @@ -617,7 +1064,8 @@ algorithm expLst={DAE.CREF(componentRef = cref)}), roots) equation result = Util.listContainsWithCompareFunc(cref, roots, Exp.crefEqual); - //Debug.fprintln("cgraph", Exp.printExpStr(inExp) +& " is found in roots:"); + Debug.fprintln("cgraph", "- ConnectionGraph.evalIsRootHelper: " +& + Exp.printExpStr(inExp) +& " = " +& Util.if_(result, "true", "false")); then (DAE.BCONST(result), roots); // deal with NOT Connections.isRoot case (DAE.LUNARY(DAE.NOT(), DAE.CALL(path=Absyn.QUALIFIED("Connections", Absyn.IDENT("isRoot")), @@ -625,19 +1073,37 @@ algorithm equation result = Util.listContainsWithCompareFunc(cref, roots, Exp.crefEqual); result = boolNot(result); - //Debug.fprintln("cgraph", Exp.printExpStr(inExp) +& " is found in roots!"); + Debug.fprintln("cgraph", "- ConnectionGraph.evalIsRootHelper: " +& + Exp.printExpStr(inExp) +& " = " +& Util.if_(result, "true", "false")); then (DAE.BCONST(result), roots); // no replacement needed case (exp, roots) equation - //Debug.fprintln("cgraph", Exp.printExpStr(exp) +& " not found in roots!"); + // Debug.fprintln("cgraph", Exp.printExpStr(exp) +& " not found in roots!"); then (exp, roots); end matchcontinue; end evalIsRootHelper; -protected import Exp; -protected import Debug; -protected import Print; +protected function printConnectionStr +"prints the connection str" + input tuple connectTuple; + output String outStr; +algorithm + outStr := matchcontinue(connectTuple) + local + DAE.ComponentRef c1, c2; + String str; + + case ((c1, c2)) + equation + str = "BROKEN(" +& + Exp.printComponentRefStr(c1) +& + ", " +& + Exp.printComponentRefStr(c2) +& + ")"; + then str; + end matchcontinue; +end printConnectionStr; protected function printEdges "Prints a list of edges to stdout." @@ -749,4 +1215,176 @@ algorithm end matchcontinue; end getConnections; +protected function removeBrokenConnectionsFromSets +"@author: adrpo + This function gets a list of connects and the connections sets + and it will remove all component refences from the connection sets + that have the origin in the given list of connects." + input Connect.Sets inSets; + input list> inBrokenConnects; + output Connect.Sets outSets; +algorithm + outSets := matchcontinue(inSets, inBrokenConnects) + local + list setLst "the connection set"; + list connection "connection_set connect_refs"; + list deletedComponents "list of components with conditional declaration = false"; + list outerConnects "connect statements to propagate upwards"; + list> broken; + + case (Connect.SETS(setLst, connection, deletedComponents, outerConnects), broken) + equation + setLst = removeBrokenConnectionsFromSetLst(setLst, broken); + outerConnects = Util.listSelect1(outerConnects, broken, outerConenctNOTFromConnect); + then + Connect.SETS(setLst, connection, deletedComponents, outerConnects); + end matchcontinue; +end removeBrokenConnectionsFromSets; + +protected function removeBrokenConnectionsFromSetLst +"@author: adrpo + This function gets a list of connects and the connections sets + and it will remove all component refences from the connection sets + that have the origin in the given list of connects." + input list inSetLst; + input list> inBrokenConnects; + output list outSetLst; +algorithm + outSetLst := matchcontinue(inSetLst, inBrokenConnects) + local + list rest, sets; + list> expComponentRefLst; + list> tplExpComponentRefFaceLst; + list> broken; + + // handle empty case + case ({}, _) then {}; + + // handle potential equality + case (Connect.EQU(expComponentRefLst)::rest, broken) + equation + // keep all that did not came from broken connections! + expComponentRefLst = + Util.listSelect1(expComponentRefLst, broken, equNOTFromConnect); + sets = removeBrokenConnectionsFromSetLst(rest, broken); + then Connect.EQU(expComponentRefLst)::sets; + + // handle flows + case (Connect.FLOW(tplExpComponentRefFaceLst)::rest, broken) + equation + // keep all that did not came from broken connections! + tplExpComponentRefFaceLst = + Util.listSelect1(tplExpComponentRefFaceLst, broken, flowNOTFromConnect); + sets = removeBrokenConnectionsFromSetLst(rest, broken); + then Connect.FLOW(tplExpComponentRefFaceLst)::sets; + end matchcontinue; +end removeBrokenConnectionsFromSetLst; + +protected function equNOTFromConnect +"@author: adrpo + This function returns true if the cref has an element source in the given broken connects" + input tuple equConnect; + input list> inBrokenConnects; + output Boolean isNotPresent; +algorithm + isNotPresent := matchcontinue(equConnect, inBrokenConnects) + local + list>> connectOptLst; + + // return true if the origin is not in the broken connects + case ((_, DAE.SOURCE(connectEquationOptLst = connectOptLst)), inBrokenConnects) + equation + false = elementSourceInBrokenConnects(connectOptLst, inBrokenConnects); + then true; + + // return false if the origin is in the broken connects + case ((_, DAE.SOURCE(connectEquationOptLst = connectOptLst)), inBrokenConnects) + equation + true = elementSourceInBrokenConnects(connectOptLst, inBrokenConnects); + then false; + end matchcontinue; +end equNOTFromConnect; + +protected function flowNOTFromConnect +"@author: adrpo + This function returns true if the cref has an element source in the given broken connects" + input tuple flowConnect; + input list> inBrokenConnects; + output Boolean isNotPresent; +algorithm + isNotPresent := matchcontinue(flowConnect, inBrokenConnects) + local + list>> connectOptLst; + + // return true if the origin is not in the broken connects + case ((_, _, DAE.SOURCE(connectEquationOptLst = connectOptLst)), inBrokenConnects) + equation + false = elementSourceInBrokenConnects(connectOptLst, inBrokenConnects); + then true; + + // return false if the origin is in the broken connects + case ((_, _, DAE.SOURCE(connectEquationOptLst = connectOptLst)), inBrokenConnects) + equation + true = elementSourceInBrokenConnects(connectOptLst, inBrokenConnects); + then false; + end matchcontinue; +end flowNOTFromConnect; + +protected function outerConenctNOTFromConnect +"@author: adrpo + This function returns true if the cref has an element source in the given broken connects" + input Connect.OuterConnect outerConnects; + input list> inBrokenConnects; + output Boolean isNotPresent; +algorithm + isNotPresent := matchcontinue(outerConnects, inBrokenConnects) + local + list>> connectOptLst; + + // return true if the origin is not in the broken connects + case (Connect.OUTERCONNECT(source = DAE.SOURCE(connectEquationOptLst = connectOptLst)), inBrokenConnects) + equation + false = elementSourceInBrokenConnects(connectOptLst, inBrokenConnects); + then true; + + // return false if the origin is in the broken connects + case (Connect.OUTERCONNECT(source = DAE.SOURCE(connectEquationOptLst = connectOptLst)), inBrokenConnects) + equation + true = elementSourceInBrokenConnects(connectOptLst, inBrokenConnects); + then false; + end matchcontinue; +end outerConenctNOTFromConnect; + +protected function elementSourceInBrokenConnects +"@author: adrpo + " + input list>> connectEquationOptLst; + input list> inBrokenConnects; + output Boolean presentInBrokenConnects; +algorithm + presentInBrokenConnects := matchcontinue(connectEquationOptLst, inBrokenConnects) + local + list> rest; + DAE.ComponentRef left, right; + Boolean b; + + // empty case + case (connectEquationOptLst, {}) then false; + + // current element is in connection list + case (connectEquationOptLst, (left, right)::rest) + equation + true = isInConnectionList(connectEquationOptLst, left, right); + print("Found it!\n"); + then true; + + // current element is NOT in connection list + case (connectEquationOptLst, (left, right)::rest) + equation + false = isInConnectionList(connectEquationOptLst, left, right); + b = elementSourceInBrokenConnects(connectEquationOptLst, rest); + then b; + end matchcontinue; +end elementSourceInBrokenConnects; + end ConnectionGraph; diff --git a/Compiler/Inst.mo b/Compiler/Inst.mo index 43047778742..49c6f4555f9 100644 --- a/Compiler/Inst.mo +++ b/Compiler/Inst.mo @@ -403,13 +403,12 @@ protected function reEvaluateInitialIfEqns " Author BZ This is a backpatch to fix the case of 'connection.isRoot' in initial if equations. After the class is instantiated a second sweep is done to check the initial if equations conditions. -If all conditions are constand, we return only the 'correct' branch equations. -" -input Env.Cache cache; -input Env.Env env; -input DAE.DAElist dae; -input Boolean isTopCall; -output DAE.DAElist odae; +If all conditions are constand, we return only the 'correct' branch equations." + input Env.Cache cache; + input Env.Env env; + input DAE.DAElist dae; + input Boolean isTopCall; + output DAE.DAElist odae; algorithm odae := matchcontinue(cache,env,dae,isTopCall) local DAE.FunctionTree funcs; @@ -424,10 +423,10 @@ algorithm odae := matchcontinue(cache,env,dae,isTopCall) end reEvaluateInitialIfEqns; protected function reEvaluateInitialIfEqns2 "" -input Env.Cache cache; -input Env.Env env; -input list elems; -output list oelems; + input Env.Cache cache; + input Env.Env env; + input list elems; + output list oelems; algorithm oelems := matchcontinue(cache,env,elems) local list conds; @@ -464,10 +463,9 @@ end reEvaluateInitialIfEqns2; protected function makeDAEElementInitial " Author BZ -Helper function for reEvaluateInitialIfEqns, makes the contenst of an initial if equation initial. -" -input list inElems; -output list outElems; +Helper function for reEvaluateInitialIfEqns, makes the contenst of an initial if equation initial." + input list inElems; + output list outElems; algorithm outElems := matchcontinue(inElems) local @@ -1217,7 +1215,7 @@ algorithm InnerOuter.checkMissingInnerDecl(dae1_1,callscope_1); (csets_1,_) = InnerOuter.retrieveOuterConnections(cache,env_3,ih,pre,csets_1,callscope_1); // print("updated sets: ");print(Connect.printSetsStr(csets_1));print("\n"); - dae2 = ConnectUtil.equations(csets_1,pre); + (dae2,graph) = ConnectUtil.equations(csets_1,pre,callscope_1,graph); (cache,dae3) = ConnectUtil.unconnectedFlowEquations(cache, csets_1, dae1, env_3, pre, callscope_1, {}); dae1_1 = updateTypesInUnconnectedConnectors(dae3,dae1_1); dae = DAEUtil.joinDaeLst({dae1_1,dae2,dae3}); @@ -1618,11 +1616,11 @@ algorithm ci_state = ClassInf.start(r, Env.getEnvName(env_1)); c_1 = SCode.classSetPartial(c, false); (cache,env_3,ih,store,dae1,(csets_1 as Connect.SETS(_,crs,dc,oc)),ci_state_1,tys,bc_ty,_,_,_) - = instClassIn(cache,env_1,ih,store, mod, pre, csets, ci_state, c_1, false, inst_dims, impl, ConnectionGraph.EMPTY,NONE); + = instClassIn(cache,env_1,ih,store, mod, pre, csets, ci_state, c_1, false, inst_dims, impl, ConnectionGraph.EMPTY, NONE); (cache,fq_class) = makeFullyQualified(cache,env_3, Absyn.IDENT(n)); dae1_1 = DAEUtil.addComponentType(dae1, fq_class); callscope_1 = isTopCall(callscope); - dae2 = ConnectUtil.equations(csets_1,pre); + (dae2 ,_) = ConnectUtil.equations(csets_1,pre,callscope_1,ConnectionGraph.EMPTY); (cache,dae3) = ConnectUtil.unconnectedFlowEquations(cache,csets_1, dae1, env_3, pre,callscope_1,{}); dae = DAEUtil.joinDaes(dae1_1,DAEUtil.joinDaes(dae2,dae3)); /* @@ -2667,7 +2665,7 @@ algorithm case (cache,env,store,csets,pre,compDAE,daes) equation // Perform unit checking/dimensional analysis - daetemp = ConnectUtil.equations(csets,pre); // ToDO. calculation of connect eqns done twice. remove in future. + (daetemp,_) = ConnectUtil.equations(csets,pre,false,ConnectionGraph.EMPTY); // ToDO. calculation of connect eqns done twice. remove in future. // equations from components (dae1) not considered, they are checked in resp recursive call // but bindings on scalar variables must be considered, therefore passing dae1 separately daetemp = DAEUtil.joinDaeLst(daetemp::daes); @@ -5394,10 +5392,10 @@ algorithm env_1 = Env.updateFrameV(env2_1, new_var, Env.VAR_DAE(), compenv); vars = Util.if_(alreadyDeclared,{},{DAE.TYPES_VAR(n,DAE.ATTR(flowPrefix,streamPrefix,acc,param,dir,io),prot,ty,binding,NONE())}); dae = Util.if_(alreadyDeclared,DAEUtil.extractFunctions(dae),dae); - (dae,ih,graph) = InnerOuter.handleInnerOuterEquations(io,dae,ih,graphNew,graph); + (dae,ih,graphNew) = InnerOuter.handleInnerOuterEquations(io,dae,ih,graphNew,graph); /* if declaration condition is true, remove dae elements and connections */ - (cache,dae,csets_1,graph,fdae) = instConditionalDeclaration(cache,env2,cond,n,dae,csets_1,pre,graph); + (cache,dae,csets_1,graph,fdae) = instConditionalDeclaration(cache,env2,cond,n,dae,csets_1,pre,graph,graphNew); dae = DAEUtil.joinDaeLst({dae,fdae,fdae0,fdae1,fdae2,fdae3,fdae4,fdae5,fdae6,fdae7}); then (cache,env_1,ih,store,dae,csets_1,ci_state,vars,graph); @@ -13192,7 +13190,7 @@ algorithm print(") with ");print(Dump.unparseInnerouterStr(io1));print(", ");print(Dump.unparseInnerouterStr(io2)); print("\n");*/ (cache,_,ih,sets_3,dae,graph) = - connectComponents(cache,env,ih, sets_2, pre, c1_2, f1, ty1,vt1, c2_2, f2, ty2,vt2, flow1,io1,io2,graph); + connectComponents(cache, env, ih, sets_2, pre, c1_2, f1, ty1, vt1, c2_2, f2, ty2, vt2, flow1, io1, io2, graph); then (cache,env,ih,sets_3,dae,graph); @@ -13727,7 +13725,7 @@ algorithm // Connect components ignoring equality constraints (cache,env,ih,sets_1,dae,_) = connectComponents( - cache,env,ih,sets, pre, + cache, env, ih, sets, pre, c1, f1, t1, vt1, c2, f2, t2, vt2, flowPrefix, io1, io2, ConnectionGraph.NOUPDATE_EMPTY); @@ -13735,7 +13733,7 @@ algorithm /* We can form the daes from connection set already at this point because there must not be flow components in types having equalityConstraint. TODO Is this correct if inner/outer has been used? */ - //dae2 = ConnectUtil.equations(sets_1,pre); + //(dae2,graph) = ConnectUtil.equations(sets_1,pre,false,graph); //dae = listAppend(dae, dae2); //DAE.printDAE(DAE.DAE(dae)); @@ -13758,7 +13756,7 @@ algorithm /* Complex types t1 extending basetype */ case (cache,env,ih,sets,pre,c1,f1,(DAE.T_COMPLEX(complexVarLst = l1,complexTypeOption = SOME(bc_tp1)),_),vt1,c2,f2,t2,vt2,flowPrefix,io1,io2,graph) equation - (cache,_,ih,sets_1,dae,graph) = connectComponents(cache,env,ih, sets, pre, c1, f1, bc_tp1,vt1, c2, f2, t2,vt2, flowPrefix,io1,io2,graph); + (cache,_,ih,sets_1,dae,graph) = connectComponents(cache, env, ih, sets, pre, c1, f1, bc_tp1,vt1, c2, f2, t2,vt2, flowPrefix,io1,io2, graph); then (cache,env,ih,sets_1,dae,graph); @@ -16119,38 +16117,41 @@ protected function instConditionalDeclaration input DAE.DAElist dae; input Connect.Sets sets; input Prefix.Prefix pre; - input ConnectionGraph.ConnectionGraph inGraph; + input ConnectionGraph.ConnectionGraph inGraphOld; + input ConnectionGraph.ConnectionGraph inGraphNew; output Env.Cache outCache; output DAE.DAElist outDae; output Connect.Sets outSets; output ConnectionGraph.ConnectionGraph outGraph; output DAE.DAElist outDae; algorithm - (outCache,outDae,outSets,outGraph,outDae) := matchcontinue(cache,env,cond,compName,dae,sets,pre,inGraph) + (outCache,outDae,outSets,outGraph,outDae) := matchcontinue(cache,env,cond,compName,dae,sets,pre,inGraphOld,inGraphNew) local Absyn.Exp condExp; DAE.Exp e; DAE.Type t; DAE.Const c; String s1,s2; Boolean b; DAE.ComponentRef cr; - ConnectionGraph.ConnectionGraph graph; + ConnectionGraph.ConnectionGraph graph,graphOld,graphNew; DAE.DAElist dae,dae1,dae2; // no condition ... keep the same - case(cache,env,NONE,compName,dae,sets,_,graph) then (cache,dae,sets,graph,DAEUtil.emptyDae); + case(cache,env,NONE,compName,dae,sets,_,graphOld,graphNew) then (cache,dae,sets,graphNew,DAEUtil.emptyDae); // we have some condition, deal with it - case(cache,env,SOME(condExp),compName,dae,sets,pre,graph) equation + case(cache,env,SOME(condExp),compName,dae,sets,pre,graphOld,graphNew) equation (cache,e,DAE.PROP(t,c ),_,dae1) = Static.elabExp(cache, env, condExp, false, NONE, false); true = Types.isBoolean(t); true = Types.isParameterOrConstant(c); (cache,Values.BOOL(b),_) = Ceval.ceval(cache, env, e, false, NONE, NONE, Ceval.MSG()); dae = Util.if_(b,dae,DAEUtil.extractFunctions(dae)); + // if the condition is false the connection graph stays the same!! + graph = Util.if_(b,graphNew,graphOld); cr = PrefixUtil.prefixCref(pre,DAE.CREF_IDENT(compName,DAE.ET_OTHER(),{})); sets = ConnectUtil.addDeletedComponent(b,cr,sets); then (cache,dae,sets,graph,dae1); // Error: Wrong type on condition - case(cache,env,SOME(condExp),compName,dae,sets,_,graph) equation + case(cache,env,SOME(condExp),compName,dae,sets,_,graphOld,graphNew) equation (cache,e,DAE.PROP(t,c ),_,_) = Static.elabExp(cache, env, condExp, false, NONE, false); false = Types.isBoolean(t); s1 = Exp.printExpStr(e); @@ -16159,7 +16160,7 @@ algorithm then fail(); // Error: condition not parameter or constant - case(cache,env,SOME(condExp),compName,dae,sets,_,graph) equation + case(cache,env,SOME(condExp),compName,dae,sets,_,graphOld,graphNew) equation (cache,e,DAE.PROP(t,c ),_,_) = Static.elabExp(cache, env, condExp, false, NONE, false); true = Types.isBoolean(t); false = Types.isParameterOrConstant(c); @@ -16167,7 +16168,7 @@ algorithm Error.addMessage(Error.COMPONENT_CONDITION_VARIABILITY,{s1}); then fail(); // failtrace - case(cache,env,SOME(condExp),compName,dae,sets,_,graph) + case(cache,env,SOME(condExp),compName,dae,sets,_,graphOld,graphNew) equation Debug.fprintln("failtrace", "- Inst.instConditionalDeclaration failed on component: " +& compName +& " for cond: " +& Dump.printExpStr(condExp)); then fail(); diff --git a/Compiler/Util.mo b/Compiler/Util.mo index c944b53491c..5ee47a4f397 100644 --- a/Compiler/Util.mo +++ b/Compiler/Util.mo @@ -1708,6 +1708,7 @@ algorithm (f_1 :: r_1); end matchcontinue; end listMap8; + public function listMap32 "function listMap32 Takes a list and a function and three extra arguments passed to the function. The function produces two values which is used for creating two new lists." @@ -2681,7 +2682,10 @@ algorithm end listSelect; public function listSelect1 "function listSelect1 - Same as listSelect above, but with extra argument to testing function." + This function retrieves all elements of a list for which + the passed function evaluates to true. The elements that + evaluates to false are thus removed from the list. + This function has an extra argument to testing function." input list inTypeALst; input Type_b inTypeB; input FuncTypeType_aType_bToBoolean inFuncTypeTypeATypeBToBoolean;