From 78435df8406ec3831db1c6e8bd49cbd9b141368a Mon Sep 17 00:00:00 2001 From: perost Date: Thu, 19 Aug 2021 12:34:52 +0200 Subject: [PATCH] Improve handling of conditional components (#7783) - Use the condition directly instead of replacing components when determining if a component is deleted, to allow deleting components in only some elements of an array. --- OMCompiler/Compiler/NFFrontEnd/NFComponent.mo | 9 --- OMCompiler/Compiler/NFFrontEnd/NFFlatten.mo | 61 ++----------------- OMCompiler/Compiler/NFFrontEnd/NFTyping.mo | 20 +++--- .../modelica/scodeinst/Condition7.mo | 24 ++++++++ .../flattening/modelica/scodeinst/Makefile | 1 + 5 files changed, 40 insertions(+), 75 deletions(-) create mode 100644 testsuite/flattening/modelica/scodeinst/Condition7.mo diff --git a/OMCompiler/Compiler/NFFrontEnd/NFComponent.mo b/OMCompiler/Compiler/NFFrontEnd/NFComponent.mo index 7b4dfcd61cf..7c38bb8b529 100644 --- a/OMCompiler/Compiler/NFFrontEnd/NFComponent.mo +++ b/OMCompiler/Compiler/NFFrontEnd/NFComponent.mo @@ -216,10 +216,6 @@ public Modifier modifier; end TYPE_ATTRIBUTE; - record DELETED_COMPONENT - Component component; - end DELETED_COMPONENT; - function new input SCode.Element definition; output Component component; @@ -273,7 +269,6 @@ public case TYPED_COMPONENT() then component.info; case ITERATOR() then component.info; case TYPE_ATTRIBUTE() then Modifier.info(component.modifier); - case DELETED_COMPONENT() then info(component.component); // Fail for enumeration literals, InstNode.info handles that case instead. end match; end info; @@ -362,7 +357,6 @@ public case UNTYPED_COMPONENT() then InstNode.getType(component.classInst); case ITERATOR() then component.ty; case TYPE_ATTRIBUTE() then component.ty; - case DELETED_COMPONENT() then getType(component.component); else Type.UNKNOWN(); end match; end getType; @@ -757,7 +751,6 @@ public cty := match component case UNTYPED_COMPONENT(attributes = Attributes.ATTRIBUTES(connectorType = cty)) then cty; case TYPED_COMPONENT(attributes = Attributes.ATTRIBUTES(connectorType = cty)) then cty; - case DELETED_COMPONENT() then connectorType(component.component); else ConnectorType.NON_CONNECTOR; end match; end connectorType; @@ -985,7 +978,6 @@ public count := match component case UNTYPED_COMPONENT() then arrayLength(component.dimensions); case TYPED_COMPONENT() then listLength(Type.arrayDims(component.ty)); - case DELETED_COMPONENT() then dimensionCount(component.component); else 0; end match; end dimensionCount; @@ -1075,7 +1067,6 @@ public case TYPED_COMPONENT(condition = condition) then Binding.isBound(condition) and Expression.isFalse(Binding.getTypedExp(condition)); - case DELETED_COMPONENT() then true; else false; end match; end isDeleted; diff --git a/OMCompiler/Compiler/NFFrontEnd/NFFlatten.mo b/OMCompiler/Compiler/NFFrontEnd/NFFlatten.mo index cdd40c1fc57..77b34d107d1 100644 --- a/OMCompiler/Compiler/NFFrontEnd/NFFlatten.mo +++ b/OMCompiler/Compiler/NFFrontEnd/NFFlatten.mo @@ -281,12 +281,15 @@ algorithm comp_node := InstNode.resolveOuter(component); c := InstNode.component(comp_node); + if Component.isDeleted(c) then + return; + end if; + () := match c case Component.TYPED_COMPONENT(condition = condition, ty = ty) algorithm // Delete the component if it has a condition that's false. if isDeletedComponent(condition, prefix) then - deleteComponent(component); return; end if; @@ -315,8 +318,6 @@ algorithm then (); - case Component.DELETED_COMPONENT() then (); - else algorithm Error.assertion(false, getInstanceName() + " got unknown component", sourceInfo()); @@ -335,14 +336,7 @@ protected Binding cond; algorithm if Binding.isBound(condition) then - // TODO: Flattening the condition works as intended here, but we can't yet - // delete components inside array instances in a reliable way since - // the components share the same node. I.e. we can't delete a[1].x - // while keeping a[2].x. So for now we skip flattening the condition, - // so that we get an error message in that case instead (because then - // the expression will be an array instead of a scalar boolean). - cond := condition; - //cond := flattenBinding(condition, prefix); + cond := flattenBinding(condition, prefix); exp := Binding.getTypedExp(cond); exp := Ceval.evalExp(exp, Ceval.EvalTarget.CONDITION(Binding.getInfo(cond))); exp := Expression.expandSplitIndices(exp); @@ -366,51 +360,6 @@ algorithm end if; end isDeletedComponent; -function deleteComponent - "Recursively marks components as deleted." - input InstNode compNode; -protected - Component comp; -algorithm - // @adrpo: don't delete the inner/outer node, it doesn't work! - if InstNode.isInnerOuterNode(compNode) then - return; - end if; - - comp := InstNode.component(compNode); - - if not Component.isDeleted(comp) then - InstNode.updateComponent(Component.DELETED_COMPONENT(comp), compNode); - deleteClassComponents(Component.classInstance(comp)); - end if; -end deleteComponent; - -function deleteClassComponents - input InstNode clsNode; -protected - Class cls = InstNode.getClass(clsNode); - array comps; -algorithm - () := match cls - case Class.INSTANCED_CLASS(elements = ClassTree.FLAT_TREE(components = comps)) - guard not Restriction.isType(cls.restriction) - algorithm - for c in comps loop - deleteComponent(c); - end for; - then - (); - - case Class.TYPED_DERIVED() - algorithm - deleteClassComponents(cls.baseClass); - then - (); - - else (); - end match; -end deleteClassComponents; - function getComponentType input Type ty; input FlattenSettings settings; diff --git a/OMCompiler/Compiler/NFFrontEnd/NFTyping.mo b/OMCompiler/Compiler/NFFrontEnd/NFTyping.mo index cd1cc91a5e5..31c1d1ee48d 100644 --- a/OMCompiler/Compiler/NFFrontEnd/NFTyping.mo +++ b/OMCompiler/Compiler/NFFrontEnd/NFTyping.mo @@ -386,12 +386,9 @@ algorithm end if; c_typed := Component.setType(ty, c); + InstNode.updateComponent(c_typed, node); - if is_deleted then - InstNode.updateComponent(Component.DELETED_COMPONENT(c_typed), node); - else - InstNode.updateComponent(c_typed, node); - + if not is_deleted then // Check that flow/stream variables are Real. checkComponentStreamAttribute(c.attributes.connectorType, ty, component); @@ -405,7 +402,6 @@ algorithm case Component.TYPED_COMPONENT() then c.ty; case Component.ITERATOR() then c.ty; case Component.ENUM_LITERAL(literal = Expression.ENUM_LITERAL(ty = ty)) then ty; - case Component.DELETED_COMPONENT() then Component.getType(c.component); // Any other type of component shouldn't show up here. else @@ -848,6 +844,10 @@ algorithm c := InstNode.component(node); () := match c + case Component.TYPED_COMPONENT() + guard Component.isDeleted(c) + then (); + case Component.TYPED_COMPONENT(binding = Binding.UNTYPED_BINDING(), attributes = attrs) algorithm name := InstNode.name(component); @@ -934,8 +934,6 @@ algorithm then (); - case Component.DELETED_COMPONENT() then (); - else algorithm Error.assertion(false, getInstanceName() + " got invalid node " + InstNode.name(node), sourceInfo()); @@ -2710,6 +2708,10 @@ protected algorithm comp := InstNode.component(component); + if Component.isDeleted(comp) then + return; + end if; + () := match comp case Component.TYPED_COMPONENT() algorithm @@ -2717,8 +2719,6 @@ algorithm then (); - case Component.DELETED_COMPONENT() then (); - else algorithm Error.assertion(false, getInstanceName() + " got uninstantiated component " + InstNode.name(component), sourceInfo()); diff --git a/testsuite/flattening/modelica/scodeinst/Condition7.mo b/testsuite/flattening/modelica/scodeinst/Condition7.mo new file mode 100644 index 00000000000..f485f1c402b --- /dev/null +++ b/testsuite/flattening/modelica/scodeinst/Condition7.mo @@ -0,0 +1,24 @@ +// name: Condition7 +// keywords: +// status: correct +// cflags: -d=newInst +// +// + +model A + parameter Boolean b; + Real x if b; +end A; + +model Condition7 + A a[3](b = {false, true, false}); +end Condition7; + +// Result: +// class Condition7 +// final parameter Boolean a[1].b = false; +// final parameter Boolean a[2].b = true; +// Real a[2].x; +// final parameter Boolean a[3].b = false; +// end Condition7; +// endResult diff --git a/testsuite/flattening/modelica/scodeinst/Makefile b/testsuite/flattening/modelica/scodeinst/Makefile index b636a89103e..ad939752004 100644 --- a/testsuite/flattening/modelica/scodeinst/Makefile +++ b/testsuite/flattening/modelica/scodeinst/Makefile @@ -232,6 +232,7 @@ Condition3.mo \ Condition4.mo \ Condition5.mo \ Condition6.mo \ +Condition7.mo \ ConditionInvalid1.mo \ ConditionInvalidBinding1.mo \ ConditionInvalidBinding2.mo \