1 cananian 1.1a // AbstractGraph.java, created Sun May  4 11:29:53 2003 by cananian
  2 cananian 1.1a // Copyright (C) 2003 C. Scott Ananian <cananian@alumni.princeton.edu>
  3 cananian 1.1a // Licensed under the terms of the GNU GPL; see COPYING for details.
  4 cananian 1.1  package harpoon.Util.Collections;
  5 cananian 1.1a 
  6 cananian 1.2  import net.cscott.jutil.AggregateSetFactory;
  7 cananian 1.2  import net.cscott.jutil.SetFactory;
  8 cananian 1.1a 
  9 cananian 1.1a import java.util.AbstractSet;
 10 cananian 1.1a import java.util.Collection;
 11 cananian 1.1a import java.util.Collections;
 12 cananian 1.1a import java.util.Iterator;
 13 cananian 1.4a import java.util.LinkedHashSet;
 14 cananian 1.1a import java.util.Map;
 15 cananian 1.1a import java.util.Set;
 16 cananian 1.1a 
 17 cananian 1.1a /**
 18 cananian 1.1a  * An <code>AbstractGraph</code> provides a basic implementation
 19 cananian 1.1a  * of the <code>Graph</code> interface.
 20 cananian 1.1a  * 
 21 cananian 1.1a  * @author  C. Scott Ananian <cananian@alumni.princeton.edu>
 22 cananian 1.3   * @version $Id: AbstractGraph.java,v 1.3 2004/02/08 03:21:44 cananian Exp $
 23 cananian 1.1a  */
 24 cananian 1.2  public abstract class AbstractGraph<N extends AbstractGraph.Node<N,E>,E extends Graph.Edge<N,E>> implements MutableGraph<N,E> {
 25 cananian 1.1a     final SetFactory<E> edgeSetFactory = new AggregateSetFactory<E>();
 26 cananian 1.4a     final Set<N> nodes = new LinkedHashSet<N>();
 27 cananian 1.4a     final Set<N> nodesRO = Collections.unmodifiableSet(nodes);
 28 cananian 1.4a     public Set<N> nodes() { return nodesRO; }
 29 cananian 1.4a 
 30 cananian 1.1a     public void summarize(Collection<N> nodesToRemove) {
 31 cananian 1.1a         for (Iterator<N> it=nodesToRemove.iterator(); it.hasNext(); )
 32 cananian 1.1a             summarize(it.next());
 33 cananian 1.1a     }
 34 cananian 1.1a     public void summarize(N nodeToRemove) {
 35 cananian 1.1a         if (!nodes.contains(nodeToRemove)) return; // done already!
 36 cananian 1.1a         // remove self-loops.
 37 cananian 1.3          for (E edge : nodeToRemove.predC()) {
 38 cananian 1.1a             assert edge.to()==nodeToRemove;
 39 cananian 1.1a             if (edge.from()==nodeToRemove)
 40 cananian 1.1a                 removeEdge(edge);
 41 cananian 1.1a         }
 42 cananian 1.1a         // A->n->B becomes A->B
 43 cananian 1.4a         for (Iterator<E> it=nodeToRemove.predC().iterator(); it.hasNext(); ) {
 44 cananian 1.1a             N pred = it.next().from();
 45 cananian 1.1a             assert pred!=nodeToRemove;
 46 cananian 1.1a             // extend this edge to all successors.
 47 cananian 1.4a             for (Iterator<E> it2=nodeToRemove.succC().iterator();
 48 cananian 1.1a                  it2.hasNext(); ) {
 49 cananian 1.1a                 N succ = it2.next().to();
 50 cananian 1.1a                 assert succ!=nodeToRemove;
 51 cananian 1.1a                 addEdge(pred, succ);
 52 cananian 1.1a             }
 53 cananian 1.1a         }
 54 cananian 1.1a         // remove original edges
 55 cananian 1.4a         for (Iterator<E> it=nodeToRemove.predC().iterator(); it.hasNext(); )
 56 cananian 1.1a             removeEdge(it.next());
 57 cananian 1.4a         for (Iterator<E> it=nodeToRemove.succC().iterator(); it.hasNext(); )
 58 cananian 1.1a             removeEdge(it.next());
 59 cananian 1.1a         // finally, remove the node.
 60 cananian 1.4a         boolean changed = nodes.remove(nodeToRemove);
 61 cananian 1.4a         assert changed;
 62 cananian 1.1a         assert !nodes.contains(nodeToRemove);
 63 cananian 1.4a         assert nodeToRemove.predC().size()==0;
 64 cananian 1.4a         assert nodeToRemove.succC().size()==0;
 65 cananian 1.1a     }
 66 cananian 1.1a     public abstract E addEdge(N from, N to);
 67 cananian 1.1a 
 68 cananian 1.4a     public void addNode(N n) {
 69 cananian 1.4a         assert !nodes.contains(n);
 70 cananian 1.4a         nodes.add(n);
 71 cananian 1.1a     }
 72 cananian 1.1a     protected void addEdge(E e) {
 73 cananian 1.1a         e.from().succ.add(e);
 74 cananian 1.1a         e.to().pred.add(e);
 75 cananian 1.1a     }
 76 cananian 1.1a     public void removeEdge(E e) {
 77 cananian 1.1a         e.from().succ.remove(e);
 78 cananian 1.1a         e.to().pred.remove(e);
 79 cananian 1.1a     }
 80 cananian 1.1a 
 81 cananian 1.1a     protected AbstractGraph() { }
 82 cananian 1.1a 
 83 cananian 1.3a     /** 
 84 cananian 1.3a      * <code>AbstractGraph.Node</code> provides a basic implementation of
 85 cananian 1.3a      * the <code>Graph.Node</code> interface.
 86 cananian 1.3a      *
 87 cananian 1.3a      * @author  C. Scott Ananian <cananian@alumni.princeton.edu>
 88 cananian 1.3       * @version $Id: AbstractGraph.java,v 1.3 2004/02/08 03:21:44 cananian Exp $
 89 cananian 1.3a      */
 90 cananian 1.4a     public static class Node<N extends Node<N,E>,E extends Graph.Edge<N,E>> implements Graph.Node<N,E> {
 91 cananian 1.1a         final Set<E> pred, succ, predRO, succRO;
 92 cananian 1.4a         public Node(AbstractGraph<N,E> parent) {
 93 cananian 1.1a             this.pred = parent.edgeSetFactory.makeSet();
 94 cananian 1.1a             this.succ = parent.edgeSetFactory.makeSet();
 95 cananian 1.1a             this.predRO = Collections.unmodifiableSet(this.pred);
 96 cananian 1.1a             this.succRO = Collections.unmodifiableSet(this.succ);
 97 cananian 1.1a         }
 98 cananian 1.4a         public Set<E> predC() { return predRO; }
 99 cananian 1.4a         public Set<E> succC() { return succRO; }
100 cananian 1.1a         public boolean isSucc(N n) {
101 cananian 1.1a             for (Iterator<E> it=succ.iterator(); it.hasNext(); )
102 cananian 1.1a                 if (it.next().to().equals(n)) return true;
103 cananian 1.1a             return false;
104 cananian 1.1a         }
105 cananian 1.1a         public boolean isPred(N n) {
106 cananian 1.1a             for (Iterator<E> it=pred.iterator(); it.hasNext(); )
107 cananian 1.1a                 if (it.next().from().equals(n)) return true;
108 cananian 1.1a             return false;
109 cananian 1.1a         }
110 cananian 1.1a     }
111 cananian 1.3a     /**
112 cananian 1.3a      * <code>AbstractGraph.Edge</code> provides a basic implementation of
113 cananian 1.3a      * the <code>Graph.Edge</code> interface.  This is a simple pair
114 cananian 1.3a      * of "from" and "to" nodes; you don't have to extend this
115 cananian 1.3a      * class when implementing <code>AbstractGraph</code> if you
116 cananian 1.3a      * prefer to use your own <code>Graph.Edge</code> implementation.
117 cananian 1.3a      *
118 cananian 1.3a      * @author  C. Scott Ananian <cananian@alumni.princeton.edu>
119 cananian 1.3       * @version $Id: AbstractGraph.java,v 1.3 2004/02/08 03:21:44 cananian Exp $
120 cananian 1.3a      */
121 cananian 1.4a     public static class Edge<N extends Node<N,E>,E extends Edge<N,E>> implements Graph.Edge<N,E> {
122 cananian 1.1a         final N from;
123 cananian 1.1a         final N to;
124 cananian 1.1a         public Edge(N from, N to) { this.from=from; this.to=to; }
125 cananian 1.1a         public N from() { return from; }
126 cananian 1.1a         public N to() { return to; }
127 cananian 1.1a     }
128 cananian 1.1a }