radiate_gp/collections/
factory.rs1use super::{GraphNode, NodeStore, NodeType, NodeValue, TreeNode};
2use crate::Arity;
3use radiate::random_provider;
4
5pub trait Factory<I, O> {
6 fn new_instance(&self, input: I) -> O;
7}
8
9impl<T> Factory<(), T> for NodeValue<T>
10where
11 T: Factory<(), T>,
12{
13 fn new_instance(&self, _: ()) -> T {
14 match self {
15 NodeValue::Bounded(value, _) => value.new_instance(()),
16 NodeValue::Unbound(value) => value.new_instance(()),
17 }
18 }
19}
20
21impl<T> Factory<NodeType, T> for NodeStore<T>
22where
23 T: Factory<(), T> + Default,
24{
25 fn new_instance(&self, input: NodeType) -> T {
26 let new_node = self.map_by_type(input, |values| {
27 random_provider::choose(&values).new_instance(())
28 });
29
30 if let Some(new_value) = new_node {
31 return new_value;
32 }
33
34 T::default()
35 }
36}
37
38impl<T: Default + Clone> Factory<(usize, NodeType), GraphNode<T>> for NodeStore<T> {
39 fn new_instance(&self, input: (usize, NodeType)) -> GraphNode<T> {
40 let (index, node_type) = input;
41
42 let new_node = self.map_by_type(node_type, |values| {
43 let node_value = match node_type {
44 NodeType::Input => &values[index % values.len()],
45 _ => random_provider::choose(&values),
46 };
47
48 match node_value {
49 NodeValue::Bounded(value, arity) => {
50 return (index, node_type, value.clone(), *arity).into();
51 }
52 NodeValue::Unbound(value) => {
53 return (index, node_type, value.clone()).into();
54 }
55 }
56 });
57
58 if let Some(new_value) = new_node {
59 return new_value;
60 }
61
62 GraphNode::new(index, node_type, T::default())
63 }
64}
65
66impl<T, F> Factory<(usize, NodeType, F), GraphNode<T>> for NodeStore<T>
67where
68 T: Default + Clone,
69 F: Fn(Arity) -> bool,
70{
71 fn new_instance(&self, input: (usize, NodeType, F)) -> GraphNode<T> {
72 let (index, node_type, filter) = input;
73 let new_node = self.map(|values| {
74 let mapped_values = values
75 .into_iter()
76 .filter(|value| match value {
77 NodeValue::Bounded(_, arity) => filter(*arity),
78 _ => false,
79 })
80 .collect::<Vec<&NodeValue<T>>>();
81
82 let node_value = random_provider::choose(&mapped_values);
83
84 match node_value {
85 NodeValue::Bounded(value, arity) => {
86 return GraphNode::with_arity(index, node_type, value.clone(), *arity);
87 }
88 NodeValue::Unbound(value) => {
89 return GraphNode::new(index, node_type, value.clone());
90 }
91 }
92 });
93
94 if let Some(new_value) = new_node {
95 return new_value;
96 }
97
98 GraphNode::new(index, node_type, T::default())
99 }
100}
101
102impl<T: Clone + Default> Factory<NodeType, TreeNode<T>> for NodeStore<T> {
103 fn new_instance(&self, input: NodeType) -> TreeNode<T> {
104 let new_node = self.map_by_type(input, |values| {
105 let node_value = random_provider::choose(&values);
106
107 match node_value {
108 NodeValue::Bounded(value, arity) => {
109 return TreeNode::with_arity(value.clone(), *arity);
110 }
111 NodeValue::Unbound(value) => {
112 return TreeNode::new(value.clone());
113 }
114 }
115 });
116
117 if let Some(new_value) = new_node {
118 return new_value;
119 }
120
121 TreeNode::new(T::default())
122 }
123}