This package includes basic recursive data structures make up of intermediate representation (IR) nodes: trees and graphs. The classes differ in whether edges are represented explicitly as nodes themselves, whether edges can be traversed in either direction, whether each node has a unique parent and whether nodes have operators which determine the number of children. The name may include the following terms:

Edge
Edges are explicitly represented with IR nodes. In this case it is possible to define attributes on edges.
Symmetric
Edges can be traversed in either direction. Otherwise the structure can only be traversed in the direction of the edges.
Tree
Each node has at most one parent (always symmetric as well)
Syntax
Each node has an operator.
Not all combinations are implemented.

The classes provide methods to add new nodes to the data structure and to attach these nodes in particular places. When a node is added to a structure, the number of children is specified. For a graph, the children of a node are the nodes that can be reached by following one directed edge. The parents are those nodes for which this node is a child. The number of parents is also specified when the node is added to the data structure. In some cases, the number of children or parents may be specified by the client with an integer parameter, num:

num < 0
the number is varying, starting with the one's complement (~num) elements (-1 means none, -2 means one etc).
num = 0
none are permitted.
num > 0
a fixed number are permitted. At the beginning each is undefined, requesting it raises the {@link fluid.ir.SlotUndefinedException} exception.
In other cases, the number is determined in a different way. For example, trees have only one place for a parent, and syntax trees get the number of children from the operator. Trees and graphs may be immutable, mutable or versioned; the constructor takes a {@link fluid.ir.SlotFactory} that specifies what kind of slots to use.

This package provides interfaces as well as classes. The interfaces should be used by clients that only need to traverse and not add or modify structure. Here is a list of classes and the corresponding interfaces:

{@link fluid.tree.Digraph}
{@link fluid.tree.DigraphInterface}
{@link fluid.tree.EdgeDigraph}
{@link fluid.tree.EdgeDigraphInterface}
{@link fluid.tree.SymmetricDigraph}
{@link fluid.tree.SymmetricDigraphInterface}
{@link fluid.tree.SymmetricEdgeDigraph}
{@link fluid.tree.SymmetricEdgeDigraphInterface}
{@link fluid.tree.Tree}
{@link fluid.tree.TreeInterface}
Additionally there is an interface {@link fluid.tree.GraphLabel} for classes where each node has a label. The class {@link fluid.tree.SyntaxTree} implements this interface.

The nodes of a structure can be enumerated in at least two ways using classes in this package

{@link fluid.tree.DepthFirstSearch}
Starting from a particular node, this node is returned and then the children are traversed. If a node has already been traversed it is skipped, thus ensuring termination.
{@link fluid.tree.ConnectedNodes}
(for symmetric structures only) Starting from a particular node, return it and then all nodes connected to it recursively. Again, if a node has already been visited, it is skipped.
There is currently no way to enumerate all the nodes entered into a structure. This capability would be incompatible with garbage collecting unconnected nodes.

These classes can be listened to using the method Digraph#addDigraphListener. There are a large variety of different events below {@link fluid.tree.DigraphEvent} that can be generated:

{@link fluid.tree.NodeEvent}
Events about nodes.
{@link fluid.tree.NewNodeEvent}
a node is added to graph
{@link fluid.tree.ChildEvent}
children changed:
{@link fluid.tree.NewChildEvent}
a new child is added
{@link fluid.tree.RemoveChildEvent}
a child is removed
{@link fluid.tree.ChangedChildEvent}
a child is changed from one node to another
{@link fluid.tree.ParentEvent}
parents changed:
{@link fluid.tree.NewParentEvent}
a new parent is added
{@link fluid.tree.RemoveParentEvent}
a parent is removed
{@link fluid.tree.ChangedParentEvent}
a parent is changed from one node to another (Currently, this event is not generated).
{@link fluid.tree.NodeEdgeEvent}
a node's (reified) incoming or outgoing edges change:
{@link fluid.tree.ChildEdgeEvent}
outgoing edges changed:
{@link fluid.tree.NewChildEdgeEvent}
a new outgoing edge is added
{@link fluid.tree.RemoveChildEdgeEvent}
an outgoing edge is removed
{@link fluid.tree.ChangedChildEdgeEvent}
an outgoing edge is changed from one edge to another
{@link fluid.tree.ParentEvent}
incoming edges changed:
{@link fluid.tree.NewParentEdgeEvent}
a new incoming edge is added
{@link fluid.tree.RemoveParentEdgeEvent}
an incoming edge is removed
{@link fluid.tree.ChangedParentEdgeEvent}
an incoming edge is changed from one edge to another (Currently, this event is not generated).
{@link fluid.tree.RemoveChildrenEvent}
all children of the node are removed.
{@link fluid.tree.RemoveParentsEvent}
all parents of the node are removed.
{@link fluid.tree.EdgeEvent}
Events about (reified) edges:
{@link fluid.tree.NewEdgeEvent}
A new edge is added to the graph.
{@link fluid.tree.EdgeNodeEvent}
An edge gets a new source or sink:
{@link fluid.tree.SourceEvent}
events about changing sources:
{@link fluid.tree.NewSourceEvent}
the source is defined
{@link fluid.tree.ChangedSourceEvent}
a source is changed from one node to another (Currently, this event is not generated).
{@link fluid.tree.SinkEvent}
events about changing sinks:
{@link fluid.tree.NewSinkEvent}
the sink is defined
{@link fluid.tree.ChangedSinkEvent}
a sink is changed from one node to another

The classes provide a way to create delegating versions of themselves. Each class can be asked to express itself in the form of derived attributes, and each class has a constructor which takes attributes to which to delegate graph methods. In other words, one can create (say) a directed graph, get this graph in the form of a ``children'' attribute and then create a directed graph which implements methods by acting upon the attributes you give it. In this way one gets a copy of the previous graph. It is interesting because one may use wrappers around the attributes that are being used to express the graph methods. The fit isn't complete; they are some operations that cannot be expressed as slot accesses; these are indicated in the known bugs section of each class.