Issue 15088: Additional changes required for structured activity node execution (fuml-ftf) Source: Model Driven Solutions (Mr. Ed Seidewitz, ed-s(at)modeldriven.com) Nature: Uncategorized Issue Severity: Summary: Specification: Semantics of a Foundational Subset for Executable UML Models Subclause: 8.5.2.2.5 ActivityNodeActivationGroup Some necessary changes to the specification for ActivityNodeActivationGroup were inadvertently left out of the revised text for the resolution to Issue 14547 approved by the FTF. The additional changes are: Added the operation checkIncomingEdges ( in incomingEdges : ActivityEdgeInstance [0..*], in activations : ActivityNodeActivation [0..*] ) : Boolean with the code: // Check if any incoming edges have a source in a given set of activations. int j = 1; boolean notFound = true; while (j <= incomingEdges.size() & notFound) { int k = 1; while (k <= activations.size() & notFound) { if (activations.getValue(k-1).isSourceFor(incomingEdges.getValue(j-1))) { notFound = false; } k = k + 1; } j = j + 1; } return notFound; In the operation Run, replace the code: ActivityEdgeInstanceList incomingEdges = activation.incomingEdges; boolean isEnabled; if (activation instanceof ActionActivation) { isEnabled = ((Action)activation.node).input.size() == 0; } else { isEnabled = (activation instanceof ControlNodeActivation) | (activation instanceof ActivityParameterNodeActivation); } int j = 1; while (j <= incomingEdges.size() & isEnabled) { int k = 1; while (k <= activations.size() & isEnabled) { if (activations.getValue(k-1).isSourceFor(incomingEdges.getValue(j-1))) { isEnabled = false; } k = k + 1; } j = j + 1; } if (isEnabled) { Debug.println("[run] Node " + activation.node.name + " is enabled."); enabledActivations.addValue(activation); } } With: if (activation instanceof ActionActivation | activation instanceof ControlNodeActivation | activation instanceof ActivityParameterNodeActivation) { boolean isEnabled = this.checkIncomingEdges(activation.incomingEdges, activations); // For an action activation, also consider incoming edges to input pins if (isEnabled & activation instanceof ActionActivation) { InputPinList inputPins = ((Action)activation.node).input; int j = 1; while (j <= inputPins.size() & isEnabled) { InputPin inputPin = inputPins.getValue(j-1); ActivityEdgeInstanceList inputEdges = ((ActionActivation)activation).getPinActivation(inputPin).incomingEdges; isEnabled = this.checkIncomingEdges(inputEdges, activations); j = j + 1; } } if (isEnabled) { Debug.println("[run] Node " + activation.node.name + " is enabled."); enabledActivations.addValue(activation); } } } Resolution: Agreed. Revised Text: In Subclause 8.5.2.2.5 and in Figure 73, add the operation checkIncomingEdges ( in incomingEdges : ActivityEdgeInstance [0..*], in activations : ActivityNodeActivation [0..*] ) : Boolean with the code: // Check if any incoming edges have a source in a given set of activations. int j = 1; boolean notFound = true; while (j <= incomingEdges.size() & notFound) { int k = 1; while (k <= activations.size() & notFound) { if (activations.getValue(k-1).isSourceFor(incomingEdges.getValue(j-1))) { notFound = false; } k = k + 1; } j = j + 1; } return notFound; In the operation Run, replace the code: ActivityEdgeInstanceList incomingEdges = activation.incomingEdges; boolean isEnabled; if (activation instanceof ActionActivation) { isEnabled = ((Action)activation.node).input.size() == 0; } else { isEnabled = (activation instanceof ControlNodeActivation) | (activation instanceof ActivityParameterNodeActivation); } int j = 1; while (j <= incomingEdges.size() & isEnabled) { int k = 1; while (k <= activations.size() & isEnabled) { if (activations.getValue(k-1).isSourceFor(incomingEdges.getValue(j-1))) { isEnabled = false; } k = k + 1; } j = j + 1; } if (isEnabled) { Debug.println("[run] Node " + activation.node.name + " is enabled."); enabledActivations.addValue(activation); } } With: if (activation instanceof ActionActivation | activation instanceof ControlNodeActivation | activation instanceof ActivityParameterNodeActivation) { boolean isEnabled = this.checkIncomingEdges(activation.incomingEdges, activations); // For an action activation, also consider incoming edges to input pins if (isEnabled & activation instanceof ActionActivation) { InputPinList inputPins = ((Action)activation.node).input; int j = 1; while (j <= inputPins.size() & isEnabled) { InputPin inputPin = inputPins.getValue(j-1); ActivityEdgeInstanceList inputEdges = ((ActionActivation)activation).getPinActivation(inputPin).incomingEdges; isEnabled = this.checkIncomingEdges(inputEdges, activations); j = j + 1; } } if (isEnabled) { Debug.println("[run] Node " + activation.node.name + " is enabled."); enabledActivations.addValue(activation); } } } Actions taken: February 25, 2010: received issue July 23, 2010: closed issue Discussion: End of Annotations:===== ubject: Additional changes required for structured activity node execution Date: Thu, 25 Feb 2010 20:00:44 -0500 X-MS-Has-Attach: X-MS-TNEF-Correlator: Thread-Topic: Additional changes required for structured activity node execution thread-index: Acq2fx/5bc4EEaNuTFSP+o762sgwUg== From: "Ed Seidewitz" To: Specification: Semantics of a Foundational Subset for Executable UML Models Subclause: 8.5.2.2.5 ActivityNodeActivationGroup Some necessary changes to the specification for ActivityNodeActivationGroup were inadvertently left out of the revised text for the resolution to Issue 14547 approved by the FTF. The additional changes are: Added the operation checkIncomingEdges ( in incomingEdges : ActivityEdgeInstance [0..*], in activations : ActivityNodeActivation [0..*] ) : Boolean with the code: // Check if any incoming edges have a source in a given set of activations. int j = 1; boolean notFound = true; while (j <= incomingEdges.size() & notFound) { int k = 1; while (k <= activations.size() & notFound) { if (activations.getValue(k-1).isSourceFor(incomingEdges.getValue(j-1))) { notFound = false; } k = k + 1; } j = j + 1; } return notFound; In the operation Run, replace the code: ActivityEdgeInstanceList incomingEdges = activation.incomingEdges; boolean isEnabled; if (activation instanceof ActionActivation) { isEnabled = ((Action)activation.node).input.size() == 0; } else { isEnabled = (activation instanceof ControlNodeActivation) | (activation instanceof ActivityParameterNodeActivation); } int j = 1; while (j <= incomingEdges.size() & isEnabled) { int k = 1; while (k <= activations.size() & isEnabled) { if (activations.getValue(k-1).isSourceFor(incomingEdges.getValue(j-1))) { isEnabled = false; } k = k + 1; } j = j + 1; } if (isEnabled) { Debug.println("[run] Node " + activation.node.name + " is enabled."); enabledActivations.addValue(activation); } } With: if (activation instanceof ActionActivation | activation instanceof ControlNodeActivation | activation instanceof ActivityParameterNodeActivation) { boolean isEnabled = this.checkIncomingEdges(activation.incomingEdges, activations); // For an action activation, also consider incoming edges to input pins if (isEnabled & activation instanceof ActionActivation) { InputPinList inputPins = ((Action)activation.node).input; int j = 1; while (j <= inputPins.size() & isEnabled) { InputPin inputPin = inputPins.getValue(j-1); ActivityEdgeInstanceList inputEdges = ((ActionActivation)activation).getPinActivation(inputPin).incomingEdges; isEnabled = this.checkIncomingEdges(inputEdges, activations); j = j + 1; } } if (isEnabled) { Debug.println("[run] Node " + activation.node.name + " is enabled."); enabledActivations.addValue(activation); } } }