@@ -84,8 +84,72 @@ You can create a copy of a node with `copy_node`:
8484copy_node(tree::Node)
8585```
8686
87- There is also an abstract type ` AbstractNode ` which is a supertype of ` Node ` :
87+ ## Graph-Like Equations
88+
89+ You can describe an equation as a * graph* rather than a tree
90+ by using the ` GraphNode ` type:
91+
92+ ``` @docs
93+ GraphNode{T}
94+ ```
95+
96+ This makes it so you can have multiple parents for a given node,
97+ and share parts of an expression. For example:
98+
99+ ``` julia
100+ julia> operators = OperatorEnum (;
101+ binary_operators= [+ , - , * ], unary_operators= [cos, sin, exp]
102+ );
103+
104+ julia> x1, x2 = GraphNode (feature= 1 ), GraphNode (feature= 2 )
105+ (x1, x2)
106+
107+ julia> y = sin (x1) + 1.5
108+ sin (x1) + 1.5
109+
110+ julia> z = exp (y) + y
111+ exp (sin (x1) + 1.5 ) + {(sin (x1) + 1.5 )}
112+ ```
113+
114+ Here, the curly braces ` {} ` indicate that the node
115+ is shared by another (or more) parent node.
116+
117+ This means that we only need to change it once
118+ to have changes propagate across the expression:
119+
120+ ``` julia
121+ julia> y. r. val *= 0.9
122+ 1.35
123+
124+ julia> z
125+ exp (sin (x1) + 1.35 ) + {(sin (x1) + 1.35 )}
126+ ```
127+
128+ This also means there are fewer nodes to describe an expression:
129+
130+ ``` julia
131+ julia> length (z)
132+ 6
133+
134+ julia> length (convert (Node, z))
135+ 10
136+ ```
137+
138+ where we have converted the ` GraphNode ` to a ` Node ` type,
139+ which breaks shared connections into separate nodes.
140+
141+ ## Abstract Types
142+
143+ Both the ` Node ` and ` GraphNode ` types are subtypes of the abstract type:
144+
145+ ``` @docs
146+ AbstractExpressionNode{T}
147+ ```
148+
149+ which can be used to create additional expression-like types.
150+ The supertype of this abstract type is the ` AbstractNode ` type,
151+ which is more generic but does not have all of the same methods:
88152
89153``` @docs
90- AbstractNode
154+ AbstractNode{T}
91155```
0 commit comments