Skip to content

Commit

Permalink
has_outgoing_relation
Browse files Browse the repository at this point in the history
  • Loading branch information
milesstoetzner authored Aug 18, 2023
1 parent a0be47a commit fe62a27
Show file tree
Hide file tree
Showing 19 changed files with 230 additions and 8 deletions.
20 changes: 12 additions & 8 deletions docs/docs/variability4tosca/specification/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -259,14 +259,16 @@ In contrast, a semantic condition targets semantic aspect of elements or the ty
Depending on the context, other default conditions are more applicable.
The following default conditions can be chosen instead of the ones introduced above.

| Element | Consistency | Semantic | Default Conditions |
|--------------------------------------------------------|-------------|----------|--------------------------------------------------------------------------------|
| Node Template with Incoming Relations (incomingnaive) | false | true | Check if any incoming relation is present using `has_incoming_relation_naive`. |
| Node Template with Incoming Relations (source) | false | true | Check if any source of any incoming relation is present. |
| Node Template with Host (host) | false | true | Check if any host is present. |
| Node Template with Artifact (artifactnaive) | false | true | Check if any artifact is present using `has_artifact_naive`. |
| Relation (Source) | true | false | Check if the source of the relation is present. |
| Relation (Target) | true | false | Check if the target of the relation is present. |
| Element | Consistency | Semantic | Default Conditions |
|-------------------------------------------------------|-------------|----------|--------------------------------------------------------------------------------|
| Node Template with Incoming Relations (incomingnaive) | false | true | Check if any incoming relation is present using `has_incoming_relation_naive`. |
| Node Template with Incoming Relations (source) | false | true | Check if any source of any incoming relation is present. |
| Node Template with Outgoing Relations (outgoing) | false | true | Check if any outgoing relation is present. |
| Node Template with Outgoing Relations (outgoingnaive) | false | true | Check if any outgoing relation is present using `has_outgoing_relation_naive`. |
| Node Template with Host (host) | false | true | Check if any host is present. |
| Node Template with Artifact (artifactnaive) | false | true | Check if any artifact is present using `has_artifact_naive`. |
| Relation (Source) | true | false | Check if the source of the relation is present. |
| Relation (Target) | true | false | Check if the target of the relation is present. |


### Type-Specific Default Conditions
Expand Down Expand Up @@ -741,6 +743,8 @@ The following presence operators can be used inside a logic expression.
| has_source | Node: String | SELF | CONTAINER | Boolean | Returns if any source of any incoming relation of the node template is present. |
| has_incoming_relation | Node: String | SELF | CONTAINER | Boolean | Returns if the node template is target of at least one present incoming relationship. |
| has_incoming_relation_naive | Node: String | SELF | CONTAINER | Boolean | Returns if the node template is target of at least one present incoming relationship in a naive way that will result in a circle considering the default condition of relations. |
| has_outgoing_relation | Node: String | SELF | CONTAINER | Boolean | Returns if the node template is source of at least one present outgoing relationship. |
| has_outgoing_relation_naive | Node: String | SELF | CONTAINER | Boolean | Returns if the node template is source of at least one present outgoing relationship in a naive way that will result in a circle considering the default condition of relations. |
| has_artifact | Node: String | SELF | CONTAINER | Boolean | Returns if any artifact of the node template is present. |
| has_artifact_naive | Node: String | SELF | CONTAINER | Boolean | Returns if any artifact of the node template is present in a naive way that will result in a circle considering the default condition of artifacts. |
| relation_presence | Tuple(Node: String | SELF | CONTAINER, Relation: String | Number) | Boolean | Returns if relation is present. |
Expand Down
12 changes: 12 additions & 0 deletions src/graph/node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,18 @@ export default class Node extends Element {
)
}

if (it === 'outgoing') {
return conditions.push(
this.isSource ? {has_outgoing_relation: this.toscaId, _cached_element: this} : true
)
}

if (it === 'outgoingnaive') {
return conditions.push(
this.isSource ? {has_outgoing_relation_naive: this.toscaId, _cached_element: this} : true
)
}

if (it === 'artifact') {
return conditions.push(this.hasArtifact ? {has_artifact: this.toscaId, _cached_element: this} : true)
}
Expand Down
22 changes: 22 additions & 0 deletions src/resolver/solver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,28 @@ export default class Solver {
return MiniSat.or(node.ingoing.map(it => it.id))
}

/**
* has_outgoing_relation
*/
if (check.isDefined(expression.has_outgoing_relation)) {
const node = this.graph.getNode(expression.has_outgoing_relation, {
element,
cached,
})
return MiniSat.or(node.outgoing.map(it => MiniSat.and(it.explicitId, it.target.id)))
}

/**
* has_outgoing_relation_naive
*/
if (check.isDefined(expression.has_outgoing_relation_naive)) {
const node = this.graph.getNode(expression.has_outgoing_relation_naive, {
element,
cached,
})
return MiniSat.or(node.outgoing.map(it => it.id))
}

/**
* has_artifact
*/
Expand Down
4 changes: 4 additions & 0 deletions src/specification/variability.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ export type NodeDefaultConditionMode =
| 'artifact'
| 'artifactnaive'
| 'incoming-artifact'
| 'outgoing'
| 'outgoingnaive'
export type RelationDefaultConditionMode = 'source-target' | 'source' | 'target'

