Skip to content

Commit

Permalink
Improve handling of conditional components (#7783)
Browse files Browse the repository at this point in the history
- 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.
  • Loading branch information
perost committed Aug 19, 2021
1 parent db83ff0 commit 78435df
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 75 deletions.
9 changes: 0 additions & 9 deletions OMCompiler/Compiler/NFFrontEnd/NFComponent.mo
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
61 changes: 5 additions & 56 deletions OMCompiler/Compiler/NFFrontEnd/NFFlatten.mo
Expand Up @@ -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;

Expand Down Expand Up @@ -315,8 +318,6 @@ algorithm
then
();

case Component.DELETED_COMPONENT() then ();

else
algorithm
Error.assertion(false, getInstanceName() + " got unknown component", sourceInfo());
Expand All @@ -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);
Expand All @@ -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<InstNode> 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;
Expand Down
20 changes: 10 additions & 10 deletions OMCompiler/Compiler/NFFrontEnd/NFTyping.mo
Expand Up @@ -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);

Expand All @@ -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
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -934,8 +934,6 @@ algorithm
then
();

case Component.DELETED_COMPONENT() then ();

else
algorithm
Error.assertion(false, getInstanceName() + " got invalid node " + InstNode.name(node), sourceInfo());
Expand Down Expand Up @@ -2710,15 +2708,17 @@ protected
algorithm
comp := InstNode.component(component);

if Component.isDeleted(comp) then
return;
end if;

() := match comp
case Component.TYPED_COMPONENT()
algorithm
typeClassSections(comp.classInst, context);
then
();

case Component.DELETED_COMPONENT() then ();

else
algorithm
Error.assertion(false, getInstanceName() + " got uninstantiated component " + InstNode.name(component), sourceInfo());
Expand Down
24 changes: 24 additions & 0 deletions 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
1 change: 1 addition & 0 deletions testsuite/flattening/modelica/scodeinst/Makefile
Expand Up @@ -232,6 +232,7 @@ Condition3.mo \
Condition4.mo \
Condition5.mo \
Condition6.mo \
Condition7.mo \
ConditionInvalid1.mo \
ConditionInvalidBinding1.mo \
ConditionInvalidBinding2.mo \
Expand Down

0 comments on commit 78435df

Please sign in to comment.