aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2023-10-15 15:57:52 +0200
committerLibravatar Kristóf Marussy <kristof@marussy.com>2023-10-15 15:57:52 +0200
commitacb5e04319883ceb0dffe25635db5dc22448f247 (patch)
treea58ba07ae482ff1b850d040bb263e38ae0d50876 /subprojects
parentrefactor(interpreter): generify RepresentativeElectionAlgorithm (diff)
downloadrefinery-acb5e04319883ceb0dffe25635db5dc22448f247.tar.gz
refinery-acb5e04319883ceb0dffe25635db5dc22448f247.tar.zst
refinery-acb5e04319883ceb0dffe25635db5dc22448f247.zip
refactor(interpreter): communication tracker algorithm
Use a faster algorithm to detect cycles in the RETE network. Only if cycles are detected fall back to the transitive closure algorithm to construct the SCCs and the reduced graph.
Diffstat (limited to 'subprojects')
-rw-r--r--subprojects/interpreter-rete/src/main/java/tools/refinery/interpreter/rete/network/ReteContainer.java7
-rw-r--r--subprojects/interpreter-rete/src/main/java/tools/refinery/interpreter/rete/network/communication/CommunicationTracker.java46
-rw-r--r--subprojects/interpreter-rete/src/main/java/tools/refinery/interpreter/rete/network/communication/NetworkComponentDetector.java84
-rw-r--r--subprojects/interpreter-rete/src/main/java/tools/refinery/interpreter/rete/network/communication/timeless/TimelessCommunicationTracker.java20
-rw-r--r--subprojects/interpreter-rete/src/main/java/tools/refinery/interpreter/rete/network/communication/timely/TimelyCommunicationTracker.java29
5 files changed, 151 insertions, 35 deletions
diff --git a/subprojects/interpreter-rete/src/main/java/tools/refinery/interpreter/rete/network/ReteContainer.java b/subprojects/interpreter-rete/src/main/java/tools/refinery/interpreter/rete/network/ReteContainer.java
index b5c91d32..3eafc149 100644
--- a/subprojects/interpreter-rete/src/main/java/tools/refinery/interpreter/rete/network/ReteContainer.java
+++ b/subprojects/interpreter-rete/src/main/java/tools/refinery/interpreter/rete/network/ReteContainer.java
@@ -90,15 +90,16 @@ public final class ReteContainer {
90 this.delayedCommandBuffer = new LinkedHashSet<DelayedCommand>(); 90 this.delayedCommandBuffer = new LinkedHashSet<DelayedCommand>();
91 this.executingDelayedCommands = false; 91 this.executingDelayedCommands = false;
92 92
93 this.logger = network.getEngine().getLogger();
94
93 if (this.isTimelyEvaluation()) { 95 if (this.isTimelyEvaluation()) {
94 this.tracker = new TimelyCommunicationTracker(this.getTimelyConfiguration()); 96 this.tracker = new TimelyCommunicationTracker(logger, this.getTimelyConfiguration());
95 } else { 97 } else {
96 this.tracker = new TimelessCommunicationTracker(); 98 this.tracker = new TimelessCommunicationTracker(logger);
97 } 99 }
98 100
99 this.nodesById = CollectionsFactory.createMap(); 101 this.nodesById = CollectionsFactory.createMap();
100 this.clearables = new LinkedList<Clearable>(); 102 this.clearables = new LinkedList<Clearable>();
101 this.logger = network.getEngine().getLogger();
102 103
103 this.connectionFactory = new ConnectionFactory(this); 104 this.connectionFactory = new ConnectionFactory(this);
104 this.nodeProvisioner = new NodeProvisioner(this); 105 this.nodeProvisioner = new NodeProvisioner(this);
diff --git a/subprojects/interpreter-rete/src/main/java/tools/refinery/interpreter/rete/network/communication/CommunicationTracker.java b/subprojects/interpreter-rete/src/main/java/tools/refinery/interpreter/rete/network/communication/CommunicationTracker.java
index 2e8eb338..1d089ba6 100644
--- a/subprojects/interpreter-rete/src/main/java/tools/refinery/interpreter/rete/network/communication/CommunicationTracker.java
+++ b/subprojects/interpreter-rete/src/main/java/tools/refinery/interpreter/rete/network/communication/CommunicationTracker.java
@@ -1,5 +1,6 @@
1/******************************************************************************* 1/*******************************************************************************
2 * Copyright (c) 2010-2017, Tamas Szabo, Istvan Rath and Daniel Varro 2 * Copyright (c) 2010-2017, Tamas Szabo, Istvan Rath and Daniel Varro
3 * Copyright (c) 2023 The Refinery Authors <https://refinery.tools/>
3 * This program and the accompanying materials are made available under the 4 * 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 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html. 6 * http://www.eclipse.org/legal/epl-v20.html.
@@ -8,12 +9,13 @@
8 *******************************************************************************/ 9 *******************************************************************************/
9package tools.refinery.interpreter.rete.network.communication; 10package tools.refinery.interpreter.rete.network.communication;
10 11
12import org.apache.log4j.Logger;
13import org.jetbrains.annotations.Nullable;
11import tools.refinery.interpreter.matchers.tuple.TupleMask; 14import tools.refinery.interpreter.matchers.tuple.TupleMask;
12import tools.refinery.interpreter.rete.aggregation.IAggregatorNode; 15import tools.refinery.interpreter.rete.aggregation.IAggregatorNode;
13import tools.refinery.interpreter.rete.boundary.ExternalInputEnumeratorNode; 16import tools.refinery.interpreter.rete.boundary.ExternalInputEnumeratorNode;
14import tools.refinery.interpreter.rete.eval.RelationEvaluatorNode; 17import tools.refinery.interpreter.rete.eval.RelationEvaluatorNode;
15import tools.refinery.interpreter.rete.index.*; 18import tools.refinery.interpreter.rete.index.*;
16import tools.refinery.interpreter.rete.itc.alg.incscc.IncSCCAlg;
17import tools.refinery.interpreter.rete.itc.alg.misc.topsort.TopologicalSorting; 19import tools.refinery.interpreter.rete.itc.alg.misc.topsort.TopologicalSorting;
18import tools.refinery.interpreter.rete.itc.graphimpl.Graph; 20import tools.refinery.interpreter.rete.itc.graphimpl.Graph;
19import tools.refinery.interpreter.rete.network.*; 21import tools.refinery.interpreter.rete.network.*;
@@ -61,7 +63,7 @@ public abstract class CommunicationTracker {
61 /** 63 /**
62 * Incremental SCC information about the dependency graph 64 * Incremental SCC information about the dependency graph
63 */ 65 */
64 protected final IncSCCAlg<Node> sccInformationProvider; 66 private final NetworkComponentDetector componentDetector;
65 67
66 /** 68 /**
67 * Precomputed node -> communication group map 69 * Precomputed node -> communication group map
@@ -76,9 +78,9 @@ public abstract class CommunicationTracker {
76 // groups should have a simple integer flag which represents its position in a priority queue 78 // groups should have a simple integer flag which represents its position in a priority queue
77 // priority queue only contains the ACTIVE groups 79 // priority queue only contains the ACTIVE groups
78 80
79 public CommunicationTracker() { 81 public CommunicationTracker(Logger logger) {
80 this.dependencyGraph = new Graph<Node>(); 82 this.dependencyGraph = new Graph<Node>();
81 this.sccInformationProvider = new IncSCCAlg<Node>(this.dependencyGraph); 83 this.componentDetector = new NetworkComponentDetector(logger, dependencyGraph);
82 this.groupQueue = new PriorityQueue<CommunicationGroup>(); 84 this.groupQueue = new PriorityQueue<CommunicationGroup>();
83 this.groupMap = new HashMap<Node, CommunicationGroup>(); 85 this.groupMap = new HashMap<Node, CommunicationGroup>();
84 } 86 }
@@ -91,11 +93,33 @@ public abstract class CommunicationTracker {
91 return this.groupMap.get(node); 93 return this.groupMap.get(node);
92 } 94 }
93 95
96 @Nullable
97 protected Set<Node> getPartition(Node node) {
98 return componentDetector.getPartition(node);
99 }
100
101 protected boolean isSingleton(Node node) {
102 var partition = getPartition(node);
103 return partition == null || partition.isEmpty();
104 }
105
106 protected Node getRepresentative(Node node) {
107 return componentDetector.getRepresentative(node);
108 }
109
110 protected boolean hasOutgoingEdges(Node representative) {
111 return componentDetector.hasOutgoingEdges(representative);
112 }
113
114 protected Graph<Node> getReducedGraph() {
115 return componentDetector.getReducedGraph();
116 }
117
94 private void precomputeGroups() { 118 private void precomputeGroups() {
95 groupMap.clear(); 119 groupMap.clear();
96 120
97 // reconstruct group map from dependency graph 121 // reconstruct group map from dependency graph
98 final Graph<Node> reducedGraph = sccInformationProvider.getReducedGraph(); 122 final Graph<Node> reducedGraph = getReducedGraph();
99 final List<Node> representatives = TopologicalSorting.compute(reducedGraph); 123 final List<Node> representatives = TopologicalSorting.compute(reducedGraph);
100 124
101 for (int i = 0; i < representatives.size(); i++) { // groups for SCC representatives 125 for (int i = 0; i < representatives.size(); i++) { // groups for SCC representatives
@@ -107,7 +131,7 @@ public abstract class CommunicationTracker {
107 maxGroupId = representatives.size() - 1; 131 maxGroupId = representatives.size() - 1;
108 132
109 for (final Node node : dependencyGraph.getAllNodes()) { // extend group map to the rest of nodes 133 for (final Node node : dependencyGraph.getAllNodes()) { // extend group map to the rest of nodes
110 final Node representative = sccInformationProvider.getRepresentative(node); 134 final Node representative = getRepresentative(node);
111 final CommunicationGroup group = groupMap.get(representative); 135 final CommunicationGroup group = groupMap.get(representative);
112 if (representative != node) { 136 if (representative != node) {
113 addToGroup(node, group); 137 addToGroup(node, group);
@@ -285,9 +309,9 @@ public abstract class CommunicationTracker {
285 309
286 // query all these information before the actual edge insertion 310 // query all these information before the actual edge insertion
287 // because SCCs may be unified during the process 311 // because SCCs may be unified during the process
288 final Node sourceRepresentative = sccInformationProvider.getRepresentative(source); 312 final Node sourceRepresentative = getRepresentative(source);
289 final Node targetRepresentative = sccInformationProvider.getRepresentative(target); 313 final Node targetRepresentative = getRepresentative(target);
290 final boolean targetHadOutgoingEdges = sccInformationProvider.hasOutgoingEdges(targetRepresentative); 314 final boolean targetHadOutgoingEdges = hasOutgoingEdges(targetRepresentative);
291 315
292 // insert the edge 316 // insert the edge
293 dependencyGraph.insertEdge(source, target); 317 dependencyGraph.insertEdge(source, target);
@@ -372,8 +396,8 @@ public abstract class CommunicationTracker {
372 // delete the edge first, and then query the SCC info provider 396 // delete the edge first, and then query the SCC info provider
373 this.dependencyGraph.deleteEdgeIfExists(source, target); 397 this.dependencyGraph.deleteEdgeIfExists(source, target);
374 398
375 final Node sourceRepresentative = sccInformationProvider.getRepresentative(source); 399 final Node sourceRepresentative = getRepresentative(source);
376 final Node targetRepresentative = sccInformationProvider.getRepresentative(target); 400 final Node targetRepresentative = getRepresentative(target);
377 401
378 // if they are still in the same SCC, 402 // if they are still in the same SCC,
379 // then this deletion did not affect the SCCs, 403 // then this deletion did not affect the SCCs,
diff --git a/subprojects/interpreter-rete/src/main/java/tools/refinery/interpreter/rete/network/communication/NetworkComponentDetector.java b/subprojects/interpreter-rete/src/main/java/tools/refinery/interpreter/rete/network/communication/NetworkComponentDetector.java
new file mode 100644
index 00000000..6ed84e45
--- /dev/null
+++ b/subprojects/interpreter-rete/src/main/java/tools/refinery/interpreter/rete/network/communication/NetworkComponentDetector.java
@@ -0,0 +1,84 @@
1/*
2 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.interpreter.rete.network.communication;
7
8import org.apache.log4j.Logger;
9import org.jetbrains.annotations.Nullable;
10import tools.refinery.interpreter.matchers.util.Direction;
11import tools.refinery.interpreter.rete.itc.alg.incscc.IncSCCAlg;
12import tools.refinery.interpreter.rete.itc.alg.representative.RepresentativeObserver;
13import tools.refinery.interpreter.rete.itc.alg.representative.StronglyConnectedComponentAlgorithm;
14import tools.refinery.interpreter.rete.itc.graphimpl.Graph;
15import tools.refinery.interpreter.rete.network.Node;
16
17import java.util.Set;
18
19public class NetworkComponentDetector implements RepresentativeObserver<Node> {
20 private final Logger logger;
21 private final Graph<Node> dependencyGraph;
22 private StronglyConnectedComponentAlgorithm<Node> stronglyConnectedComponentAlgorithm;
23 private IncSCCAlg<Node> sccInformationProvider;
24
25 public NetworkComponentDetector(Logger logger, Graph<Node> dependencyGraph) {
26 this.logger = logger;
27 this.dependencyGraph = dependencyGraph;
28 stronglyConnectedComponentAlgorithm = new StronglyConnectedComponentAlgorithm<>(dependencyGraph);
29 stronglyConnectedComponentAlgorithm.setObserver(this);
30 if (stronglyConnectedComponentAlgorithm.getComponents()
31 .values()
32 .stream()
33 .anyMatch(component -> component.size() > 1)) {
34 switchToTransitiveClosureAlgorithm();
35 }
36 }
37
38 @Nullable
39 public Set<Node> getPartition(Node node) {
40 if (sccInformationProvider == null) {
41 return null;
42 }
43 return sccInformationProvider.sccs.getPartition(node);
44 }
45
46 public Node getRepresentative(Node node) {
47 if (sccInformationProvider == null) {
48 return node;
49 }
50 return sccInformationProvider.getRepresentative(node);
51 }
52
53 public boolean hasOutgoingEdges(Node representative) {
54 if (sccInformationProvider == null) {
55 return !dependencyGraph.getTargetNodes(representative).isEmpty();
56 }
57 return sccInformationProvider.hasOutgoingEdges(representative);
58 }
59
60 public Graph<Node> getReducedGraph() {
61 if (sccInformationProvider == null) {
62 return dependencyGraph;
63 }
64 return sccInformationProvider.getReducedGraph();
65 }
66
67 @Override
68 public void tupleChanged(Node node, Node representative, Direction direction) {
69 if (direction == Direction.INSERT && !node.equals(representative)) {
70 switchToTransitiveClosureAlgorithm();
71 }
72 }
73
74 private void switchToTransitiveClosureAlgorithm() {
75 logger.warn("RETE network cycle detected, switching to transitive closure algorithm for communication groups");
76 if (stronglyConnectedComponentAlgorithm != null) {
77 stronglyConnectedComponentAlgorithm.dispose();
78 stronglyConnectedComponentAlgorithm = null;
79 }
80 if (sccInformationProvider == null) {
81 sccInformationProvider = new IncSCCAlg<>(dependencyGraph);
82 }
83 }
84}
diff --git a/subprojects/interpreter-rete/src/main/java/tools/refinery/interpreter/rete/network/communication/timeless/TimelessCommunicationTracker.java b/subprojects/interpreter-rete/src/main/java/tools/refinery/interpreter/rete/network/communication/timeless/TimelessCommunicationTracker.java
index 77f40fc3..02116d71 100644
--- a/subprojects/interpreter-rete/src/main/java/tools/refinery/interpreter/rete/network/communication/timeless/TimelessCommunicationTracker.java
+++ b/subprojects/interpreter-rete/src/main/java/tools/refinery/interpreter/rete/network/communication/timeless/TimelessCommunicationTracker.java
@@ -1,5 +1,6 @@
1/******************************************************************************* 1/*******************************************************************************
2 * Copyright (c) 2010-2019, Tamas Szabo, Istvan Rath and Daniel Varro 2 * Copyright (c) 2010-2019, Tamas Szabo, Istvan Rath and Daniel Varro
3 * Copyright (c) 2023 The Refinery Authors <https://refinery.tools/>
3 * This program and the accompanying materials are made available under the 4 * 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 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html. 6 * http://www.eclipse.org/legal/epl-v20.html.
@@ -8,11 +9,7 @@
8 *******************************************************************************/ 9 *******************************************************************************/
9package tools.refinery.interpreter.rete.network.communication.timeless; 10package tools.refinery.interpreter.rete.network.communication.timeless;
10 11
11import java.util.Collection; 12import org.apache.log4j.Logger;
12import java.util.HashSet;
13import java.util.Set;
14import java.util.Map.Entry;
15
16import tools.refinery.interpreter.rete.index.DualInputNode; 13import tools.refinery.interpreter.rete.index.DualInputNode;
17import tools.refinery.interpreter.rete.index.Indexer; 14import tools.refinery.interpreter.rete.index.Indexer;
18import tools.refinery.interpreter.rete.index.IndexerListener; 15import tools.refinery.interpreter.rete.index.IndexerListener;
@@ -26,6 +23,11 @@ import tools.refinery.interpreter.rete.network.communication.MessageSelector;
26import tools.refinery.interpreter.rete.network.mailbox.Mailbox; 23import tools.refinery.interpreter.rete.network.mailbox.Mailbox;
27import tools.refinery.interpreter.rete.network.mailbox.timeless.BehaviorChangingMailbox; 24import tools.refinery.interpreter.rete.network.mailbox.timeless.BehaviorChangingMailbox;
28 25
26import java.util.Collection;
27import java.util.HashSet;
28import java.util.Map.Entry;
29import java.util.Set;
30
29/** 31/**
30 * Timeless implementation of the communication tracker. 32 * Timeless implementation of the communication tracker.
31 * 33 *
@@ -33,10 +35,13 @@ import tools.refinery.interpreter.rete.network.mailbox.timeless.BehaviorChanging
33 * @since 2.2 35 * @since 2.2
34 */ 36 */
35public class TimelessCommunicationTracker extends CommunicationTracker { 37public class TimelessCommunicationTracker extends CommunicationTracker {
38 public TimelessCommunicationTracker(Logger logger) {
39 super(logger);
40 }
36 41
37 @Override 42 @Override
38 protected CommunicationGroup createGroup(Node representative, int index) { 43 protected CommunicationGroup createGroup(Node representative, int index) {
39 final boolean isSingleton = this.sccInformationProvider.sccs.getPartition(representative).size() == 1; 44 final boolean isSingleton = isSingleton(representative);
40 final boolean isReceiver = representative instanceof Receiver; 45 final boolean isReceiver = representative instanceof Receiver;
41 final boolean isPosetIndifferent = isReceiver 46 final boolean isPosetIndifferent = isReceiver
42 && ((Receiver) representative).getMailbox() instanceof BehaviorChangingMailbox; 47 && ((Receiver) representative).getMailbox() instanceof BehaviorChangingMailbox;
@@ -95,14 +100,13 @@ public class TimelessCommunicationTracker extends CommunicationTracker {
95 final Mailbox mailbox = ((Receiver) node).getMailbox(); 100 final Mailbox mailbox = ((Receiver) node).getMailbox();
96 if (mailbox instanceof BehaviorChangingMailbox) { 101 if (mailbox instanceof BehaviorChangingMailbox) {
97 final CommunicationGroup group = this.groupMap.get(node); 102 final CommunicationGroup group = this.groupMap.get(node);
98 final Set<Node> sccNodes = this.sccInformationProvider.sccs.getPartition(node);
99 // a default mailbox must split its messages iff 103 // a default mailbox must split its messages iff
100 // (1) its receiver is in a recursive group and 104 // (1) its receiver is in a recursive group and
101 final boolean c1 = group.isRecursive(); 105 final boolean c1 = group.isRecursive();
102 // (2) its receiver is at the SCC boundary of that group 106 // (2) its receiver is at the SCC boundary of that group
103 final boolean c2 = isAtSCCBoundary(node); 107 final boolean c2 = isAtSCCBoundary(node);
104 // (3) its group consists of more than one node 108 // (3) its group consists of more than one node
105 final boolean c3 = sccNodes.size() > 1; 109 final boolean c3 = isSingleton(node);
106 ((BehaviorChangingMailbox) mailbox).setSplitFlag(c1 && c2 && c3); 110 ((BehaviorChangingMailbox) mailbox).setSplitFlag(c1 && c2 && c3);
107 } 111 }
108 } 112 }
diff --git a/subprojects/interpreter-rete/src/main/java/tools/refinery/interpreter/rete/network/communication/timely/TimelyCommunicationTracker.java b/subprojects/interpreter-rete/src/main/java/tools/refinery/interpreter/rete/network/communication/timely/TimelyCommunicationTracker.java
index a0cdc701..6a92ac91 100644
--- a/subprojects/interpreter-rete/src/main/java/tools/refinery/interpreter/rete/network/communication/timely/TimelyCommunicationTracker.java
+++ b/subprojects/interpreter-rete/src/main/java/tools/refinery/interpreter/rete/network/communication/timely/TimelyCommunicationTracker.java
@@ -1,5 +1,6 @@
1/******************************************************************************* 1/*******************************************************************************
2 * Copyright (c) 2010-2019, Tamas Szabo, Istvan Rath and Daniel Varro 2 * Copyright (c) 2010-2019, Tamas Szabo, Istvan Rath and Daniel Varro
3 * Copyright (c) 2023 The Refinery Authors <https://refinery.tools/>
3 * This program and the accompanying materials are made available under the 4 * 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 * terms of the Eclipse Public License v. 2.0 which is available at
5 * http://www.eclipse.org/legal/epl-v20.html. 6 * http://www.eclipse.org/legal/epl-v20.html.
@@ -8,20 +9,14 @@
8 *******************************************************************************/ 9 *******************************************************************************/
9package tools.refinery.interpreter.rete.network.communication.timely; 10package tools.refinery.interpreter.rete.network.communication.timely;
10 11
11import java.util.Collection; 12import org.apache.log4j.Logger;
12import java.util.List;
13import java.util.Map;
14import java.util.Map.Entry;
15import java.util.Set;
16import java.util.function.Function;
17
18import tools.refinery.interpreter.rete.itc.alg.misc.topsort.TopologicalSorting;
19import tools.refinery.interpreter.rete.itc.graphimpl.Graph;
20import tools.refinery.interpreter.matchers.util.CollectionsFactory; 13import tools.refinery.interpreter.matchers.util.CollectionsFactory;
21import tools.refinery.interpreter.rete.index.IndexerListener; 14import tools.refinery.interpreter.rete.index.IndexerListener;
22import tools.refinery.interpreter.rete.index.SpecializedProjectionIndexer; 15import tools.refinery.interpreter.rete.index.SpecializedProjectionIndexer;
23import tools.refinery.interpreter.rete.index.SpecializedProjectionIndexer.ListenerSubscription; 16import tools.refinery.interpreter.rete.index.SpecializedProjectionIndexer.ListenerSubscription;
24import tools.refinery.interpreter.rete.index.StandardIndexer; 17import tools.refinery.interpreter.rete.index.StandardIndexer;
18import tools.refinery.interpreter.rete.itc.alg.misc.topsort.TopologicalSorting;
19import tools.refinery.interpreter.rete.itc.graphimpl.Graph;
25import tools.refinery.interpreter.rete.matcher.TimelyConfiguration; 20import tools.refinery.interpreter.rete.matcher.TimelyConfiguration;
26import tools.refinery.interpreter.rete.matcher.TimelyConfiguration.TimelineRepresentation; 21import tools.refinery.interpreter.rete.matcher.TimelyConfiguration.TimelineRepresentation;
27import tools.refinery.interpreter.rete.network.NetworkStructureChangeSensitiveNode; 22import tools.refinery.interpreter.rete.network.NetworkStructureChangeSensitiveNode;
@@ -35,6 +30,13 @@ import tools.refinery.interpreter.rete.network.communication.NodeComparator;
35import tools.refinery.interpreter.rete.network.mailbox.Mailbox; 30import tools.refinery.interpreter.rete.network.mailbox.Mailbox;
36import tools.refinery.interpreter.rete.single.DiscriminatorDispatcherNode; 31import tools.refinery.interpreter.rete.single.DiscriminatorDispatcherNode;
37 32
33import java.util.Collection;
34import java.util.List;
35import java.util.Map;
36import java.util.Map.Entry;
37import java.util.Set;
38import java.util.function.Function;
39
38/** 40/**
39 * Timely (DDF) implementation of the {@link CommunicationTracker}. 41 * Timely (DDF) implementation of the {@link CommunicationTracker}.
40 * 42 *
@@ -45,13 +47,14 @@ public class TimelyCommunicationTracker extends CommunicationTracker {
45 47
46 protected final TimelyConfiguration configuration; 48 protected final TimelyConfiguration configuration;
47 49
48 public TimelyCommunicationTracker(final TimelyConfiguration configuration) { 50 public TimelyCommunicationTracker(final Logger logger, final TimelyConfiguration configuration) {
51 super(logger);
49 this.configuration = configuration; 52 this.configuration = configuration;
50 } 53 }
51 54
52 @Override 55 @Override
53 protected CommunicationGroup createGroup(final Node representative, final int index) { 56 protected CommunicationGroup createGroup(final Node representative, final int index) {
54 final boolean isSingleton = this.sccInformationProvider.sccs.getPartition(representative).size() == 1; 57 final boolean isSingleton = isSingleton(representative);
55 return new TimelyCommunicationGroup(this, representative, index, isSingleton); 58 return new TimelyCommunicationGroup(this, representative, index, isSingleton);
56 } 59 }
57 60
@@ -130,8 +133,8 @@ public class TimelyCommunicationTracker extends CommunicationTracker {
130 protected void postProcessGroup(final CommunicationGroup group) { 133 protected void postProcessGroup(final CommunicationGroup group) {
131 if (this.configuration.getTimelineRepresentation() == TimelineRepresentation.FAITHFUL) { 134 if (this.configuration.getTimelineRepresentation() == TimelineRepresentation.FAITHFUL) {
132 final Node representative = group.getRepresentative(); 135 final Node representative = group.getRepresentative();
133 final Set<Node> groupMembers = this.sccInformationProvider.sccs.getPartition(representative); 136 final Set<Node> groupMembers = getPartition(representative);
134 if (groupMembers.size() > 1) { 137 if (groupMembers != null && groupMembers.size() > 1) {
135 final Graph<Node> graph = new Graph<Node>(); 138 final Graph<Node> graph = new Graph<Node>();
136 139
137 for (final Node node : groupMembers) { 140 for (final Node node : groupMembers) {