Skip to main content

radiate_gp/collections/trees/
node.rs

1use super::TreeIterator;
2use crate::{Arity, Factory, NodeStore, NodeType, Tree, node::Node};
3use radiate_core::genome::{Gene, Valid};
4#[cfg(feature = "serde")]
5use serde::{Deserialize, Serialize};
6use std::{fmt::Debug, hash::Hash};
7
8/// A node in a tree structure that represents a single element with optional children.
9///
10/// The [TreeNode] struct is a fundamental building block for tree-based genetic programming in Radiate.
11/// It represents a node in a tree that can have zero or more child nodes, forming a hierarchical structure.
12/// Each node has a value of type T and maintains an optional list of child nodes.
13///
14/// # Type Parameters
15/// * `T` - The type of value stored in the node. This type must implement `Clone`, `PartialEq`, and other traits
16///   required by the genetic programming operations.
17///
18/// # Fields
19/// * `value` - The actual value stored in the node
20/// * `arity` - Optional Arity that specifies how many children the node can have
21/// * `children` - Optional vector of child nodes
22///
23/// # Examples
24/// ```
25/// use radiate_gp::{collections::{TreeNode}, Arity, Node};
26///
27/// // Create a new node with value 42
28/// let node = TreeNode::new(42);
29///
30/// // Create a node with specific arity
31/// let node_with_arity = TreeNode::with_arity(42, Arity::Exact(2));
32/// let other_node_with_arity = TreeNode::from((42, Arity::Exact(2)));
33///
34/// assert_eq!(node_with_arity.arity(), other_node_with_arity.arity());
35///
36/// // Create a node with children
37/// let node_with_children = TreeNode::with_children(42, vec![
38///     TreeNode::new(1),
39///     TreeNode::new(2)
40/// ]);
41/// let other_node_with_children = TreeNode::from((42, vec![
42///     TreeNode::new(1),
43///     TreeNode::new(2),
44/// ]));
45/// ```
46///
47/// # Node Types and [Arity]
48/// The node's type and arity determine its behavior and validity:
49/// * `Leaf` nodes have no children (arity is [Arity::Zero])
50/// * `Vertex` nodes can have any number of children (arity is [Arity::Any])
51/// * `Root` nodes are the starting point of the tree and can have any number of children
52///
53/// # Tree Operations
54/// The struct provides several methods for tree manipulation:
55/// * `new()` - Creates a new node with no children
56/// * `with_arity()` - Creates a node with a specific arity
57/// * `with_children()` - Creates a node with a list of children
58/// * `add_child()` - Adds a child to the node
59/// * `attach()` - Attaches a child and returns self for method chaining
60/// * `detach()` - Removes a child at a specific index
61/// * `swap_subtrees()` - Swaps subtrees between two nodes
62///
63/// # Tree Traversal
64/// The struct implements the [TreeIterator] trait, providing three traversal methods:
65/// * `iter_pre_order()` - Traverses the tree in pre-order (root, then children)
66/// * `iter_post_order()` - Traverses the tree in post-order (children, then root)
67/// * `iter_breadth_first()` - Traverses the tree level by level
68///
69/// # Tree Properties
70/// The struct provides methods to query tree properties:
71/// * `is_leaf()` - Checks if the node has no children - must have [Arity::Zero]
72/// * `size()` - Returns the total number of nodes in the subtree
73/// * `height()` - Returns the height of the subtree
74///
75/// # Validity
76/// A node is considered valid based on its arity:
77/// * Nodes with [Arity::Zero] must have no children
78/// * Nodes with [variant@Arity::Exact] must have exactly n children
79/// * Nodes with [Arity::Any] can have any number of children
80///
81/// # Implementation Details
82/// The struct implements several traits:
83/// * `Node` - Provides common node behavior and access to value and type information
84/// * `Gene` - Enables genetic operations for the node making it compatible with genetic algorithms
85/// * `Valid` - Defines validity rules for the node
86/// * `Debug` - Provides debug formatting
87/// * `Clone`, `PartialEq` - Required for genetic programming operations
88/// * `Format` - Provides pretty-printing of the tree structure
89///
90/// # Evaluation
91/// When `T` implements the `Eval` trait, the node can be evaluated with input data:
92/// ```rust
93/// use radiate_gp::{Op, Eval, TreeNode};
94///
95/// let tree = TreeNode::new(Op::add())
96///     .attach(TreeNode::new(Op::constant(2.0)))
97///     .attach(TreeNode::new(Op::constant(3.0)));
98///
99/// let result = tree.eval(&[]); // Evaluates to 5.0
100/// ```
101#[derive(PartialEq)]
102#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
103pub struct TreeNode<T> {
104    value: T,
105    arity: Option<Arity>,
106    children: Option<Vec<TreeNode<T>>>,
107}
108
109impl<T> TreeNode<T> {
110    pub fn new(val: T) -> Self {
111        TreeNode {
112            value: val,
113            arity: None,
114            children: None,
115        }
116    }
117
118    pub fn with_arity(val: T, arity: Arity) -> Self {
119        TreeNode {
120            value: val,
121            arity: Some(arity),
122            children: None,
123        }
124    }
125
126    pub fn with_children<N>(val: T, children: Vec<N>) -> Self
127    where
128        N: Into<TreeNode<T>>,
129    {
130        TreeNode {
131            value: val,
132            arity: None,
133            children: Some(children.into_iter().map(|n| n.into()).collect()),
134        }
135    }
136
137    pub fn is_leaf(&self) -> bool {
138        self.children.is_none()
139    }
140
141    pub fn add_child(&mut self, child: impl Into<TreeNode<T>>) {
142        let node = child.into();
143        if let Some(children) = self.children.as_mut() {
144            children.push(node);
145        } else {
146            self.children = Some(vec![node]);
147        }
148    }
149
150    pub fn attach(mut self, other: impl Into<TreeNode<T>>) -> Self {
151        self.add_child(other);
152        self
153    }
154
155    pub fn detach(&mut self, index: usize) -> Option<TreeNode<T>> {
156        if let Some(children) = self.children.as_mut()
157            && index < children.len()
158        {
159            return Some(children.remove(index));
160        }
161
162        None
163    }
164
165    pub fn children(&self) -> Option<&[TreeNode<T>]> {
166        self.children.as_deref()
167    }
168
169    pub fn children_mut(&mut self) -> Option<&mut Vec<TreeNode<T>>> {
170        self.children.as_mut()
171    }
172
173    pub fn take_children(&mut self) -> Option<Vec<TreeNode<T>>> {
174        self.children.take()
175    }
176
177    #[inline]
178    pub fn size(&self) -> usize {
179        if let Some(children) = self.children.as_ref() {
180            children.iter().fold(1, |acc, child| acc + child.size())
181        } else {
182            1
183        }
184    }
185
186    #[inline]
187    pub fn height(&self) -> usize {
188        if let Some(children) = self.children.as_ref() {
189            1 + children
190                .iter()
191                .map(|child| child.height())
192                .max()
193                .unwrap_or(0)
194        } else {
195            0
196        }
197    }
198
199    #[inline]
200    pub fn get_mut(&mut self, index: usize) -> Option<&mut TreeNode<T>> {
201        let mut cur = 0;
202        Self::get_mut_preorder(self, index, &mut cur)
203    }
204
205    #[inline]
206    fn get_mut_preorder<'a>(
207        node: &'a mut TreeNode<T>,
208        target: usize,
209        cur: &mut usize,
210    ) -> Option<&'a mut TreeNode<T>> {
211        if *cur == target {
212            return Some(node);
213        }
214
215        if let Some(children) = node.children_mut() {
216            for child in children {
217                *cur += 1;
218                if let Some(found) = Self::get_mut_preorder(child, target, cur) {
219                    return Some(found);
220                }
221            }
222        }
223
224        None
225    }
226}
227
228impl<T> Node for TreeNode<T> {
229    type Value = T;
230
231    fn value(&self) -> &Self::Value {
232        &self.value
233    }
234
235    fn value_mut(&mut self) -> &mut Self::Value {
236        &mut self.value
237    }
238
239    fn node_type(&self) -> NodeType {
240        if self.children.is_some() {
241            NodeType::Vertex
242        } else {
243            NodeType::Leaf
244        }
245    }
246
247    fn arity(&self) -> Arity {
248        if let Some(arity) = self.arity {
249            arity
250        } else if let Some(children) = self.children.as_ref() {
251            Arity::Exact(children.len())
252        } else {
253            match self.node_type() {
254                NodeType::Leaf => Arity::Zero,
255                NodeType::Vertex => Arity::Any,
256                NodeType::Root => Arity::Any,
257                _ => Arity::Zero,
258            }
259        }
260    }
261}
262
263impl<T> Gene for TreeNode<T>
264where
265    T: Clone + PartialEq,
266{
267    type Allele = T;
268
269    fn allele(&self) -> &Self::Allele {
270        &self.value
271    }
272
273    fn allele_mut(&mut self) -> &mut Self::Allele {
274        &mut self.value
275    }
276
277    fn new_instance(&self) -> Self {
278        TreeNode {
279            value: self.value.clone(),
280            arity: self.arity,
281            children: self.children.as_ref().map(|children| {
282                children
283                    .iter()
284                    .map(|child| child.new_instance())
285                    .collect::<Vec<TreeNode<T>>>()
286            }),
287        }
288    }
289
290    fn with_allele(&self, allele: &Self::Allele) -> Self {
291        TreeNode {
292            value: allele.clone(),
293            arity: self.arity,
294            children: self.children.as_ref().map(|children| children.to_vec()),
295        }
296    }
297}
298
299impl<T> Valid for TreeNode<T> {
300    fn is_valid(&self) -> bool {
301        for node in self.iter_breadth_first() {
302            match node.arity() {
303                Arity::Zero => return node.children.is_none(),
304                Arity::Exact(n) => {
305                    if node.children.is_none() || node.children.as_ref().unwrap().len() != n {
306                        return false;
307                    }
308                }
309                Arity::Any => {}
310            }
311        }
312
313        true
314    }
315}
316
317impl<T> Factory<(usize, Option<NodeStore<T>>), Option<TreeNode<T>>> for TreeNode<T>
318where
319    T: Clone + Default,
320{
321    fn new_instance(&self, (index, store): (usize, Option<NodeStore<T>>)) -> Option<TreeNode<T>> {
322        store.and_then(|store| Tree::with_depth(index, store).take_root())
323    }
324}
325
326impl<T: Clone> Clone for TreeNode<T> {
327    fn clone(&self) -> Self {
328        TreeNode {
329            value: self.value.clone(),
330            arity: self.arity,
331            children: self.children.as_ref().map(|children| children.to_vec()),
332        }
333    }
334}
335
336impl<T: Default> Default for TreeNode<T> {
337    fn default() -> Self {
338        TreeNode {
339            value: T::default(),
340            arity: None,
341            children: None,
342        }
343    }
344}
345
346impl<T: Hash> Hash for TreeNode<T> {
347    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
348        self.value.hash(state);
349        self.arity.hash(state);
350        if let Some(children) = self.children.as_ref() {
351            for child in children {
352                child.hash(state);
353            }
354        }
355    }
356}
357
358impl<T: Debug> Debug for TreeNode<T> {
359    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
360        write!(
361            f,
362            "{:>10?} :: {:<10} {:<12} C: {:?}",
363            format!("{:?}", self.node_type())[..3].to_owned(),
364            self.arity(),
365            format!("{:?}", self.value).to_owned(),
366            match &self.children {
367                Some(children) => children.len(),
368                None => 0,
369            },
370        )
371    }
372}
373
374impl<T> From<(T, Arity)> for TreeNode<T> {
375    fn from(value: (T, Arity)) -> Self {
376        TreeNode::with_arity(value.0, value.1)
377    }
378}
379
380impl<T> From<(T, Vec<TreeNode<T>>)> for TreeNode<T> {
381    fn from(value: (T, Vec<TreeNode<T>>)) -> Self {
382        TreeNode::with_children(value.0, value.1)
383    }
384}
385
386macro_rules! impl_from {
387    ($($t:ty),+) => {
388        $(
389            impl From<$t> for TreeNode<$t> {
390                fn from(value: $t) -> Self {
391                    TreeNode::new(value)
392                }
393            }
394        )+
395    };
396}
397
398impl_from!(
399    u8,
400    u16,
401    u32,
402    u64,
403    u128,
404    i8,
405    i16,
406    i32,
407    i64,
408    i128,
409    f32,
410    f64,
411    String,
412    bool,
413    char,
414    usize,
415    isize,
416    &'static str,
417    ()
418);
419
420impl<T> From<TreeNode<T>> for Vec<TreeNode<T>> {
421    fn from(node: TreeNode<T>) -> Self {
422        vec![node]
423    }
424}
425
426#[cfg(test)]
427mod tests {
428    use super::*;
429    use crate::{Arity, Eval, NodeType, Op};
430
431    #[test]
432    fn test_node_creation() {
433        let node = TreeNode::new(42);
434
435        assert_eq!(node.value(), &42);
436        assert!(node.is_leaf());
437        assert_eq!(node.arity(), Arity::Zero);
438        assert_eq!(node.node_type(), NodeType::Leaf);
439
440        let node = TreeNode::with_arity(42, Arity::Exact(2));
441
442        assert_eq!(node.value(), &42);
443        assert!(node.is_leaf());
444        assert_eq!(node.arity(), Arity::Exact(2));
445        assert_eq!(node.node_type(), NodeType::Leaf);
446
447        let node = TreeNode::with_children(42, vec![TreeNode::new(1), TreeNode::new(2)]);
448
449        assert_eq!(node.value(), &42);
450        assert!(!node.is_leaf());
451        assert_eq!(node.arity(), Arity::Exact(2));
452        assert_eq!(node.node_type(), NodeType::Vertex);
453    }
454
455    #[test]
456    fn test_node_manipulation() {
457        let mut node = TreeNode::new(42);
458        node.add_child(TreeNode::new(1));
459
460        assert!(!node.is_leaf());
461        assert_eq!(node.children().unwrap().len(), 1);
462        assert_eq!(node.children().unwrap()[0].value(), &1);
463
464        let node = TreeNode::new(42)
465            .attach(TreeNode::new(1))
466            .attach(TreeNode::new(2));
467
468        assert_eq!(node.children().unwrap().len(), 2);
469        assert_eq!(node.children().unwrap()[0].value(), &1);
470        assert_eq!(node.children().unwrap()[1].value(), &2);
471
472        let mut node = TreeNode::with_children(42, vec![TreeNode::new(1), TreeNode::new(2)]);
473        let detached = node.detach(0);
474
475        assert!(detached.is_some());
476        assert_eq!(detached.unwrap().value(), &1);
477        assert_eq!(node.children().unwrap().len(), 1);
478        assert_eq!(node.children().unwrap()[0].value(), &2);
479
480        assert!(node.detach(5).is_none());
481    }
482
483    #[test]
484    fn test_tree_properties() {
485        let node = TreeNode::new(42).attach(TreeNode::new(1)).attach(
486            TreeNode::new(2)
487                .attach(TreeNode::new(3))
488                .attach(TreeNode::new(4)),
489        );
490
491        assert_eq!(node.size(), 5);
492        assert_eq!(node.height(), 2);
493
494        let leaf = TreeNode::new(42);
495
496        assert_eq!(leaf.size(), 1);
497        assert_eq!(leaf.height(), 0);
498    }
499
500    #[test]
501    fn test_tree_traversal() {
502        // Create a tree:
503        //       42
504        //      /  \
505        //     1    2
506        //         / \
507        //        3   4
508        let node = TreeNode::new(42).attach(TreeNode::new(1)).attach(
509            TreeNode::new(2)
510                .attach(TreeNode::new(3))
511                .attach(TreeNode::new(4)),
512        );
513
514        let pre_order: Vec<i32> = node.iter_pre_order().map(|n| *n.value()).collect();
515        assert_eq!(pre_order, vec![42, 1, 2, 3, 4]);
516
517        let post_order: Vec<i32> = node.iter_post_order().map(|n| *n.value()).collect();
518        assert_eq!(post_order, vec![1, 3, 4, 2, 42]);
519
520        let bfs: Vec<i32> = node.iter_breadth_first().map(|n| *n.value()).collect();
521        assert_eq!(bfs, vec![42, 1, 2, 3, 4]);
522    }
523
524    #[test]
525    fn test_node_validity() {
526        let node = TreeNode::with_arity(42, Arity::Zero);
527        assert!(node.is_valid());
528
529        let mut node = TreeNode::with_arity(42, Arity::Zero);
530        node.add_child(TreeNode::new(1));
531        assert!(!node.is_valid());
532
533        let node = TreeNode::with_arity(42, Arity::Exact(2))
534            .attach(TreeNode::new(1))
535            .attach(TreeNode::new(2));
536        assert!(node.is_valid());
537
538        let mut node = TreeNode::with_arity(42, Arity::Exact(2));
539        node.add_child(TreeNode::new(1));
540        assert!(!node.is_valid());
541
542        let node = TreeNode::with_arity(42, Arity::Any)
543            .attach(TreeNode::new(1))
544            .attach(TreeNode::new(2))
545            .attach(TreeNode::new(3));
546        assert!(node.is_valid());
547    }
548
549    #[test]
550    fn test_node_evaluation() {
551        // Test simple arithmetic expression: (1 + 2) * 3
552        let node = TreeNode::new(Op::mul())
553            .attach(
554                TreeNode::new(Op::add())
555                    .attach(TreeNode::new(Op::constant(1.0)))
556                    .attach(TreeNode::new(Op::constant(2.0))),
557            )
558            .attach(TreeNode::new(Op::constant(3.0)));
559
560        let result = node.eval(&[]);
561        assert_eq!(result, 9.0);
562
563        // Test expression with variables: (x + 2) * 3
564        let node = TreeNode::new(Op::mul())
565            .attach(
566                TreeNode::new(Op::add())
567                    .attach(TreeNode::new(Op::var(0)))
568                    .attach(TreeNode::new(Op::constant(2.0))),
569            )
570            .attach(TreeNode::new(Op::constant(3.0)));
571
572        assert_eq!(node.eval(&[1.0]), 9.0);
573        assert_eq!(node.eval(&[2.0]), 12.0);
574        assert_eq!(node.eval(&[3.0]), 15.0);
575    }
576
577    #[test]
578    fn test_cloning_and_equality() {
579        let node1 = TreeNode::new(42)
580            .attach(TreeNode::new(1))
581            .attach(TreeNode::new(2));
582
583        let node2 = node1.clone();
584        assert_eq!(node1, node2);
585
586        let node3 = TreeNode::new(43)
587            .attach(TreeNode::new(1))
588            .attach(TreeNode::new(2));
589        assert_ne!(node1, node3);
590
591        let node4 = TreeNode::new(42).attach(TreeNode::new(1));
592        assert_ne!(node1, node4);
593    }
594
595    #[test]
596    #[cfg(feature = "serde")]
597    fn test_node_can_serialize() {
598        let root = TreeNode::new(42)
599            .attach(TreeNode::new(1))
600            .attach(
601                TreeNode::new(2)
602                    .attach(TreeNode::new(3))
603                    .attach(TreeNode::new(4)),
604            )
605            .attach(TreeNode::with_arity(3, Arity::Exact(2)));
606
607        let serialized = serde_json::to_string(&root).unwrap();
608        let deserialized: TreeNode<i32> = serde_json::from_str(&serialized).unwrap();
609
610        assert_eq!(root, deserialized);
611    }
612}