Adding sypet to repo
[Benchmarks_CSolver.git] / sypet-non-incremental / src / edu / utexas / sypet / synthesis / model / ReachabilityGraphNode.java
diff --git a/sypet-non-incremental/src/edu/utexas/sypet/synthesis/model/ReachabilityGraphNode.java b/sypet-non-incremental/src/edu/utexas/sypet/synthesis/model/ReachabilityGraphNode.java
new file mode 100644 (file)
index 0000000..16723b6
--- /dev/null
@@ -0,0 +1,180 @@
+/*-
+ * APT - Analysis of Petri Nets and labeled Transition systems
+ * Copyright (C) 2012-2013  Members of the project group APT
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+package edu.utexas.sypet.synthesis.model;
+
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+import static java.util.Collections.unmodifiableList;
+import static java.util.Collections.unmodifiableSet;
+
+import uniol.apt.adt.pn.Marking;
+import uniol.apt.adt.pn.Transition;
+
+/**
+ * This class represents a node in a reachability graph. A node is labeled with
+ * a marking which identifies it uniquely and has a firing sequence with which
+ * it can be reached from the initial marking of the underlying Petri net.
+ * Additionally, the postset of the node is available.
+ * 
+ * @author Yu Feng
+ */
+public class ReachabilityGraphNode {
+       private final ReachabilityGraph graph;
+       private final Marking marking;
+       private final List<Transition> firingSequence;
+       private final ReachabilityGraphNode parent;
+       private final ReachabilityGraphNode covered;
+       private Set<ReachabilityGraphEdge> postsetEdges;
+
+       /**
+        * Construct a new coverability graph node.
+        * 
+        * @param graph
+        *            The graph that this node belongs to.
+        * @param transition
+        *            The transition that is fired from this node's parent to reach
+        *            this new node.
+        * @param marking
+        *            The marking that identifies this node.
+        * @param parent
+        *            The parent node of this node.
+        * @param covered
+        *            The node which is covered by this node.
+        */
+       ReachabilityGraphNode(ReachabilityGraph graph, Transition transition, Marking marking, ReachabilityGraphNode parent,
+                       ReachabilityGraphNode covered) {
+               this.graph = graph;
+               this.marking = marking;
+               this.parent = parent;
+               this.covered = covered;
+               List<Transition> sequence = new LinkedList<>();
+               if (parent != null) {
+                       sequence.addAll(parent.firingSequence);
+                       sequence.add(transition);
+               } else {
+                       assert transition == null;
+               }
+               this.firingSequence = unmodifiableList(sequence);
+       }
+
+       /**
+        * Get the parent of this node on the path back to the root of the depth
+        * first search tree.
+        * 
+        * @return the parent or null
+        */
+       ReachabilityGraphNode getParent() {
+               return this.parent;
+       }
+
+       /**
+        * Get the node in the coverability graph that is covered by this node, if
+        * such a node exists.
+        * 
+        * @return the covered node or null
+        * @see getFiringSequenceFromCoveredNode
+        */
+       public ReachabilityGraphNode getCoveredNode() {
+               return this.covered;
+       }
+
+       /**
+        * Get the marking that this node represents.
+        * 
+        * @return The marking.
+        */
+       public Marking getMarking() {
+               return new Marking(this.marking);
+       }
+
+       /**
+        * Get the firing sequence which reaches the marking represented by this
+        * instance from the initial marking of the Petri net.
+        * 
+        * @return The firing sequence.
+        * @see getFiringSequenceFromCoveredNode
+        */
+       public List<Transition> getFiringSequence() {
+               return this.firingSequence;
+       }
+
+       /**
+        * Get the firing sequence which reaches this node from the covered node, or
+        * null. This function can be used together with getFiringSequence to
+        * describe a way to generate tokens in the Petri net. If the return value
+        * is not null, the sequence returned from this function can be fired in an
+        * infinite loop in the marking described by
+        * <code>getCoveredNode.getMarking()</code>, and will increase the number of
+        * token in the Petri net.
+        * 
+        * @return The firing sequence.
+        * @see getCoveredNode
+        * @see getFiringSequence
+        */
+       public List<Transition> getFiringSequenceFromCoveredNode() {
+               if (this.covered == null)
+                       return null;
+               int coveredSequenceLength = this.covered.getFiringSequence().size();
+               return this.firingSequence.subList(coveredSequenceLength, this.firingSequence.size());
+       }
+
+       /**
+        * Get all nodes that are in this node's postset.
+        * 
+        * @return the postset.
+        */
+       public Set<ReachabilityGraphNode> getPostset() {
+               Set<ReachabilityGraphNode> postset = new HashSet<>();
+               for (ReachabilityGraphEdge edge : getPostsetEdges()) {
+                       postset.add(edge.getTarget());
+               }
+               return unmodifiableSet(postset);
+       }
+
+       /**
+        * Get all edges that begin in this node.
+        * 
+        * @return all edges.
+        */
+       public Set<ReachabilityGraphEdge> getPostsetEdges() {
+               if (postsetEdges == null)
+                       postsetEdges = unmodifiableSet(graph.getPostsetEdges(this));
+               return postsetEdges;
+       }
+
+       public Set<ReachabilityGraphEdge> getPostsetEdgesByTgt(ReachabilityGraphNode tgt) {
+               if (postsetEdges == null)
+                       postsetEdges = unmodifiableSet(graph.getPostsetEdges(this));
+
+               Set<ReachabilityGraphEdge> edges = new HashSet<>();
+               for (ReachabilityGraphEdge e : postsetEdges) {
+                       if (e.getTarget().equals(tgt) && !tgt.equals(e.getSource()))
+                               edges.add(e);
+               }
+               return edges;
+       }
+
+       public String toString() {
+               return getMarking().toString();
+       }
+}