If I have a tree, I can use AbstractTrees.jl to iterate it. All I needed was to define
import AbstractTrees as AT
AT.children(n::MyNode) = ...
Great!
But often times I don’t have a tree and I don’t want to build it in memory. Instead I have an object that we could consider the tree root, and I have operations that I can do to mutate the object which lead me to other nodes. For motivation, imagine that you want to walk the tree in a board game: you don’t want to have a copy of the board for every position that you’re considering, you just want to be able to iterate thru the positions (so you can hash them and score them). Question: can I get AbstractTrees.jl to mutate my object instead of moving from node to node?
Reading the docs I learned about an object called a TreeCursor. A cursor is an object that ATs.jl uses internally to navigate a tree. According to the docs:
Tree iteration algorithms rely on
TreeCursor
objects. ATreeCursor
is a wrapper for a tree node which contains all information needed to navigate to other positions within the tree. They themselves are nodes of a tree with theStoredParents
andStoredSiblings
traits.
So I thought, maybe instead of building a tree and passing it into ATs.jl I can build a cursor directly, and pass that? From the docs all I need to do is, in addition to AT.children
also implement some traits plus the functions AT.parent
and AT.nextsibling
.
I’d like to hear from either someone who contributed to this library, or is experienced with it, whether this is a use-case (although not one covered by the documentation) or whether I’m missing something - and if the latter, is there a way to use ATs.jls if I don’t want to build a tree? The reason why I’m not super confident this idea might make sense is that, while the AT.parent
case works great (mutate my object to go up one level and then return itself), it’s not clear how the AT.children
would work - I could return an object with getindex
defined on it, but it’s not clear that ATs won’t do something that will break this - for example call AT.children
, make a copy, access the result to get one child node, call AT.nextsibling
on it, then access a different of element of its AT.children
copy.