From 96e38f59a182be77f5986ac28e79003848e54ec7 Mon Sep 17 00:00:00 2001 From: eal Date: Sun, 3 Jul 2022 12:47:29 -0700 Subject: [PATCH] Do not include in cycles downstream reactions --- .../generator/ReactionInstanceGraph.java | 4 +-- .../org/lflang/generator/ReactorInstance.java | 36 +++++++++++-------- 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/org.lflang/src/org/lflang/generator/ReactionInstanceGraph.java b/org.lflang/src/org/lflang/generator/ReactionInstanceGraph.java index 4b76c29ff8..72c20bb63a 100644 --- a/org.lflang/src/org/lflang/generator/ReactionInstanceGraph.java +++ b/org.lflang/src/org/lflang/generator/ReactionInstanceGraph.java @@ -32,7 +32,7 @@ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY import java.util.Set; import org.lflang.generator.ReactionInstance.Runtime; -import org.lflang.graph.DirectedGraph; +import org.lflang.graph.PrecedenceGraph; import org.lflang.lf.Variable; /** @@ -54,7 +54,7 @@ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * @author{Marten Lohstroh } * @author{Edward A. Lee } */ -public class ReactionInstanceGraph extends DirectedGraph { +public class ReactionInstanceGraph extends PrecedenceGraph { /** * Create a new graph by traversing the maps in the named instances diff --git a/org.lflang/src/org/lflang/generator/ReactorInstance.java b/org.lflang/src/org/lflang/generator/ReactorInstance.java index c7d169ab23..32a4e40426 100644 --- a/org.lflang/src/org/lflang/generator/ReactorInstance.java +++ b/org.lflang/src/org/lflang/generator/ReactorInstance.java @@ -244,26 +244,34 @@ public void clearCaches(boolean includingRuntimes) { public Set> getCycles() { if (depth != 0) return root().getCycles(); if (cachedCycles != null) return cachedCycles; - Set reactions = new LinkedHashSet<>(); + cachedCycles = new LinkedHashSet<>(); ReactionInstanceGraph reactionRuntimes = assignLevels(); - for (ReactionInstance.Runtime runtime : reactionRuntimes.nodes()) { - reactions.add(runtime.getReaction()); - } - Set ports = new LinkedHashSet<>(); - // Need to figure out which ports are involved in the cycles. - // It may not be all ports that depend on this reaction. - for (ReactionInstance r : reactions) { - for (TriggerInstance p : r.effects) { - if (p instanceof PortInstance) { - findPaths((PortInstance)p, reactions, ports); + if (reactionRuntimes.nodes().size() > 0) { + Set reactions = new LinkedHashSet<>(); + Set ports = new LinkedHashSet<>(); + // There are cycles. But the nodes set includes not + // just the cycles, but also nodes that are downstream of the + // cycles. Use Tarjan's algorithm to get just the cycles. + var cycleNodes = reactionRuntimes.getCycles(); + for (var cycle : cycleNodes) { + for (ReactionInstance.Runtime runtime : cycle) { + reactions.add(runtime.getReaction()); + } + } + // Need to figure out which ports are involved in the cycles. + // It may not be all ports that depend on this reaction. + for (ReactionInstance r : reactions) { + for (TriggerInstance p : r.effects) { + if (p instanceof PortInstance) { + findPaths((PortInstance)p, reactions, ports); + } } } + cachedCycles.addAll(reactions); + cachedCycles.addAll(ports); } - cachedCycles = new LinkedHashSet<>(); - cachedCycles.addAll(reactions); - cachedCycles.addAll(ports); return cachedCycles; }