Skip to content

Commit 981e3b0

Browse files
committed
docs: describe generic getters and setters
1 parent f16af83 commit 981e3b0

File tree

3 files changed

+73
-5
lines changed

3 files changed

+73
-5
lines changed

docs/src/api.md

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,42 @@ You can create a copy of a node with `copy_node`:
7575
copy_node
7676
```
7777

78+
## Generic Node Accessors
79+
80+
For working with nodes of arbitrary arity:
81+
82+
```@docs
83+
get_child
84+
set_child!
85+
get_children
86+
set_children!
87+
```
88+
89+
Examples:
90+
91+
```julia
92+
# Define operators including ternary
93+
my_ternary(x, y, z) = x + y * z
94+
operators = OperatorEnum(((sin,), (+, *), (my_ternary,))) # (unary, binary, ternary)
95+
96+
tree = Node{Float64,3}(; op=1, children=(Node{Float64,3}(; val=1.0), Node{Float64,3}(; val=2.0)))
97+
new_child = Node{Float64,3}(; val=3.0)
98+
99+
left_child = get_child(tree, 1)
100+
right_child = get_child(tree, 2)
101+
102+
set_child!(tree, new_child, 1)
103+
104+
children = get_children(tree)
105+
left, right = get_children(tree, Val(2)) # type stable
106+
107+
# Transform to ternary operation
108+
child1, child2, child3 = Node{Float64,3}(; val=4.0), Node{Float64,3}(; val=5.0), Node{Float64,3}(; val=6.0)
109+
set_children!(tree, (child1, child2, child3))
110+
tree.op = 1 # my_ternary
111+
tree.degree = 3
112+
```
113+
78114
## Graph Nodes
79115

80116
You can describe an equation as a *graph* rather than a tree
@@ -109,7 +145,7 @@ This means that we only need to change it once
109145
to have changes propagate across the expression:
110146

111147
```julia
112-
julia> y.r.val *= 0.9
148+
julia> get_child(y, 2).val *= 0.9
113149
1.35
114150

115151
julia> z

src/Node.jl

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,9 @@ nodes, you can evaluate or print a given expression.
117117
object. Only defined if `degree >= 1`
118118
- `children::NTuple{D,Node{T,D}}`: Children of the node. Only defined up to `degree`
119119
120+
For accessing and modifying children, use [`get_child`](@ref), [`set_child!`](@ref),
121+
[`get_children`](@ref), and [`set_children!`](@ref).
122+
120123
# Constructors
121124
122125
@@ -188,17 +191,46 @@ end
188191
@inline function get_children(node::AbstractNode)
189192
return getfield(node, :children)
190193
end
194+
195+
"""
196+
get_children(node::AbstractNode)
197+
get_children(node::AbstractNode, ::Val{n})
198+
199+
Return the children tuple of a node. The first form returns the complete children tuple as stored.
200+
The second form returns a tuple of exactly `n` children, useful for type stability when the
201+
number of children needed is known at compile time.
202+
"""
191203
@inline function get_children(node::AbstractNode, ::Val{n}) where {n}
192204
cs = get_children(node)
193205
return ntuple(i -> cs[i], Val(Int(n)))
194206
end
207+
208+
"""
209+
get_child(node::AbstractNode, i::Integer)
210+
211+
Return the `i`-th child of a node (1-indexed).
212+
"""
195213
@inline function get_child(n::AbstractNode{D}, i::Int) where {D}
196214
return get_children(n)[i]
197215
end
216+
217+
"""
218+
set_child!(node::AbstractNode, child::AbstractNode, i::Integer)
219+
220+
Replace the `i`-th child of a node (1-indexed) with the given child node.
221+
Returns the new child. Updates the children tuple in-place.
222+
"""
198223
@inline function set_child!(n::AbstractNode{D}, child::AbstractNode{D}, i::Int) where {D}
199224
set_children!(n, Base.setindex(get_children(n), child, i))
200225
return child
201226
end
227+
228+
"""
229+
set_children!(node::AbstractNode, children::Tuple)
230+
231+
Replace all children of a node with the given tuple. If fewer children are
232+
provided than the node's maximum degree, remaining slots are filled with poison nodes.
233+
"""
202234
@inline function set_children!(n::AbstractNode{D}, children::Union{Tuple,AbstractVector{<:AbstractNode{D}}}) where {D}
203235
D2 = length(children)
204236
if D === D2

src/Simplify.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,15 +74,15 @@ function combine_operators(tree::Node{T,2}, operators::AbstractOperatorEnum) whe
7474
#(const - (const - var)) => (var - const)
7575
l = get_child(tree, 1)
7676
r = get_child(tree, 2)
77-
simplified_const = (get_child(r, 1).val - l.val) #neg(sub(l.val, r.l.val))
77+
simplified_const = (get_child(r, 1).val - l.val) #neg(sub(l.val, get_child(r, 1).val))
7878
set_child!(tree, get_child(get_child(tree, 2), 2), 1)
7979
set_child!(tree, l, 2)
8080
get_child(tree, 2).val = simplified_const
8181
elseif is_node_constant(get_child(get_child(tree, 2), 2))
8282
#(const - (var - const)) => (const - var)
8383
l = get_child(tree, 1)
8484
r = get_child(tree, 2)
85-
simplified_const = l.val + get_child(r, 2).val #plus(l.val, r.r.val)
85+
simplified_const = l.val + get_child(r, 2).val #plus(l.val, get_child(r, 2).val)
8686
set_child!(tree, get_child(get_child(tree, 2), 1), 2)
8787
get_child(tree, 1).val = simplified_const
8888
end
@@ -93,15 +93,15 @@ function combine_operators(tree::Node{T,2}, operators::AbstractOperatorEnum) whe
9393
#((const - var) - const) => (const - var)
9494
l = get_child(tree, 1)
9595
r = get_child(tree, 2)
96-
simplified_const = get_child(l, 1).val - r.val#sub(l.l.val, r.val)
96+
simplified_const = get_child(l, 1).val - r.val#sub(get_child(l, 1).val, r.val)
9797
set_child!(tree, get_child(get_child(tree, 1), 2), 2)
9898
set_child!(tree, r, 1)
9999
get_child(tree, 1).val = simplified_const
100100
elseif is_node_constant(get_child(get_child(tree, 1), 2))
101101
#((var - const) - const) => (var - const)
102102
l = get_child(tree, 1)
103103
r = get_child(tree, 2)
104-
simplified_const = r.val + get_child(l, 2).val #plus(r.val, l.r.val)
104+
simplified_const = r.val + get_child(l, 2).val #plus(r.val, get_child(l, 2).val)
105105
set_child!(tree, get_child(get_child(tree, 1), 1), 1)
106106
get_child(tree, 2).val = simplified_const
107107
end

0 commit comments

Comments
 (0)