export type DefaultOptions = {
Expand Down Expand Up @@ -202,6 +204,8 @@ export type LogicExpression =
has_source?: string | 'SELF' | 'CONTAINER'
has_incoming_relation?: string | 'SELF' | 'CONTAINER'
has_incoming_relation_naive?: string | 'SELF' | 'CONTAINER'
has_outgoing_relation?: string | 'SELF' | 'CONTAINER'
has_outgoing_relation_naive?: string | 'SELF' | 'CONTAINER'
has_artifact?: string | 'SELF' | 'CONTAINER'
has_artifact_naive?: string | 'SELF' | 'CONTAINER'

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
tosca_definitions_version: tosca_simple_yaml_1_3

topology_template:
node_templates:
target:
type: target
22 changes: 22 additions & 0 deletions tests/conformance/pruning/outgoing-relation-absent/template.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
tosca_definitions_version: tosca_variability_1_0

topology_template:
variability:
options:
node_default_condition: true
node_default_condition_mode: outgoing

relation_default_condition: true
relation_default_condition_mode: source-target

type_default_condition: true
node_templates:
source:
type: source
requirements:
- relation:
node: target
conditions: false

target:
type: target
8 changes: 8 additions & 0 deletions tests/conformance/pruning/outgoing-relation-absent/test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
description: |
- The node "source" has an outgoing relation "relation" to node "target".
- The node default condition mode "outgoing" is used.
- Thus, there is no cycle.
- "relation" is absent
- Thus, "source" is absent
- "target" is always present
12 changes: 12 additions & 0 deletions tests/conformance/pruning/outgoing-relation-present/expected.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
tosca_definitions_version: tosca_simple_yaml_1_3

topology_template:
node_templates:
source:
type: source
requirements:
- relation:
node: target

target:
type: target
22 changes: 22 additions & 0 deletions tests/conformance/pruning/outgoing-relation-present/template.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
tosca_definitions_version: tosca_variability_1_0

topology_template:
variability:
options:
node_default_condition: true
node_default_condition_mode: outgoing

relation_default_condition: true
relation_default_condition_mode: source-target

type_default_condition: true
node_templates:
source:
type: source
requirements:
- relation:
node: target
conditions: true

target:
type: target
8 changes: 8 additions & 0 deletions tests/conformance/pruning/outgoing-relation-present/test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
description: |
- The node "source" has an outgoing relation "relation" to node "target".
- The node default condition mode "outgoing" is used.
- Thus, there is no cycle.
- "relation" is present
- Thus, "source" is present
- "target" is always present
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
tosca_definitions_version: tosca_simple_yaml_1_3
22 changes: 22 additions & 0 deletions tests/conformance/pruning/outgoing-target-absent/template.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
tosca_definitions_version: tosca_variability_1_0

topology_template:
variability:
options:
node_default_condition: true
node_default_condition_mode: outgoing

relation_default_condition: true
relation_default_condition_mode: source-target

type_default_condition: true
node_templates:
source:
type: source
requirements:
- relation:
node: target

target:
type: target
conditions: false
8 changes: 8 additions & 0 deletions tests/conformance/pruning/outgoing-target-absent/test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
description: |
- The node "source" has an outgoing relation "relation" to node "target".
- The node default condition mode "outgoing" is used.
- Thus, there is no cycle.
- "target" is absent
- Thus, "relation" is absent
- Thus, "source" is absent
12 changes: 12 additions & 0 deletions tests/conformance/pruning/outgoing-target-present/expected.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
tosca_definitions_version: tosca_simple_yaml_1_3

topology_template:
node_templates:
source:
type: source
requirements:
- relation:
node: target

target:
type: target
21 changes: 21 additions & 0 deletions tests/conformance/pruning/outgoing-target-present/template.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
tosca_definitions_version: tosca_variability_1_0

topology_template:
variability:
options:
node_default_condition: true
node_default_condition_mode: outgoing

relation_default_condition: true
relation_default_condition_mode: source-target

type_default_condition: true
node_templates:
source:
type: source
requirements:
- relation:
node: target

target:
type: target
5 changes: 5 additions & 0 deletions tests/conformance/pruning/outgoing-target-present/test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
description: |
- The node "source" has an outgoing relation "relation" to node "target".
- The node default condition mode "outgoing" is used.
- Thus, there is no cycle.
- Nothing is removed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
tosca_definitions_version: tosca_simple_yaml_1_3

topology_template:
node_templates:
target:
type: target
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
tosca_definitions_version: tosca_variability_1_0

topology_template:
variability:
options:
node_default_condition: true
node_default_condition_mode: outgoingnaive

relation_default_condition: true
relation_default_condition_mode: source-target

type_default_condition: true
node_templates:
source:
type: source
requirements:
- relation:
node: target

target:
type: target
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
description: |
- The node "source" has an outgoing relation "relation" to node "target".
- The node default condition mode "outgoingnaive" is used.
- Thus, there is a cycle: "source" checks if "relation" is present and "relation" checks if "source" is present.
- Thus, "source" and "relation" can be removed.
- "target" is present since it has no default condition assigned.

0 comments on commit fe62a27

Please sign in to comment.