aboutsummaryrefslogtreecommitdiffstats
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
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.
-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) {