aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/viatra-runtime-rete/src/main/java/tools/refinery/viatra/runtime/rete/single/TransitiveClosureNode.java
diff options
context:
space:
mode:
Diffstat (limited to 'subprojects/viatra-runtime-rete/src/main/java/tools/refinery/viatra/runtime/rete/single/TransitiveClosureNode.java')
-rw-r--r--subprojects/viatra-runtime-rete/src/main/java/tools/refinery/viatra/runtime/rete/single/TransitiveClosureNode.java147
1 files changed, 147 insertions, 0 deletions
diff --git a/subprojects/viatra-runtime-rete/src/main/java/tools/refinery/viatra/runtime/rete/single/TransitiveClosureNode.java b/subprojects/viatra-runtime-rete/src/main/java/tools/refinery/viatra/runtime/rete/single/TransitiveClosureNode.java
new file mode 100644
index 00000000..eeead31b
--- /dev/null
+++ b/subprojects/viatra-runtime-rete/src/main/java/tools/refinery/viatra/runtime/rete/single/TransitiveClosureNode.java
@@ -0,0 +1,147 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2012, Tamas Szabo, Gabor Bergmann, Istvan Rath and Daniel Varro
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html.
6 *
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package tools.refinery.viatra.runtime.rete.single;
10
11import tools.refinery.viatra.runtime.base.itc.alg.incscc.IncSCCAlg;
12import tools.refinery.viatra.runtime.base.itc.alg.misc.Tuple;
13import tools.refinery.viatra.runtime.base.itc.graphimpl.Graph;
14import tools.refinery.viatra.runtime.base.itc.igraph.ITcDataSource;
15import tools.refinery.viatra.runtime.base.itc.igraph.ITcObserver;
16import tools.refinery.viatra.runtime.matchers.tuple.Tuples;
17import tools.refinery.viatra.runtime.matchers.util.Clearable;
18import tools.refinery.viatra.runtime.matchers.util.Direction;
19import tools.refinery.viatra.runtime.matchers.util.timeline.Timeline;
20import tools.refinery.viatra.runtime.rete.network.NetworkStructureChangeSensitiveNode;
21import tools.refinery.viatra.runtime.rete.network.ReinitializedNode;
22import tools.refinery.viatra.runtime.rete.network.ReteContainer;
23import tools.refinery.viatra.runtime.rete.network.communication.CommunicationGroup;
24import tools.refinery.viatra.runtime.rete.network.communication.Timestamp;
25
26import java.util.Collection;
27import java.util.Map;
28
29/**
30 * This class represents a transitive closure node in the Rete net.
31 * <p>
32 * This node must not be used in recursive {@link CommunicationGroup}s.
33 *
34 * @author Gabor Bergmann
35 *
36 */
37public class TransitiveClosureNode extends SingleInputNode
38 implements Clearable, ITcObserver<Object>, NetworkStructureChangeSensitiveNode, ReinitializedNode {
39
40 private Graph<Object> graphDataSource;
41 private ITcDataSource<Object> transitiveClosureAlgorithm;
42
43 /**
44 * Create a new transitive closure rete node.
45 *
46 * Client may optionally call {@link #reinitializeWith(Collection)} before using the node, instead of inserting the
47 * initial set of tuples one by one.
48 *
49 * @param reteContainer
50 * the rete container of the node
51 */
52 public TransitiveClosureNode(ReteContainer reteContainer) {
53 super(reteContainer);
54 graphDataSource = new Graph<Object>();
55 transitiveClosureAlgorithm = new IncSCCAlg<Object>(graphDataSource);
56 transitiveClosureAlgorithm.attachObserver(this);
57 reteContainer.registerClearable(this);
58 }
59
60 @Override
61 public void networkStructureChanged() {
62 if (this.reteContainer.isTimelyEvaluation() && this.reteContainer.getCommunicationTracker().isInRecursiveGroup(this)) {
63 throw new IllegalStateException(this.toString() + " cannot be used in recursive differential dataflow evaluation!");
64 }
65 super.networkStructureChanged();
66 }
67
68 /**
69 * Initializes the graph data source with the given collection of tuples.
70 *
71 * @param tuples
72 * the initial collection of tuples
73 */
74 @Override
75 public void reinitializeWith(Collection<tools.refinery.viatra.runtime.matchers.tuple.Tuple> tuples) {
76 clear();
77
78 for (tools.refinery.viatra.runtime.matchers.tuple.Tuple t : tuples) {
79 graphDataSource.insertNode(t.get(0));
80 graphDataSource.insertNode(t.get(1));
81 graphDataSource.insertEdge(t.get(0), t.get(1));
82 }
83 transitiveClosureAlgorithm.attachObserver(this);
84 }
85
86 @Override
87 public void pullInto(final Collection<tools.refinery.viatra.runtime.matchers.tuple.Tuple> collector, final boolean flush) {
88 for (final Tuple<Object> tuple : ((IncSCCAlg<Object>) transitiveClosureAlgorithm).getTcRelation()) {
89 collector.add(Tuples.staticArityFlatTupleOf(tuple.getSource(), tuple.getTarget()));
90 }
91 }
92
93 @Override
94 public void pullIntoWithTimeline(
95 final Map<tools.refinery.viatra.runtime.matchers.tuple.Tuple, Timeline<Timestamp>> collector,
96 final boolean flush) {
97 // use all zero timestamps because this node cannot be used in recursive groups anyway
98 for (final Tuple<Object> tuple : ((IncSCCAlg<Object>) transitiveClosureAlgorithm).getTcRelation()) {
99 collector.put(Tuples.staticArityFlatTupleOf(tuple.getSource(), tuple.getTarget()), Timestamp.INSERT_AT_ZERO_TIMELINE);
100 }
101 }
102
103 @Override
104 public void update(Direction direction, tools.refinery.viatra.runtime.matchers.tuple.Tuple updateElement,
105 Timestamp timestamp) {
106 if (updateElement.getSize() == 2) {
107 Object source = updateElement.get(0);
108 Object target = updateElement.get(1);
109
110 if (direction == Direction.INSERT) {
111 graphDataSource.insertNode(source);
112 graphDataSource.insertNode(target);
113 graphDataSource.insertEdge(source, target);
114 }
115 if (direction == Direction.DELETE) {
116 graphDataSource.deleteEdgeIfExists(source, target);
117
118 if (((IncSCCAlg<Object>) transitiveClosureAlgorithm).isIsolated(source)) {
119 graphDataSource.deleteNode(source);
120 }
121 if (!source.equals(target) && ((IncSCCAlg<Object>) transitiveClosureAlgorithm).isIsolated(target)) {
122 graphDataSource.deleteNode(target);
123 }
124 }
125 }
126 }
127
128 @Override
129 public void clear() {
130 transitiveClosureAlgorithm.dispose();
131 graphDataSource = new Graph<Object>();
132 transitiveClosureAlgorithm = new IncSCCAlg<Object>(graphDataSource);
133 }
134
135 @Override
136 public void tupleInserted(Object source, Object target) {
137 tools.refinery.viatra.runtime.matchers.tuple.Tuple tuple = Tuples.staticArityFlatTupleOf(source, target);
138 propagateUpdate(Direction.INSERT, tuple, Timestamp.ZERO);
139 }
140
141 @Override
142 public void tupleDeleted(Object source, Object target) {
143 tools.refinery.viatra.runtime.matchers.tuple.Tuple tuple = Tuples.staticArityFlatTupleOf(source, target);
144 propagateUpdate(Direction.DELETE, tuple, Timestamp.ZERO);
145 }
146
147}