--- /dev/null
+.\" Automatically generated by Pod::Man 2.22 (Pod::Simple 3.10)
+.\"
+.\" Standard preamble:
+.\" ========================================================================
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Vb \" Begin verbatim text
+.ft CW
+.nf
+.ne \\$1
+..
+.de Ve \" End verbatim text
+.ft R
+.fi
+..
+.\" Set up some character translations and predefined strings. \*(-- will
+.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
+.\" double quote, and \*(R" will give a right double quote. \*(C+ will
+.\" give a nicer C++. Capital omega is used to do unbreakable dashes and
+.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
+.\" nothing in troff, for use with C<>.
+.tr \(*W-
+.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
+.ie n \{\
+. ds -- \(*W-
+. ds PI pi
+. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
+. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
+. ds L" ""
+. ds R" ""
+. ds C` ""
+. ds C' ""
+'br\}
+.el\{\
+. ds -- \|\(em\|
+. ds PI \(*p
+. ds L" ``
+. ds R" ''
+'br\}
+.\"
+.\" Escape single quotes in literal strings from groff's Unicode transform.
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\"
+.\" If the F register is turned on, we'll generate index entries on stderr for
+.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
+.\" entries marked with X<> in POD. Of course, you'll have to process the
+.\" output yourself in some meaningful fashion.
+.ie \nF \{\
+. de IX
+. tm Index:\\$1\t\\n%\t"\\$2"
+..
+. nr % 0
+. rr F
+.\}
+.el \{\
+. de IX
+..
+.\}
+.\"
+.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
+.\" Fear. Run. Save yourself. No user-serviceable parts.
+. \" fudge factors for nroff and troff
+.if n \{\
+. ds #H 0
+. ds #V .8m
+. ds #F .3m
+. ds #[ \f1
+. ds #] \fP
+.\}
+.if t \{\
+. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
+. ds #V .6m
+. ds #F 0
+. ds #[ \&
+. ds #] \&
+.\}
+. \" simple accents for nroff and troff
+.if n \{\
+. ds ' \&
+. ds ` \&
+. ds ^ \&
+. ds , \&
+. ds ~ ~
+. ds /
+.\}
+.if t \{\
+. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
+. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
+. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
+. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
+. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
+. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
+.\}
+. \" troff and (daisy-wheel) nroff accents
+.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
+.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
+.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
+.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
+.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
+.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
+.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
+.ds ae a\h'-(\w'a'u*4/10)'e
+.ds Ae A\h'-(\w'A'u*4/10)'E
+. \" corrections for vroff
+.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
+.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
+. \" for low resolution devices (crt and lpr)
+.if \n(.H>23 .if \n(.V>19 \
+\{\
+. ds : e
+. ds 8 ss
+. ds o a
+. ds d- d\h'-1'\(ga
+. ds D- D\h'-1'\(hy
+. ds th \o'bp'
+. ds Th \o'LP'
+. ds ae ae
+. ds Ae AE
+.\}
+.rm #[ #] #H #V #F C
+.\" ========================================================================
+.\"
+.IX Title "Tree::DAG_Node 3"
+.TH Tree::DAG_Node 3 "2007-12-09" "perl v5.8.7" "User Contributed Perl Documentation"
+.\" For nroff, turn off justification. Always turn off hyphenation; it makes
+.\" way too many mistakes in technical documents.
+.if n .ad l
+.nh
+.SH "NAME"
+Tree::DAG_Node \- (super)class for representing nodes in a tree
+.SH "SYNOPSIS"
+.IX Header "SYNOPSIS"
+Using as a base class:
+.PP
+.Vb 5
+\& package Game::Tree::Node; # or whatever you\*(Aqre doing
+\& use Tree::DAG_Node;
+\& @ISA = qw(Tree::DAG_Node);
+\& ...your own methods overriding/extending
+\& the methods in Tree::DAG_Node...
+.Ve
+.PP
+Using as a class of its own:
+.PP
+.Vb 6
+\& use Tree::DAG_Node;
+\& my $root = Tree::DAG_Node\->new();
+\& $root\->name("I\*(Aqm the tops");
+\& my $new_daughter = $root\->new_daughter;
+\& $new_daughter\->name("More");
+\& ...
+.Ve
+.SH "DESCRIPTION"
+.IX Header "DESCRIPTION"
+This class encapsulates/makes/manipulates objects that represent nodes
+in a tree structure. The tree structure is not an object itself, but
+is emergent from the linkages you create between nodes. This class
+provides the methods for making linkages that can be used to build up
+a tree, while preventing you from ever making any kinds of linkages
+which are not allowed in a tree (such as having a node be its own
+mother or ancestor, or having a node have two mothers).
+.PP
+This is what I mean by a \*(L"tree structure\*(R", a bit redundantly stated:
+.PP
+* A tree is a special case of an acyclic directed graph.
+.PP
+* A tree is a network of nodes where there's exactly one root
+node (i.e., 'the top'), and the only primary relationship between nodes
+is the mother-daugher relationship.
+.PP
+* No node can be its own mother, or its mother's mother, etc.
+.PP
+* Each node in the tree has exactly one \*(L"parent\*(R" (node in the \*(L"up\*(R"
+direction) \*(-- except the root, which is parentless.
+.PP
+* Each node can have any number (0 to any finite number) of daughter
+nodes. A given node's daughter nodes constitute an \fIordered\fR list.
+(However, you are free to consider this ordering irrelevant.
+Some applications do need daughters to be ordered, so I chose to
+consider this the general case.)
+.PP
+* A node can appear in only one tree, and only once in that tree.
+Notably (notable because it doesn't follow from the two above points),
+a node cannot appear twice in its mother's daughter list.
+.PP
+* In other words, there's an idea of up (toward the root) versus
+down (away from the root), and left (i.e., toward the start (index 0)
+of a given node's daughter list) versus right (toward the end of a
+given node's daughter list).
+.PP
+Trees as described above have various applications, among them:
+representing syntactic constituency, in formal linguistics;
+representing contingencies in a game tree; representing abstract
+syntax in the parsing of any computer language \*(-- whether in
+expression trees for programming languages, or constituency in the
+parse of a markup language document. (Some of these might not use the
+fact that daughters are ordered.)
+.PP
+(Note: B\-Trees are a very special case of the above kinds of trees,
+and are best treated with their own class. Check \s-1CPAN\s0 for modules
+encapsulating B\-Trees; or if you actually want a database, and for
+some reason ended up looking here, go look at AnyDBM_File.)
+.PP
+Many base classes are not usable except as such \*(-- but Tree::DAG_Node
+can be used as a normal class. You can go ahead and say:
+.PP
+.Vb 6
+\& use Tree::DAG_Node;
+\& my $root = Tree::DAG_Node\->new();
+\& $root\->name("I\*(Aqm the tops");
+\& $new_daughter = Tree::DAG_Node\->new();
+\& $new_daughter\->name("More");
+\& $root\->add_daughter($new_daughter);
+.Ve
+.PP
+and so on, constructing and linking objects from Tree::DAG_Node and
+making useful tree structures out of them.
+.SH "A NOTE TO THE READER"
+.IX Header "A NOTE TO THE READER"
+This class is big and provides lots of methods. If your problem is
+simple (say, just representing a simple parse tree), this class might
+seem like using an atomic sledgehammer to swat a fly. But the
+complexity of this module's bells and whistles shouldn't detract from
+the efficiency of using this class for a simple purpose. In fact, I'd
+be very surprised if any one user ever had use for more that even a
+third of the methods in this class. And remember: an atomic
+sledgehammer \fBwill\fR kill that fly.
+.SH "OBJECT CONTENTS"
+.IX Header "OBJECT CONTENTS"
+Implementationally, each node in a tree is an object, in the sense of
+being an arbitrarily complex data structure that belongs to a class
+(presumably Tree::DAG_Node, or ones derived from it) that provides
+methods.
+.PP
+The attributes of a node-object are:
+.IP "mother \*(-- this node's mother. undef if this is a root." 4
+.IX Item "mother this node's mother. undef if this is a root."
+.PD 0
+.IP "daughters \*(-- the (possibly empty) list of daughters of this node." 4
+.IX Item "daughters the (possibly empty) list of daughters of this node."
+.IP "name \*(-- the name for this node." 4
+.IX Item "name the name for this node."
+.PD
+Need not be unique, or even printable. This is printed in some of the
+various dumper methods, but it's up to you if you don't put anything
+meaningful or printable here.
+.IP "attributes \*(-- whatever the user wants to use it for." 4
+.IX Item "attributes whatever the user wants to use it for."
+Presumably a hashref to whatever other attributes the user wants to
+store without risk of colliding with the object's real attributes.
+(Example usage: attributes to an \s-1SGML\s0 tag \*(-- you definitely wouldn't
+want the existence of a \*(L"mother=foo\*(R" pair in such a tag to collide with
+a node object's 'mother' attribute.)
+.Sp
+Aside from (by default) initializing it to {}, and having the access
+method called \*(L"attributes\*(R" (described a ways below), I don't do
+anything with the \*(L"attributes\*(R" in this module. I basically intended
+this so that users who don't want/need to bother deriving a class
+from Tree::DAG_Node, could still attach whatever data they wanted in a
+node.
+.PP
+\&\*(L"mother\*(R" and \*(L"daughters\*(R" are attributes that relate to linkage \*(-- they
+are never written to directly, but are changed as appropriate by the
+\&\*(L"linkage methods\*(R", discussed below.
+.PP
+The other two (and whatever others you may add in derived classes) are
+simply accessed thru the same-named methods, discussed further below.
+.SS "\s-1ABOUT\s0 \s-1THE\s0 \s-1DOCUMENTED\s0 \s-1INTERFACE\s0"
+.IX Subsection "ABOUT THE DOCUMENTED INTERFACE"
+Stick to the documented interface (and comments in the source \*(--
+especially ones saying \*(L"undocumented!\*(R" and/or \*(L"disfavored!\*(R" \*(-- do not
+count as documentation!), and don't rely on any behavior that's not in
+the documented interface.
+.PP
+Specifically, unless the documentation for a particular method says
+\&\*(L"this method returns thus-and-such a value\*(R", then you should not rely on
+it returning anything meaningful.
+.PP
+A \fIpassing\fR acquintance with at least the broader details of the source
+code for this class is assumed for anyone using this class as a base
+class \*(-- especially if you're overriding existing methods, and
+\&\fBdefinitely\fR if you're overriding linkage methods.
+.SH "MAIN CONSTRUCTOR, AND INITIALIZER"
+.IX Header "MAIN CONSTRUCTOR, AND INITIALIZER"
+.IP "the constructor \s-1CLASS\-\s0>\fInew()\fR or \s-1CLASS\-\s0>new({...options...})" 4
+.IX Item "the constructor CLASS->new() or CLASS->new({...options...})"
+This creates a new node object, calls \f(CW$object\fR\->_init({...options...})
+to provide it sane defaults (like: undef name, undef mother, no
+daughters, 'attributes' setting of a new empty hashref), and returns
+the object created. (If you just said \*(L"\s-1CLASS\-\s0>\fInew()\fR\*(R" or \*(L"\s-1CLASS\-\s0>new\*(R",
+then it pretends you called \*(L"\s-1CLASS\-\s0>new({})\*(R".)
+.Sp
+Currently no options for putting in {...options...} are part
+of the documented interface, but the options is here in case
+you want to add such behavior in a derived class.
+.Sp
+Read on if you plan on using Tree::DAG_New as a base class.
+(Otherwise feel free to skip to the description of _init.)
+.Sp
+There are, in my mind, two ways to do object construction:
+.Sp
+Way 1: create an object, knowing that it'll have certain uninteresting
+sane default values, and then call methods to change those values to
+what you want. Example:
+.Sp
+.Vb 4
+\& $node = Tree::DAG_Node\->new;
+\& $node\->name(\*(AqSupahnode!\*(Aq);
+\& $root\->add_daughter($node);
+\& $node\->add_daughters(@some_others)
+.Ve
+.Sp
+Way 2: be able to specify some/most/all the object's attributes in
+the call to the constructor. Something like:
+.Sp
+.Vb 5
+\& $node = Tree::DAG_Node\->new({
+\& name => \*(AqSupahnode!\*(Aq,
+\& mother => $root,
+\& daughters => \e@some_others
+\& });
+.Ve
+.Sp
+After some deliberation, I've decided that the second way is a Bad
+Thing. First off, it is \fBnot\fR markedly more concise than the first
+way. Second off, it often requires subtly different syntax (e.g.,
+\&\e@some_others vs \f(CW@some_others\fR). It just complicates things for the
+programmer and the user, without making either appreciably happier.
+.Sp
+(This is not to say that options in general for a constructor are bad
+\&\*(-- \f(CW\*(C`random_network\*(C'\fR, discussed far below, necessarily takes options.
+But note that those are not options for the default values of
+attributes.)
+.Sp
+Anyway, if you use Tree::DAG_Node as a superclass, and you add
+attributes that need to be initialized, what you need to do is provide
+an _init method that calls \f(CW$this\fR\->SUPER::_init($options) to use its
+superclass's _init method, and then initializes the new attributes:
+.Sp
+.Vb 4
+\& sub _init {
+\& my($this, $options) = @_[0,1];
+\& $this\->SUPER::_init($options); # call my superclass\*(Aqs _init to
+\& # init all the attributes I\*(Aqm inheriting
+\&
+\& # Now init /my/ new attributes:
+\& $this\->{\*(Aqamigos\*(Aq} = []; # for example
+\& }
+.Ve
+.Sp
+\&...or, as I prefer when I'm being a neat freak:
+.Sp
+.Vb 3
+\& sub _init {
+\& my($this, $options) = @_[0,1];
+\& $this\->SUPER::_init($options);
+\&
+\& $this\->_init_amigos($options);
+\& }
+\&
+\& sub _init_amigos {
+\& my $this = $_[0];
+\& # Or my($this,$options) = @_[0,1]; if I\*(Aqm using $options
+\& $this\->{\*(Aqamigos\*(Aq} = [];
+\& }
+.Ve
+.Sp
+In other words, I like to have each attribute initialized thru a
+method named _init_[attribute], which should expect the object as
+\&\f(CW$_\fR[0] and the the options hashref (or {} if none was given) as \f(CW$_\fR[1].
+If you insist on having your _init recognize options for setting
+attributes, you might as well have them dealt with by the appropriate
+_init_[attribute] method, like this:
+.Sp
+.Vb 3
+\& sub _init {
+\& my($this, $options) = @_[0,1];
+\& $this\->SUPER::_init($options);
+\&
+\& $this\->_init_amigos($options);
+\& }
+\&
+\& sub _init_amigos {
+\& my($this,$options) = @_[0,1]; # I need options this time
+\& $this\->{\*(Aqamigos\*(Aq} = [];
+\& $this\->amigos(@{$options\->{\*(Aqamigos\*(Aq}}) if $options\->{\*(Aqamigos\*(Aq};
+\& }
+.Ve
+.Sp
+All this bookkeeping looks silly with just one new attribute in a
+class derived straight from Tree::DAG_Node, but if there's lots of new
+attributes running around, and if you're deriving from a class derived
+from a class derived from Tree::DAG_Node, then tidy
+stratification/modularization like this can keep you sane.
+.ie n .IP "the constructor $obj\->\fInew()\fR or $obj\->new({...options...})" 4
+.el .IP "the constructor \f(CW$obj\fR\->\fInew()\fR or \f(CW$obj\fR\->new({...options...})" 4
+.IX Item "the constructor $obj->new() or $obj->new({...options...})"
+Just another way to get at the \f(CW\*(C`new\*(C'\fR method. This \fBdoes not copy\fR
+\&\f(CW$obj\fR, but merely constructs a new object of the same class as it.
+Saves you the bother of going \f(CW$class\fR = ref \f(CW$obj\fR; \f(CW$obj2\fR = \f(CW$class\fR\->new;
+.ie n .IP "the method $node\->_init({...options...})" 4
+.el .IP "the method \f(CW$node\fR\->_init({...options...})" 4
+.IX Item "the method $node->_init({...options...})"
+Initialize the object's attribute values. See the discussion above.
+Presumably this should be called only by the guts of the \f(CW\*(C`new\*(C'\fR
+constructor \*(-- never by the end user.
+.Sp
+Currently there are no documented options for putting in
+{...options...}, but (in case you want to disregard the above rant)
+the option exists for you to use {...options...} for something useful
+in a derived class.
+.Sp
+Please see the source for more information.
+.ie n .IP "see also (below) the constructors ""new_daughter"" and ""new_daughter_left""" 4
+.el .IP "see also (below) the constructors ``new_daughter'' and ``new_daughter_left''" 4
+.IX Item "see also (below) the constructors new_daughter and new_daughter_left"
+.SH "LINKAGE-RELATED METHODS"
+.IX Header "LINKAGE-RELATED METHODS"
+.PD 0
+.ie n .IP "$node\->daughters" 4
+.el .IP "\f(CW$node\fR\->daughters" 4
+.IX Item "$node->daughters"
+.PD
+This returns the (possibly empty) list of daughters for \f(CW$node\fR.
+.ie n .IP "$node\->mother" 4
+.el .IP "\f(CW$node\fR\->mother" 4
+.IX Item "$node->mother"
+This returns what node is \f(CW$node\fR's mother. This is undef if \f(CW$node\fR has
+no mother \*(-- i.e., if it is a root.
+.ie n .IP "$mother\->add_daughters( \s-1LIST\s0 )" 4
+.el .IP "\f(CW$mother\fR\->add_daughters( \s-1LIST\s0 )" 4
+.IX Item "$mother->add_daughters( LIST )"
+This method adds the node objects in \s-1LIST\s0 to the (right) end of
+\&\f(CW$mother\fR's \f(CW\*(C`daughter\*(C'\fR list. Making a node N1 the daughter of another
+node N2 also means that N1's \f(CW\*(C`mother\*(C'\fR attribute is \*(L"automatically\*(R" set
+to N2; it also means that N1 stops being anything else's daughter as
+it becomes N2's daughter.
+.Sp
+If you try to make a node its own mother, a fatal error results. If
+you try to take one of a a node N1's ancestors and make it also a
+daughter of N1, a fatal error results. A fatal error results if
+anything in \s-1LIST\s0 isn't a node object.
+.Sp
+If you try to make N1 a daughter of N2, but it's \fBalready\fR a daughter
+of N2, then this is a no-operation \*(-- it won't move such nodes to the
+end of the list or anything; it just skips doing anything with them.
+.ie n .IP "$node\->add_daughter( \s-1LIST\s0 )" 4
+.el .IP "\f(CW$node\fR\->add_daughter( \s-1LIST\s0 )" 4
+.IX Item "$node->add_daughter( LIST )"
+An exact synonym for \f(CW$node\fR\->add_daughters(\s-1LIST\s0)
+.ie n .IP "$mother\->add_daughters_left( \s-1LIST\s0 )" 4
+.el .IP "\f(CW$mother\fR\->add_daughters_left( \s-1LIST\s0 )" 4
+.IX Item "$mother->add_daughters_left( LIST )"
+This method is just like \f(CW\*(C`add_daughters\*(C'\fR, except that it adds the
+node objects in \s-1LIST\s0 to the (left) beginning of \f(CW$mother\fR's daughter
+list, instead of the (right) end of it.
+.ie n .IP "$node\->add_daughter_left( \s-1LIST\s0 )" 4
+.el .IP "\f(CW$node\fR\->add_daughter_left( \s-1LIST\s0 )" 4
+.IX Item "$node->add_daughter_left( LIST )"
+An exact synonym for \f(CW$node\fR\->add_daughters_left( \s-1LIST\s0 )
+.IP "Note:" 4
+.IX Item "Note:"
+The above link-making methods perform basically an \f(CW\*(C`unshift\*(C'\fR or
+\&\f(CW\*(C`push\*(C'\fR on the mother node's daughter list. To get the full range of
+list-handling functionality, copy the daughter list, and change it,
+and then call \f(CW\*(C`set_daughters\*(C'\fR on the result:
+.Sp
+.Vb 3
+\& @them = $mother\->daughters;
+\& @removed = splice(@them, 0,2, @new_nodes);
+\& $mother\->set_daughters(@them);
+.Ve
+.Sp
+Or consider a structure like:
+.Sp
+.Vb 5
+\& $mother\->set_daughters(
+\& grep($_\->name =~ /NP/ ,
+\& $mother\->daughters
+\& )
+\& );
+.Ve
+.ie n .IP "the constructor $daughter = $mother\->new_daughter, or" 4
+.el .IP "the constructor \f(CW$daughter\fR = \f(CW$mother\fR\->new_daughter, or" 4
+.IX Item "the constructor $daughter = $mother->new_daughter, or"
+.PD 0
+.ie n .IP "the constructor $daughter = $mother\->new_daughter({...options...})" 4
+.el .IP "the constructor \f(CW$daughter\fR = \f(CW$mother\fR\->new_daughter({...options...})" 4
+.IX Item "the constructor $daughter = $mother->new_daughter({...options...})"
+.PD
+This \fBconstructs\fR a \fBnew\fR node (of the same class as \f(CW$mother\fR), and
+adds it to the (right) end of the daughter list of \f(CW$mother\fR. This is
+essentially the same as going
+.Sp
+.Vb 2
+\& $daughter = $mother\->new;
+\& $mother\->add_daughter($daughter);
+.Ve
+.Sp
+but is rather more efficient because (since \f(CW$daughter\fR is guaranteed new
+and isn't linked to/from anything), it doesn't have to check that
+\&\f(CW$daughter\fR isn't an ancestor of \f(CW$mother\fR, isn't already daughter to a
+mother it needs to be unlinked from, isn't already in \f(CW$mother\fR's
+daughter list, etc.
+.Sp
+As you'd expect for a constructor, it returns the node-object created.
+.ie n .IP "the constructor $mother\->new_daughter_left, or" 4
+.el .IP "the constructor \f(CW$mother\fR\->new_daughter_left, or" 4
+.IX Item "the constructor $mother->new_daughter_left, or"
+.PD 0
+.ie n .IP "$mother\->new_daughter_left({...options...})" 4
+.el .IP "\f(CW$mother\fR\->new_daughter_left({...options...})" 4
+.IX Item "$mother->new_daughter_left({...options...})"
+.PD
+This is just like \f(CW$mother\fR\->new_daughter, but adds the new daughter
+to the left (start) of \f(CW$mother\fR's daughter list.
+.ie n .IP "$mother\->remove_daughters( \s-1LIST\s0 )" 4
+.el .IP "\f(CW$mother\fR\->remove_daughters( \s-1LIST\s0 )" 4
+.IX Item "$mother->remove_daughters( LIST )"
+This removes the nodes listed in \s-1LIST\s0 from \f(CW$mother\fR's daughter list.
+This is a no-operation if \s-1LIST\s0 is empty. If there are things in \s-1LIST\s0
+that aren't a current daughter of \f(CW$mother\fR, they are ignored.
+.Sp
+Not to be confused with \f(CW$mother\fR\->clear_daughters.
+.ie n .IP "$node\->remove_daughter( \s-1LIST\s0 )" 4
+.el .IP "\f(CW$node\fR\->remove_daughter( \s-1LIST\s0 )" 4
+.IX Item "$node->remove_daughter( LIST )"
+An exact synonym for \f(CW$node\fR\->remove_daughters( \s-1LIST\s0 )
+.ie n .IP "$node\->unlink_from_mother" 4
+.el .IP "\f(CW$node\fR\->unlink_from_mother" 4
+.IX Item "$node->unlink_from_mother"
+This removes node from the daughter list of its mother. If it has no
+mother, this is a no-operation.
+.Sp
+Returns the mother unlinked from (if any).
+.ie n .IP "$mother\->clear_daughters" 4
+.el .IP "\f(CW$mother\fR\->clear_daughters" 4
+.IX Item "$mother->clear_daughters"
+This unlinks all \f(CW$mother\fR's daughters.
+Returns the the list of what used to be \f(CW$mother\fR's daughters.
+.Sp
+Not to be confused with \f(CW$mother\fR\->remove_daughters( \s-1LIST\s0 ).
+.ie n .IP "$mother\->set_daughters( \s-1LIST\s0 )" 4
+.el .IP "\f(CW$mother\fR\->set_daughters( \s-1LIST\s0 )" 4
+.IX Item "$mother->set_daughters( LIST )"
+This unlinks all \f(CW$mother\fR's daughters, and replaces them with the
+daughters in \s-1LIST\s0.
+.Sp
+Currently implemented as just \f(CW$mother\fR\->clear_daughters followed by
+\&\f(CW$mother\fR\->add_daughters( \s-1LIST\s0 ).
+.ie n .IP "$node\->replace_with( \s-1LIST\s0 )" 4
+.el .IP "\f(CW$node\fR\->replace_with( \s-1LIST\s0 )" 4
+.IX Item "$node->replace_with( LIST )"
+This replaces \f(CW$node\fR in its mother's daughter list, by unlinking \f(CW$node\fR
+and replacing it with the items in \s-1LIST\s0. This returns a list consisting
+of \f(CW$node\fR followed by \s-1LIST\s0, i.e., the nodes that replaced it.
+.Sp
+\&\s-1LIST\s0 can include \f(CW$node\fR itself (presumably at most once). \s-1LIST\s0 can
+also be empty-list. However, if any items in \s-1LIST\s0 are sisters to
+\&\f(CW$node\fR, they are ignored, and are not in the copy of \s-1LIST\s0 passed as the
+return value.
+.Sp
+As you might expect for any linking operation, the items in \s-1LIST\s0
+cannot be \f(CW$node\fR's mother, or any ancestor to it; and items in \s-1LIST\s0 are,
+of course, unlinked from their mothers (if they have any) as they're
+linked to \f(CW$node\fR's mother.
+.Sp
+(In the special (and bizarre) case where \f(CW$node\fR is root, this simply calls
+\&\f(CW$this\fR\->unlink_from_mother on all the items in \s-1LIST\s0, making them roots of
+their own trees.)
+.Sp
+Note that the daughter-list of \f(CW$node\fR is not necessarily affected; nor
+are the daughter-lists of the items in \s-1LIST\s0. I mention this in case you
+think replace_with switches one node for another, with respect to its
+mother list \fBand\fR its daughter list, leaving the rest of the tree
+unchanged. If that's what you want, replacing \f(CW$Old\fR with \f(CW$New\fR, then you
+want:
+.Sp
+.Vb 2
+\& $New\->set_daughters($Old\->clear_daughters);
+\& $Old\->replace_with($New);
+.Ve
+.Sp
+(I can't say \f(CW$node\fR's and LIST\-items' daughter lists are \fBnever\fR
+affected my replace_with \*(-- they can be affected in this case:
+.Sp
+.Vb 4
+\& $N1 = ($node\->daughters)[0]; # first daughter of $node
+\& $N2 = ($N1\->daughters)[0]; # first daughter of $N1;
+\& $N3 = Tree::DAG_Node\->random_network; # or whatever
+\& $node\->replace_with($N1, $N2, $N3);
+.Ve
+.Sp
+As a side affect of attaching \f(CW$N1\fR and \f(CW$N2\fR to \f(CW$node\fR's mother, they're
+unlinked from their parents ($node, and \f(CW$N1\fR, replectively).
+But N3's daughter list is unaffected.
+.Sp
+In other words, this method does what it has to, as you'd expect it
+to.
+.ie n .IP "$node\->replace_with_daughters" 4
+.el .IP "\f(CW$node\fR\->replace_with_daughters" 4
+.IX Item "$node->replace_with_daughters"
+This replaces \f(CW$node\fR in its mother's daughter list, by unlinking \f(CW$node\fR
+and replacing it with its daughters. In other words, \f(CW$node\fR becomes
+motherless and daughterless as its daughters move up and take its place.
+This returns a list consisting of \f(CW$node\fR followed by the nodes that were
+its daughters.
+.Sp
+In the special (and bizarre) case where \f(CW$node\fR is root, this simply
+unlinks its daughters from it, making them roots of their own trees.
+.Sp
+Effectively the same as \f(CW$node\fR\->replace_with($node\->daughters), but more
+efficient, since less checking has to be done. (And I also think
+\&\f(CW$node\fR\->replace_with_daughters is a more common operation in
+tree-wrangling than \f(CW$node\fR\->replace_with(\s-1LIST\s0), so deserves a named
+method of its own, but that's just me.)
+.ie n .IP "$node\->add_left_sisters( \s-1LIST\s0 )" 4
+.el .IP "\f(CW$node\fR\->add_left_sisters( \s-1LIST\s0 )" 4
+.IX Item "$node->add_left_sisters( LIST )"
+This adds the elements in \s-1LIST\s0 (in that order) as immediate left sisters of
+\&\f(CW$node\fR. In other words, given that B's mother's daughter-list is (A,B,C,D),
+calling B\->add_left_sisters(X,Y) makes B's mother's daughter-list
+(A,X,Y,B,C,D).
+.Sp
+If \s-1LIST\s0 is empty, this is a no-op, and returns empty-list.
+.Sp
+This is basically implemented as a call to \f(CW$node\fR\->replace_with(\s-1LIST\s0,
+\&\f(CW$node\fR), and so all replace_with's limitations and caveats apply.
+.Sp
+The return value of \f(CW$node\fR\->add_left_sisters( \s-1LIST\s0 ) is the elements of
+\&\s-1LIST\s0 that got added, as returned by replace_with \*(-- minus the copies
+of \f(CW$node\fR you'd get from a straight call to \f(CW$node\fR\->replace_with(\s-1LIST\s0,
+\&\f(CW$node\fR).
+.ie n .IP "$node\->add_left_sister( \s-1LIST\s0 )" 4
+.el .IP "\f(CW$node\fR\->add_left_sister( \s-1LIST\s0 )" 4
+.IX Item "$node->add_left_sister( LIST )"
+An exact synonym for \f(CW$node\fR\->add_left_sisters(\s-1LIST\s0)
+.ie n .IP "$node\->add_right_sisters( \s-1LIST\s0 )" 4
+.el .IP "\f(CW$node\fR\->add_right_sisters( \s-1LIST\s0 )" 4
+.IX Item "$node->add_right_sisters( LIST )"
+Just like add_left_sisters (which see), except that the the elements
+in \s-1LIST\s0 (in that order) as immediate \fBright\fR sisters of \f(CW$node\fR;
+.Sp
+In other words, given that B's mother's daughter-list is (A,B,C,D),
+calling B\->add_right_sisters(X,Y) makes B's mother's daughter-list
+(A,B,X,Y,C,D).
+.ie n .IP "$node\->add_right_sister( \s-1LIST\s0 )" 4
+.el .IP "\f(CW$node\fR\->add_right_sister( \s-1LIST\s0 )" 4
+.IX Item "$node->add_right_sister( LIST )"
+An exact synonym for \f(CW$node\fR\->add_right_sisters(\s-1LIST\s0)
+.SH "OTHER ATTRIBUTE METHODS"
+.IX Header "OTHER ATTRIBUTE METHODS"
+.ie n .IP "$node\->name or $node\->name(\s-1SCALAR\s0)" 4
+.el .IP "\f(CW$node\fR\->name or \f(CW$node\fR\->name(\s-1SCALAR\s0)" 4
+.IX Item "$node->name or $node->name(SCALAR)"
+In the first form, returns the value of the node object's \*(L"name\*(R"
+attribute. In the second form, sets it to the value of \s-1SCALAR\s0.
+.ie n .IP "$node\->attributes or $node\->attributes(\s-1SCALAR\s0)" 4
+.el .IP "\f(CW$node\fR\->attributes or \f(CW$node\fR\->attributes(\s-1SCALAR\s0)" 4
+.IX Item "$node->attributes or $node->attributes(SCALAR)"
+In the first form, returns the value of the node object's \*(L"attributes\*(R"
+attribute. In the second form, sets it to the value of \s-1SCALAR\s0. I
+intend this to be used to store a reference to a (presumably
+anonymous) hash the user can use to store whatever attributes he
+doesn't want to have to store as object attributes. In this case, you
+needn't ever set the value of this. (_init has already initialized it
+to {}.) Instead you can just do...
+.Sp
+.Vb 1
+\& $node\->attributes\->{\*(Aqfoo\*(Aq} = \*(Aqbar\*(Aq;
+.Ve
+.Sp
+\&...to write foo => bar.
+.ie n .IP "$node\->attribute or $node\->attribute(\s-1SCALAR\s0)" 4
+.el .IP "\f(CW$node\fR\->attribute or \f(CW$node\fR\->attribute(\s-1SCALAR\s0)" 4
+.IX Item "$node->attribute or $node->attribute(SCALAR)"
+An exact synonym for \f(CW$node\fR\->attributes or \f(CW$node\fR\->attributes(\s-1SCALAR\s0)
+.SH "OTHER METHODS TO DO WITH RELATIONSHIPS"
+.IX Header "OTHER METHODS TO DO WITH RELATIONSHIPS"
+.ie n .IP "$node\->is_node" 4
+.el .IP "\f(CW$node\fR\->is_node" 4
+.IX Item "$node->is_node"
+This always returns true. More pertinently, \f(CW$object\fR\->can('is_node')
+is true (regardless of what \f(CW\*(C`is_node\*(C'\fR would do if called) for objects
+belonging to this class or for any class derived from it.
+.ie n .IP "$node\->ancestors" 4
+.el .IP "\f(CW$node\fR\->ancestors" 4
+.IX Item "$node->ancestors"
+Returns the list of this node's ancestors, starting with its mother,
+then grandmother, and ending at the root. It does this by simply
+following the 'mother' attributes up as far as it can. So if \f(CW$item\fR \s-1IS\s0
+the root, this returns an empty list.
+.Sp
+Consider that scalar($node\->ancestors) returns the ply of this node
+within the tree \*(-- 2 for a granddaughter of the root, etc., and 0 for
+root itself.
+.ie n .IP "$node\->root" 4
+.el .IP "\f(CW$node\fR\->root" 4
+.IX Item "$node->root"
+Returns the root of whatever tree \f(CW$node\fR is a member of. If \f(CW$node\fR is
+the root, then the result is \f(CW$node\fR itself.
+.ie n .IP "$node\->is_daughter_of($node2)" 4
+.el .IP "\f(CW$node\fR\->is_daughter_of($node2)" 4
+.IX Item "$node->is_daughter_of($node2)"
+Returns true iff \f(CW$node\fR is a daughter of \f(CW$node2\fR.
+Currently implemented as just a test of ($it\->mother eq \f(CW$node2\fR).
+.ie n .IP "$node\->self_and_descendants" 4
+.el .IP "\f(CW$node\fR\->self_and_descendants" 4
+.IX Item "$node->self_and_descendants"
+Returns a list consisting of itself (as element 0) and all the
+descendants of \f(CW$node\fR. Returns just itself if \f(CW$node\fR is a
+terminal_node.
+.Sp
+(Note that it's spelled \*(L"descendants\*(R", not \*(L"descendents\*(R".)
+.ie n .IP "$node\->descendants" 4
+.el .IP "\f(CW$node\fR\->descendants" 4
+.IX Item "$node->descendants"
+Returns a list consisting of all the descendants of \f(CW$node\fR. Returns
+empty-list if \f(CW$node\fR is a terminal_node.
+.Sp
+(Note that it's spelled \*(L"descendants\*(R", not \*(L"descendents\*(R".)
+.ie n .IP "$node\->leaves_under" 4
+.el .IP "\f(CW$node\fR\->leaves_under" 4
+.IX Item "$node->leaves_under"
+Returns a list (going left-to-right) of all the leaf nodes under
+\&\f(CW$node\fR. (\*(L"Leaf nodes\*(R" are also called \*(L"terminal nodes\*(R" \*(-- i.e., nodes
+that have no daughters.) Returns \f(CW$node\fR in the degenerate case of
+\&\f(CW$node\fR being a leaf itself.
+.ie n .IP "$node\->depth_under" 4
+.el .IP "\f(CW$node\fR\->depth_under" 4
+.IX Item "$node->depth_under"
+Returns an integer representing the number of branches between this
+\&\f(CW$node\fR and the most distant leaf under it. (In other words, this
+returns the ply of subtree starting of \f(CW$node\fR. Consider
+scalar($it\->ancestors) if you want the ply of a node within the whole
+tree.)
+.ie n .IP "$node\->generation" 4
+.el .IP "\f(CW$node\fR\->generation" 4
+.IX Item "$node->generation"
+Returns a list of all nodes (going left-to-right) that are in \f(CW$node\fR's
+generation \*(-- i.e., that are the some number of nodes down from
+the root. \f(CW$root\fR\->generation is just \f(CW$root\fR.
+.Sp
+Of course, \f(CW$node\fR is always in its own generation.
+.ie n .IP "$node\->generation_under(\s-1NODE2\s0)" 4
+.el .IP "\f(CW$node\fR\->generation_under(\s-1NODE2\s0)" 4
+.IX Item "$node->generation_under(NODE2)"
+Like \f(CW$node\fR\->generation, but returns only the nodes in \f(CW$node\fR's generation
+that are also descendants of \s-1NODE2\s0 \*(-- in other words,
+.Sp
+.Vb 1
+\& @us = $node\->generation_under( $node\->mother\->mother );
+.Ve
+.Sp
+is all \f(CW$node\fR's first cousins (to borrow yet more kinship terminology) \*(--
+assuming \f(CW$node\fR does indeed have a grandmother. Actually \*(L"cousins\*(R" isn't
+quite an apt word, because \f(CW@us\fR ends up including \f(CW$node\fR's siblings and
+\&\f(CW$node\fR.
+.Sp
+Actually, \f(CW\*(C`generation_under\*(C'\fR is just an alias to \f(CW\*(C`generation\*(C'\fR, but I
+figure that this:
+.Sp
+.Vb 1
+\& @us = $node\->generation_under($way_upline);
+.Ve
+.Sp
+is a bit more readable than this:
+.Sp
+.Vb 1
+\& @us = $node\->generation($way_upline);
+.Ve
+.Sp
+But it's up to you.
+.Sp
+\&\f(CW$node\fR\->generation_under($node) returns just \f(CW$node\fR.
+.Sp
+If you call \f(CW$node\fR\->generation_under($node) but \s-1NODE2\s0 is not \f(CW$node\fR or an
+ancestor of \f(CW$node\fR, it behaves as if you called just \f(CW$node\fR\->\fIgeneration()\fR.
+.ie n .IP "$node\->self_and_sisters" 4
+.el .IP "\f(CW$node\fR\->self_and_sisters" 4
+.IX Item "$node->self_and_sisters"
+Returns a list of all nodes (going left-to-right) that have the same
+mother as \f(CW$node\fR \*(-- including \f(CW$node\fR itself. This is just like
+\&\f(CW$node\fR\->mother\->daughters, except that that fails where \f(CW$node\fR is root,
+whereas \f(CW$root\fR\->self_and_siblings, as a special case, returns \f(CW$root\fR.
+.Sp
+(Contrary to how you may interpret how this method is named, \*(L"self\*(R" is
+not (necessarily) the first element of what's returned.)
+.ie n .IP "$node\->sisters" 4
+.el .IP "\f(CW$node\fR\->sisters" 4
+.IX Item "$node->sisters"
+Returns a list of all nodes (going left-to-right) that have the same
+mother as \f(CW$node\fR \*(-- \fBnot including\fR \f(CW$node\fR itself. If \f(CW$node\fR is root,
+this returns empty-list.
+.ie n .IP "$node\->left_sister" 4
+.el .IP "\f(CW$node\fR\->left_sister" 4
+.IX Item "$node->left_sister"
+Returns the node that's the immediate left sister of \f(CW$node\fR. If \f(CW$node\fR
+is the leftmost (or only) daughter of its mother (or has no mother),
+then this returns undef.
+.Sp
+(See also \f(CW$node\fR\->add_left_sisters(\s-1LIST\s0).)
+.ie n .IP "$node\->left_sisters" 4
+.el .IP "\f(CW$node\fR\->left_sisters" 4
+.IX Item "$node->left_sisters"
+Returns a list of nodes that're sisters to the left of \f(CW$node\fR. If
+\&\f(CW$node\fR is the leftmost (or only) daughter of its mother (or has no
+mother), then this returns an empty list.
+.Sp
+(See also \f(CW$node\fR\->add_left_sisters(\s-1LIST\s0).)
+.ie n .IP "$node\->right_sister" 4
+.el .IP "\f(CW$node\fR\->right_sister" 4
+.IX Item "$node->right_sister"
+Returns the node that's the immediate right sister of \f(CW$node\fR. If \f(CW$node\fR
+is the rightmost (or only) daughter of its mother (or has no mother),
+then this returns undef.
+.Sp
+(See also \f(CW$node\fR\->add_right_sisters(\s-1LIST\s0).)
+.ie n .IP "$node\->right_sisters" 4
+.el .IP "\f(CW$node\fR\->right_sisters" 4
+.IX Item "$node->right_sisters"
+Returns a list of nodes that're sisters to the right of \f(CW$node\fR. If
+\&\f(CW$node\fR is the rightmost (or only) daughter of its mother (or has no
+mother), then this returns an empty list.
+.Sp
+(See also \f(CW$node\fR\->add_right_sisters(\s-1LIST\s0).)
+.ie n .IP "$node\->my_daughter_index" 4
+.el .IP "\f(CW$node\fR\->my_daughter_index" 4
+.IX Item "$node->my_daughter_index"
+Returns what index this daughter is, in its mother's \f(CW\*(C`daughter\*(C'\fR list.
+In other words, if \f(CW$node\fR is ($node\->mother\->daughters)[3], then
+\&\f(CW$node\fR\->my_daughter_index returns 3.
+.Sp
+As a special case, returns 0 if \f(CW$node\fR has no mother.
+.ie n .IP "$node\->address or $anynode\->address(\s-1ADDRESS\s0)" 4
+.el .IP "\f(CW$node\fR\->address or \f(CW$anynode\fR\->address(\s-1ADDRESS\s0)" 4
+.IX Item "$node->address or $anynode->address(ADDRESS)"
+With the first syntax, returns the address of \f(CW$node\fR within its tree,
+based on its position within the tree. An address is formed by noting
+the path between the root and \f(CW$node\fR, and concatenating the
+daughter-indices of the nodes this passes thru (starting with 0 for
+the root, and ending with \f(CW$node\fR).
+.Sp
+For example, if to get from node \s-1ROOT\s0 to node \f(CW$node\fR, you pass thru
+\&\s-1ROOT\s0, A, B, and \f(CW$node\fR, then the address is determined as:
+.Sp
+* \s-1ROOT\s0's my_daughter_index is 0.
+.Sp
+* A's my_daughter_index is, suppose, 2. (A is index 2 in \s-1ROOT\s0's
+daughter list.)
+.Sp
+* B's my_daughter_index is, suppose, 0. (B is index 0 in A's
+daughter list.)
+.Sp
+* \f(CW$node\fR's my_daughter_index is, suppose, 4. ($node is index 4 in
+B's daughter list.)
+.Sp
+The address of the above-described \f(CW$node\fR is, therefore, \*(L"0:2:0:4\*(R".
+.Sp
+(As a somewhat special case, the address of the root is always \*(L"0\*(R";
+and since addresses start from the root, all addresses start with a
+\&\*(L"0\*(R".)
+.Sp
+The second syntax, where you provide an address, starts from the root
+of the tree \f(CW$anynode\fR belongs to, and returns the node corresponding to
+that address. Returns undef if no node corresponds to that address.
+Note that this routine may be somewhat liberal in its interpretation
+of what can constitute an address; i.e., it accepts \*(L"0.2.0.4\*(R", besides
+\&\*(L"0:2:0:4\*(R".
+.Sp
+Also note that the address of a node in a tree is meaningful only in
+that tree as currently structured.
+.Sp
+(Consider how ($address1 cmp \f(CW$address2\fR) may be magically meaningful
+to you, if you mant to figure out what nodes are to the right of what
+other nodes.)
+.ie n .IP "$node\->common(\s-1LIST\s0)" 4
+.el .IP "\f(CW$node\fR\->common(\s-1LIST\s0)" 4
+.IX Item "$node->common(LIST)"
+Returns the lowest node in the tree that is ancestor-or-self to the
+nodes \f(CW$node\fR and \s-1LIST\s0.
+.Sp
+If the nodes are far enough apart in the tree, the answer is just the
+root.
+.Sp
+If the nodes aren't all in the same tree, the answer is undef.
+.Sp
+As a degenerate case, if \s-1LIST\s0 is empty, returns \f(CW$node\fR.
+.ie n .IP "$node\->common_ancestor(\s-1LIST\s0)" 4
+.el .IP "\f(CW$node\fR\->common_ancestor(\s-1LIST\s0)" 4
+.IX Item "$node->common_ancestor(LIST)"
+Returns the lowest node that is ancestor to all the nodes given (in
+nodes \f(CW$node\fR and \s-1LIST\s0). In other words, it answers the question: \*(L"What
+node in the tree, as low as possible, is ancestor to the nodes given
+($node and \s-1LIST\s0)?\*(R"
+.Sp
+If the nodes are far enough apart, the answer is just the root \*(--
+except if any of the nodes are the root itself, in which case the
+answer is undef (since the root has no ancestor).
+.Sp
+If the nodes aren't all in the same tree, the answer is undef.
+.Sp
+As a degenerate case, if \s-1LIST\s0 is empty, returns \f(CW$node\fR's mother;
+that'll be undef if \f(CW$node\fR is root.
+.SH "YET MORE METHODS"
+.IX Header "YET MORE METHODS"
+.ie n .IP "$node\->walk_down({ callback => \e&foo, callbackback => \e&foo, ... })" 4
+.el .IP "\f(CW$node\fR\->walk_down({ callback => \e&foo, callbackback => \e&foo, ... })" 4
+.IX Item "$node->walk_down({ callback => &foo, callbackback => &foo, ... })"
+Performs a depth-first traversal of the structure at and under \f(CW$node\fR.
+What it does at each node depends on the value of the options hashref,
+which you must provide. There are three options, \*(L"callback\*(R" and
+\&\*(L"callbackback\*(R" (at least one of which must be defined, as a sub
+reference), and \*(L"_depth\*(R". This is what \f(CW\*(C`walk_down\*(C'\fR does, in
+pseudocode form:
+.Sp
+* Start at the \f(CW$node\fR given.
+.Sp
+* If there's a \f(CW\*(C`callback\*(C'\fR, call it with \f(CW$node\fR as the first argument,
+and the options hashref as the second argument (which contains the
+potentially useful \f(CW\*(C`_depth\*(C'\fR, remember). This function must return
+true or false \*(-- if false, it will block the next step:
+.Sp
+* If \f(CW$node\fR has any daughter nodes, increment \f(CW\*(C`_depth\*(C'\fR, and call
+\&\f(CW$daughter\fR\->walk_down(options_hashref) for each daughter (in order, of
+course), where options_hashref is the same hashref it was called with.
+When this returns, decrements \f(CW\*(C`_depth\*(C'\fR.
+.Sp
+* If there's a \f(CW\*(C`callbackback\*(C'\fR, call just it as with \f(CW\*(C`callback\*(C'\fR (but
+tossing out the return value). Note that \f(CW\*(C`callback\*(C'\fR returning false
+blocks traversal below \f(CW$node\fR, but doesn't block calling callbackback
+for \f(CW$node\fR. (Incidentally, in the unlikely case that \f(CW$node\fR has stopped
+being a node object, \f(CW\*(C`callbackback\*(C'\fR won't get called.)
+.Sp
+* Return.
+.Sp
+\&\f(CW$node\fR\->walk_down is the way to recursively do things to a tree (if you
+start at the root) or part of a tree; if what you're doing is best done
+via pre-pre order traversal, use \f(CW\*(C`callback\*(C'\fR; if what you're doing is
+best done with post-order traversal, use \f(CW\*(C`callbackback\*(C'\fR.
+\&\f(CW\*(C`walk_down\*(C'\fR is even the basis for plenty of the methods in this
+class. See the source code for examples both simple and horrific.
+.Sp
+Note that if you don't specify \f(CW\*(C`_depth\*(C'\fR, it effectively defaults to
+0. You should set it to scalar($node\->ancestors) if you want
+\&\f(CW\*(C`_depth\*(C'\fR to reflect the true depth-in-the-tree for the nodes called,
+instead of just the depth below \f(CW$node\fR. (If \f(CW$node\fR is the root, there's
+difference, of course.)
+.Sp
+And \fBby the way\fR, it's a bad idea to modify the tree from the callback.
+Unpredictable things may happen. I instead suggest having your callback
+add to a stack of things that need changing, and then, once \f(CW\*(C`walk_down\*(C'\fR
+is all finished, changing those nodes from that stack.
+.Sp
+Note that the existence of \f(CW\*(C`walk_down\*(C'\fR doesn't mean you can't write
+you own special-use traversers.
+.ie n .IP "@lines = $node\->dump_names({ ...options... });" 4
+.el .IP "\f(CW@lines\fR = \f(CW$node\fR\->dump_names({ ...options... });" 4
+.IX Item "@lines = $node->dump_names({ ...options... });"
+Dumps, as an indented list, the names of the nodes starting at \f(CW$node\fR,
+and continuing under it. Options are:
+.Sp
+* _depth \*(-- A nonnegative number. Indicating the depth to consider
+\&\f(CW$node\fR as being at (and so the generation under that is that plus one,
+etc.). Defaults to 0. You may choose to use set _depth =>
+scalar($node\->ancestors).
+.Sp
+* tick \*(-- a string to preface each entry with, between the
+indenting-spacing and the node's name. Defaults to empty-string. You
+may prefer \*(L"*\*(R" or \*(L"\-> \*(R" or someting.
+.Sp
+* indent \*(-- the string used to indent with. Defaults to \*(L" \*(R" (two
+spaces). Another sane value might be \*(L". \*(R" (period, space). Setting it
+to empty-string suppresses indenting.
+.Sp
+The dump is not printed, but is returned as a list, where each
+item is a line, with a \*(L"\en\*(R" at the end.
+.IP "the constructor \s-1CLASS\-\s0>random_network({...options...})" 4
+.IX Item "the constructor CLASS->random_network({...options...})"
+.PD 0
+.ie n .IP "the method $node\->random_network({...options...})" 4
+.el .IP "the method \f(CW$node\fR\->random_network({...options...})" 4
+.IX Item "the method $node->random_network({...options...})"
+.PD
+In the first case, constructs a randomly arranged network under a new
+node, and returns the root node of that tree. In the latter case,
+constructs the network under \f(CW$node\fR.
+.Sp
+Currently, this is implemented a bit half-heartedly, and
+half-wittedly. I basically needed to make up random-looking networks
+to stress-test the various tree-dumper methods, and so wrote this. If
+you actually want to rely on this for any application more
+serious than that, I suggest examining the source code and seeing if
+this does really what you need (say, in reliability of randomness);
+and feel totally free to suggest changes to me (especially in the form
+of "I rewrote \f(CW\*(C`random_network\*(C'\fR, here's the code...")
+.Sp
+It takes four options:
+.Sp
+* max_node_count \*(-- maximum number of nodes this tree will be allowed
+to have (counting the root). Defaults to 25.
+.Sp
+* min_depth \*(-- minimum depth for the tree. Defaults to 2. Leaves can
+be generated only after this depth is reached, so the tree will be at
+least this deep \*(-- unless max_node_count is hit first.
+.Sp
+* max_depth \*(-- maximum depth for the tree. Defaults to 3 plus
+min_depth. The tree will not be deeper than this.
+.Sp
+* max_children \*(-- maximum number of children any mother in the tree
+can have. Defaults to 4.
+.IP "the constructor \s-1CLASS\-\s0>lol_to_tree($lol);" 4
+.IX Item "the constructor CLASS->lol_to_tree($lol);"
+Converts something like bracket-notation for \*(L"Chomsky trees\*(R" (or
+rather, the closest you can come with Perl
+list\-of\-lists(\-of\-lists(\-of\-lists))) into a tree structure. Returns
+the root of the tree converted.
+.Sp
+The conversion rules are that: 1) if the last (possibly the only) item
+in a given list is a scalar, then that is used as the \*(L"name\*(R" attribute
+for the node based on this list. 2) All other items in the list
+represent daughter nodes of the current node \*(-- recursively so, if
+they are list references; otherwise, (non-terminal) scalars are
+considered to denote nodes with that name. So ['Foo', 'Bar', 'N'] is
+an alternate way to represent [['Foo'], ['Bar'], 'N'].
+.Sp
+An example will illustrate:
+.Sp
+.Vb 10
+\& use Tree::DAG_Node;
+\& $lol =
+\& [
+\& [
+\& [ [ \*(AqDet:The\*(Aq ],
+\& [ [ \*(Aqdog\*(Aq ], \*(AqN\*(Aq], \*(AqNP\*(Aq],
+\& [ \*(Aq/with rabies\e\e\*(Aq, \*(AqPP\*(Aq],
+\& \*(AqNP\*(Aq
+\& ],
+\& [ \*(Aqdied\*(Aq, \*(AqVP\*(Aq],
+\& \*(AqS\*(Aq
+\& ];
+\& $tree = Tree::DAG_Node\->lol_to_tree($lol);
+\& $diagram = $tree\->draw_ascii_tree;
+\& print map "$_\en", @$diagram;
+.Ve
+.Sp
+\&...returns this tree:
+.Sp
+.Vb 10
+\& |
+\& <S>
+\& |
+\& /\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\e
+\& | |
+\& <NP> <VP>
+\& | |
+\& /\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\e <died>
+\& | |
+\& <NP> <PP>
+\& | |
+\& /\-\-\-\-\-\-\-\e </with rabies\e>
+\& | |
+\& <Det:The> <N>
+\& |
+\& <dog>
+.Ve
+.Sp
+By the way (and this rather follows from the above rules), when
+denoting a LoL tree consisting of just one node, this:
+.Sp
+.Vb 1
+\& $tree = Tree::DAG_Node\->lol_to_tree( \*(AqLonely\*(Aq );
+.Ve
+.Sp
+is okay, although it'd probably occur to you to denote it only as:
+.Sp
+.Vb 1
+\& $tree = Tree::DAG_Node\->lol_to_tree( [\*(AqLonely\*(Aq] );
+.Ve
+.Sp
+which is of course fine, too.
+.ie n .IP "$node\->tree_to_lol_notation({...options...})" 4
+.el .IP "\f(CW$node\fR\->tree_to_lol_notation({...options...})" 4
+.IX Item "$node->tree_to_lol_notation({...options...})"
+Dumps a tree (starting at \f(CW$node\fR) as the sort of LoL-like bracket
+notation you see in the above example code. Returns just one big
+block of text. The only option is \*(L"multiline\*(R" \*(-- if true, it dumps
+the text as the sort of indented structure as seen above; if false
+(and it defaults to false), dumps it all on one line (with no
+indenting, of course).
+.Sp
+For example, starting with the tree from the above example,
+this:
+.Sp
+.Vb 1
+\& print $tree\->tree_to_lol_notation, "\en";
+.Ve
+.Sp
+prints the following (which I've broken over two lines for sake of
+printablitity of documentation):
+.Sp
+.Vb 2
+\& [[[[\*(AqDet:The\*(Aq], [[\*(Aqdog\*(Aq], \*(AqN\*(Aq], \*(AqNP\*(Aq], [["/with rabies\ex5c"],
+\& \*(AqPP\*(Aq], \*(AqNP\*(Aq], [[\*(Aqdied\*(Aq], \*(AqVP\*(Aq], \*(AqS\*(Aq],
+.Ve
+.Sp
+Doing this:
+.Sp
+.Vb 1
+\& print $tree\->tree_to_lol_notation({ multiline => 1 });
+.Ve
+.Sp
+prints the same content, just spread over many lines, and prettily
+indented.
+.ie n .IP "$node\->tree_to_lol" 4
+.el .IP "\f(CW$node\fR\->tree_to_lol" 4
+.IX Item "$node->tree_to_lol"
+Returns that tree (starting at \f(CW$node\fR) represented as a LoL, like what
+\&\f(CW$lol\fR, above, holds. (This is as opposed to \f(CW\*(C`tree_to_lol_notation\*(C'\fR,
+which returns the viewable code like what gets evaluated and stored in
+\&\f(CW$lol\fR, above.)
+.Sp
+Lord only knows what you use this for \*(-- maybe for feeding to
+Data::Dumper, in case \f(CW\*(C`tree_to_lol_notation\*(C'\fR doesn't do just what you
+want?
+.IP "the constructor \s-1CLASS\-\s0>simple_lol_to_tree($simple_lol);" 4
+.IX Item "the constructor CLASS->simple_lol_to_tree($simple_lol);"
+This is like lol_to_tree, except that rule 1 doesn't apply \*(-- i.e.,
+all scalars (or really, anything not a listref) in the LoL-structure
+end up as named terminal nodes, and only terminal nodes get names
+(and, of course, that name comes from that scalar value). This method
+is useful for making things like expression trees, or at least
+starting them off. Consider that this:
+.Sp
+.Vb 3
+\& $tree = Tree::DAG_Node\->simple_lol_to_tree(
+\& [ \*(Aqfoo\*(Aq, [\*(Aqbar\*(Aq, [\*(Aqbaz\*(Aq], \*(Aqquux\*(Aq], \*(Aqzaz\*(Aq, \*(Aqpati\*(Aq ]
+\& );
+.Ve
+.Sp
+converts from something like a Lispish or Iconish tree, if you pretend
+the brackets are parentheses.
+.Sp
+Note that there is a (possibly surprising) degenerate case of what I'm
+calling a \*(L"simple-LoL\*(R", and it's like this:
+.Sp
+.Vb 1
+\& $tree = Tree::DAG_Node\->simple_lol_to_tree(\*(AqLonely\*(Aq);
+.Ve
+.Sp
+This is the (only) way you can specify a tree consisting of only a
+single node, which here gets the name 'Lonely'.
+.ie n .IP "$node\->tree_to_simple_lol" 4
+.el .IP "\f(CW$node\fR\->tree_to_simple_lol" 4
+.IX Item "$node->tree_to_simple_lol"
+Returns that tree (starting at \f(CW$node\fR) represented as a simple-LoL \*(--
+i.e., one where non-terminal nodes are represented as listrefs, and
+terminal nodes are gotten from the contents of those nodes' "name'
+attributes.
+.Sp
+Note that in the case of \f(CW$node\fR being terminal, what you get back is
+the same as \f(CW$node\fR\->name.
+.Sp
+Compare to tree_to_simple_lol_notation.
+.ie n .IP "$node\->tree_to_simple_lol_notation({...options...})" 4
+.el .IP "\f(CW$node\fR\->tree_to_simple_lol_notation({...options...})" 4
+.IX Item "$node->tree_to_simple_lol_notation({...options...})"
+A simple-LoL version of tree_to_lol_notation (which see); takes the
+same options.
+.ie n .IP "$list_r = $node\->draw_ascii_tree({ ... options ... })" 4
+.el .IP "\f(CW$list_r\fR = \f(CW$node\fR\->draw_ascii_tree({ ... options ... })" 4
+.IX Item "$list_r = $node->draw_ascii_tree({ ... options ... })"
+Draws a nice ASCII-art representation of the tree structure
+at-and-under \f(CW$node\fR, with \f(CW$node\fR at the top. Returns a reference to the
+list of lines (with no \*(L"\en\*(R"s or anything at the end of them) that make
+up the picture.
+.Sp
+Example usage:
+.Sp
+.Vb 1
+\& print map("$_\en", @{$tree\->draw_ascii_tree});
+.Ve
+.Sp
+draw_ascii_tree takes parameters you set in the options hashref:
+.Sp
+* \*(L"no_name\*(R" \*(-- if true, \f(CW\*(C`draw_ascii_tree\*(C'\fR doesn't print the name of
+the node; simply prints a \*(L"*\*(R". Defaults to 0 (i.e., print the node
+name.)
+.Sp
+* \*(L"h_spacing\*(R" \*(-- number 0 or greater. Sets the number of spaces
+inserted horizontally between nodes (and groups of nodes) in a tree.
+Defaults to 1.
+.Sp
+* \*(L"h_compact\*(R" \*(-- number 0 or 1. Sets the extent to which
+\&\f(CW\*(C`draw_ascii_tree\*(C'\fR tries to save horizontal space. Defaults to 1. If
+I think of a better scrunching algorithm, there'll be a \*(L"2\*(R" setting
+for this.
+.Sp
+* \*(L"v_compact\*(R" \*(-- number 0, 1, or 2. Sets the degree to which
+\&\f(CW\*(C`draw_ascii_tree\*(C'\fR tries to save vertical space. Defaults to 1.
+.Sp
+This occasionally returns trees that are a bit cock-eyed in parts; if
+anyone can suggest a better drawing algorithm, I'd be appreciative.
+.ie n .IP "$node\->copy_tree or $node\->copy_tree({...options...})" 4
+.el .IP "\f(CW$node\fR\->copy_tree or \f(CW$node\fR\->copy_tree({...options...})" 4
+.IX Item "$node->copy_tree or $node->copy_tree({...options...})"
+This returns the root of a copy of the tree that \f(CW$node\fR is a member of.
+If you pass no options, copy_tree pretends you've passed {}.
+.Sp
+This method is currently implemented as just a call to
+\&\f(CW$this\fR\->root\->copy_at_and_under({...options...}), but magic may be
+added in the future.
+.Sp
+Options you specify are passed down to calls to \f(CW$node\fR\->copy.
+.ie n .IP "$node\->copy_at_and_under or $node\->copy_at_and_under({...options...})" 4
+.el .IP "\f(CW$node\fR\->copy_at_and_under or \f(CW$node\fR\->copy_at_and_under({...options...})" 4
+.IX Item "$node->copy_at_and_under or $node->copy_at_and_under({...options...})"
+This returns a copy of the subtree consisting of \f(CW$node\fR and everything
+under it.
+.Sp
+If you pass no options, copy_at_and_under pretends you've passed {}.
+.Sp
+This works by recursively building up the new tree from the leaves,
+duplicating nodes using \f(CW$orig_node\fR\->copy($options_ref) and then
+linking them up into a new tree of the same shape.
+.Sp
+Options you specify are passed down to calls to \f(CW$node\fR\->copy.
+.ie n .IP "the constructor $node\->copy or $node\->copy({...options...})" 4
+.el .IP "the constructor \f(CW$node\fR\->copy or \f(CW$node\fR\->copy({...options...})" 4
+.IX Item "the constructor $node->copy or $node->copy({...options...})"
+Returns a copy of \f(CW$node\fR, \fBminus\fR its daughter or mother attributes
+(which are set back to default values).
+.Sp
+If you pass no options, \f(CW\*(C`copy\*(C'\fR pretends you've passed {}.
+.Sp
+Magic happens with the 'attributes' attribute: if it's a hashref (and
+it usually is), the new node doesn't end up with the same hashref, but
+with ref to a hash with the content duplicated from the original's
+hashref. If 'attributes' is not a hashref, but instead an object that
+belongs to a class that provides a method called \*(L"copy\*(R", then that
+method is called, and the result saved in the clone's 'attribute'
+attribute. Both of these kinds of magic are disabled if the options
+you pass to \f(CW\*(C`copy\*(C'\fR (maybe via \f(CW\*(C`copy_tree\*(C'\fR, or \f(CW\*(C`copy_at_and_under\*(C'\fR)
+includes (\f(CW\*(C`no_attribute_copy\*(C'\fR => 1).
+.Sp
+The options hashref you pass to \f(CW\*(C`copy\*(C'\fR (derictly or indirectly) gets
+changed slightly after you call \f(CW\*(C`copy\*(C'\fR \*(-- it gets an entry called
+\&\*(L"from_to\*(R" added to it. Chances are you would never know nor care, but
+this is reserved for possible future use. See the source if you are
+wildly curious.
+.Sp
+Note that if you are using \f(CW$node\fR\->copy (whether directly or via
+\&\f(CW$node\fR\->copy_tree or \f(CW$node\fR\->copy_at_or_under), and it's not properly
+copying object attributes containing references, you probably
+shouldn't fight it or try to fix it \*(-- simply override copy_tree with:
+.Sp
+.Vb 6
+\& sub copy_tree {
+\& use Storable qw(dclone);
+\& my $this = $_[0];
+\& return dclone($this\->root);
+\& # d for "deep"
+\& }
+.Ve
+.Sp
+or
+.Sp
+.Vb 6
+\& sub copy_tree {
+\& use Data::Dumper;
+\& my $this = $_[0];
+\& $Data::Dumper::Purity = 1;
+\& return eval(Dumper($this\->root));
+\& }
+.Ve
+.Sp
+Both of these avoid you having to reinvent the wheel.
+.Sp
+How to override copy_at_or_under with something that uses Storable
+or Data::Dumper is left as an exercise to the reader.
+.Sp
+Consider that if in a derived class, you add attributes with really
+bizarre contents (like a unique-for-all-time-ID), you may need to
+override \f(CW\*(C`copy\*(C'\fR. Consider:
+.Sp
+.Vb 5
+\& sub copy {
+\& my($it, @etc) = @_;
+\& $it\->SUPER::copy(@etc);
+\& $it\->{\*(AqUID\*(Aq} = &get_new_UID;
+\& }
+.Ve
+.Sp
+\&...or the like. See the source of Tree::DAG_Node::copy for
+inspiration.
+.ie n .IP "$node\->delete_tree" 4
+.el .IP "\f(CW$node\fR\->delete_tree" 4
+.IX Item "$node->delete_tree"
+Destroys the entire tree that \f(CW$node\fR is a member of (starting at the
+root), by nulling out each node-object's attributes (including, most
+importantly, its linkage attributes \*(-- hopefully this is more than
+sufficient to eliminate all circularity in the data structure), and
+then moving it into the class \s-1DEADNODE\s0.
+.Sp
+Use this when you're finished with the tree in question, and want to
+free up its memory. (If you don't do this, it'll get freed up anyway
+when your program ends.)
+.Sp
+If you try calling any methods on any of the node objects in the tree
+you've destroyed, you'll get an error like:
+.Sp
+.Vb 2
+\& Can\*(Aqt locate object method "leaves_under"
+\& via package "DEADNODE".
+.Ve
+.Sp
+So if you see that, that's what you've done wrong. (Actually, the
+class \s-1DEADNODE\s0 does provide one method: a no-op method \*(L"delete_tree\*(R".
+So if you want to delete a tree, but think you may have deleted it
+already, it's safe to call \f(CW$node\fR\->delete_tree on it (again).)
+.Sp
+The \f(CW\*(C`delete_tree\*(C'\fR method is needed because Perl's garbage collector
+would never (as currently implemented) see that it was time to
+de-allocate the memory the tree uses \*(-- until either you call
+\&\f(CW$node\fR\->delete_tree, or until the program stops (at \*(L"global
+destruction\*(R" time, when \fBeverything\fR is unallocated).
+.Sp
+Incidentally, there are better ways to do garbage-collecting on a
+tree, ways which don't require the user to explicitly call a method
+like \f(CW\*(C`delete_tree\*(C'\fR \*(-- they involve dummy classes, as explained at
+\&\f(CW\*(C`http://mox.perl.com/misc/circle\-destroy.pod\*(C'\fR
+.Sp
+However, introducing a dummy class concept into Tree::DAG_Node would
+be rather a distraction. If you want to do this with your derived
+classes, via a \s-1DESTROY\s0 in a dummy class (or in a tree-metainformation
+class, maybe), then feel free to.
+.Sp
+The only case where I can imagine \f(CW\*(C`delete_tree\*(C'\fR failing to totally
+void the tree, is if you use the hashref in the \*(L"attributes\*(R" attribute
+to store (presumably among other things) references to other nodes'
+\&\*(L"attributes\*(R" hashrefs \*(-- which 1) is maybe a bit odd, and 2) is your
+problem, because it's your hash structure that's circular, not the
+tree's. Anyway, consider:
+.Sp
+.Vb 8
+\& # null out all my "attributes" hashes
+\& $anywhere\->root\->walk_down({
+\& \*(Aqcallback\*(Aq => sub {
+\& $hr = $_[0]\->attributes; %$hr = (); return 1;
+\& }
+\& });
+\& # And then:
+\& $anywhere\->delete_tree;
+.Ve
+.Sp
+(I suppose \f(CW\*(C`delete_tree\*(C'\fR is a \*(L"destructor\*(R", or as close as you can
+meaningfully come for a circularity-rich data structure in Perl.)
+.SS "When and How to Destroy"
+.IX Subsection "When and How to Destroy"
+It should be clear to you that if you've built a big parse tree or
+something, and then you're finished with it, you should call
+\&\f(CW$some_node\fR\->delete_tree on it if you want the memory back.
+.PP
+But consider this case: you've got this tree:
+.PP
+.Vb 5
+\& A
+\& / | \e
+\& B C D
+\& | | \e
+\& E X Y
+.Ve
+.PP
+Let's say you decide you don't want D or any of its descendants in the
+tree, so you call D\->unlink_from_mother. This does \s-1NOT\s0 automagically
+destroy the tree D\-X-Y. Instead it merely splits the tree into two:
+.PP
+.Vb 5
+\& A D
+\& / \e / \e
+\& B C X Y
+\& |
+\& E
+.Ve
+.PP
+To destroy D and its little tree, you have to explicitly call
+delete_tree on it.
+.PP
+Note, however, that if you call C\->unlink_from_mother, and if you don't
+have a link to C anywhere, then it \fBdoes\fR magically go away. This is
+because nothing links to C \*(-- whereas with the D\-X-Y tree, D links to
+X and Y, and X and Y each link back to D. Note that calling
+C\->delete_tree is harmless \*(-- after all, a tree of only one node is
+still a tree.
+.PP
+So, this is a surefire way of getting rid of all \f(CW$node\fR's children and
+freeing up the memory associated with them and their descendants:
+.PP
+.Vb 1
+\& foreach my $it ($node\->clear_daughters) { $it\->delete_tree }
+.Ve
+.PP
+Just be sure not to do this:
+.PP
+.Vb 2
+\& foreach my $it ($node\->daughters) { $it\->delete_tree }
+\& $node\->clear_daughters;
+.Ve
+.PP
+That's bad; the first call to \f(CW$_\fR\->delete_tree will climb to the root
+of \f(CW$node\fR's tree, and nuke the whole tree, not just the bits under \f(CW$node\fR.
+You might as well have just called \f(CW$node\fR\->delete_tree.
+(Moreavor, once \f(CW$node\fR is dead, you can't call clear_daughters on it,
+so you'll get an error there.)
+.SH "BUG REPORTS"
+.IX Header "BUG REPORTS"
+If you find a bug in this library, report it to me as soon as possible,
+at the address listed in the \s-1MAINTAINER\s0 section, below. Please try to
+be as specific as possible about how you got the bug to occur.
+.SH "HELP!"
+.IX Header "HELP!"
+If you develop a given routine for dealing with trees in some way, and
+use it a lot, then if you think it'd be of use to anyone else, do email
+me about it; it might be helpful to others to include that routine, or
+something based on it, in a later version of this module.
+.PP
+It's occurred to me that you might like to (and might yourself develop
+routines to) draw trees in something other than \s-1ASCII\s0 art. If you do so
+\&\*(-- say, for PostScript output, or for output interpretable by some
+external plotting program \*(-- I'd be most interested in the results.
+.SH "RAMBLINGS"
+.IX Header "RAMBLINGS"
+This module uses \*(L"strict\*(R", but I never wrote it with \-w warnings in
+mind \*(-- so if you use \-w, do not be surprised if you see complaints
+from the guts of DAG_Node. As long as there is no way to turn off \-w
+for a given module (instead of having to do it in every single
+subroutine with a \*(L"local $^W\*(R"), I'm not going to change this. However,
+I do, at points, get bursts of ambition, and I try to fix code in
+DAG_Node that generates warnings, \fIas I come across them\fR \*(-- which is
+only occasionally. Feel free to email me any patches for any such
+fixes you come up with, tho.
+.PP
+Currently I don't assume (or enforce) anything about the class
+membership of nodes being manipulated, other than by testing whether
+each one provides a method \f(CW\*(C`is_node\*(C'\fR, a la:
+.PP
+.Vb 1
+\& die "Not a node!!!" unless UNIVERSAL::can($node, "is_node");
+.Ve
+.PP
+So, as far as I'm concerned, a given tree's nodes are free to belong to
+different classes, just so long as they provide/inherit \f(CW\*(C`is_node\*(C'\fR, the
+few methods that this class relies on to navigate the tree, and have the
+same internal object structure, or a superset of it. Presumably this
+would be the case for any object belonging to a class derived from
+\&\f(CW\*(C`Tree::DAG_Node\*(C'\fR, or belonging to \f(CW\*(C`Tree::DAG_Node\*(C'\fR itself.
+.PP
+When routines in this class access a node's \*(L"mother\*(R" attribute, or its
+\&\*(L"daughters\*(R" attribute, they (generally) do so directly (via
+\&\f(CW$node\fR\->{'mother'}, etc.), for sake of efficiency. But classes derived
+from this class should probably do this instead thru a method (via
+\&\f(CW$node\fR\->mother, etc.), for sake of portability, abstraction, and general
+goodness.
+.PP
+However, no routines in this class (aside from, necessarily, \f(CW\*(C`_init\*(C'\fR,
+\&\f(CW\*(C`_init_name\*(C'\fR, and \f(CW\*(C`name\*(C'\fR) access the \*(L"name\*(R" attribute directly;
+routines (like the various tree draw/dump methods) get the \*(L"name\*(R" value
+thru a call to \f(CW$obj\fR\->\fIname()\fR. So if you want the object's name to not be
+a real attribute, but instead have it derived dynamically from some feature
+of the object (say, based on some of its other attributes, or based on
+its address), you can to override the \f(CW\*(C`name\*(C'\fR method, without causing
+problems. (Be sure to consider the case of \f(CW$obj\fR\->name as a write
+method, as it's used in \f(CW\*(C`lol_to_tree\*(C'\fR and \f(CW\*(C`random_network\*(C'\fR.)
+.SH "SEE ALSO"
+.IX Header "SEE ALSO"
+HTML::Element
+.PP
+Wirth, Niklaus. 1976. \fIAlgorithms + Data Structures = Programs\fR
+Prentice-Hall, Englewood Cliffs, \s-1NJ\s0.
+.PP
+Knuth, Donald Ervin. 1997. \fIArt of Computer Programming, Volume 1,
+Third Edition: Fundamental Algorithms\fR. Addison-Wesley, Reading, \s-1MA\s0.
+.PP
+Wirth's classic, currently and lamentably out of print, has a good
+section on trees. I find it clearer than Knuth's (if not quite as
+encyclopedic), probably because Wirth's example code is in a
+block-structured high-level language (basically Pascal), instead
+of in assembler (\s-1MIX\s0).
+.PP
+Until some kind publisher brings out a new printing of Wirth's book,
+try poking around used bookstores (or \f(CW\*(C`www.abebooks.com\*(C'\fR) for a copy.
+I think it was also republished in the 1980s under the title
+\&\fIAlgorithms and Data Structures\fR, and in a German edition called
+\&\fIAlgorithmen und Datenstrukturen\fR. (That is, I'm sure books by Knuth
+were published under those titles, but I'm \fIassuming\fR that they're just
+later printings/editions of \fIAlgorithms + Data Structures =
+Programs\fR.)
+.SH "MAINTAINER"
+.IX Header "MAINTAINER"
+David Hand, \f(CW\*(C`<cogent@cpan.org>\*(C'\fR
+.SH "AUTHOR"
+.IX Header "AUTHOR"
+Sean M. Burke, \f(CW\*(C`<sburke@cpan.org>\*(C'\fR
+.SH "COPYRIGHT, LICENSE, AND DISCLAIMER"
+.IX Header "COPYRIGHT, LICENSE, AND DISCLAIMER"
+Copyright 1998\-2001, 2004, 2007 by Sean M. Burke and David Hand.
+.PP
+This program is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+.PP
+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.