1use super::transaction::TransactionResult;
2use crate::collections::graphs::GraphTransaction;
3use crate::collections::{Direction, GraphNode};
4use crate::{GraphIterator, NodeType};
5use radiate_core::Valid;
6#[cfg(feature = "serde")]
7use serde::{Deserialize, Serialize};
8use std::collections::HashSet;
9use std::fmt::Debug;
10use std::hash::Hash;
11use std::ops::{Index, IndexMut};
12
13#[derive(Clone, PartialEq)]
140#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
141pub struct Graph<T> {
142 nodes: Vec<GraphNode<T>>,
143}
144
145impl<T> Graph<T> {
146 pub fn new(nodes: Vec<GraphNode<T>>) -> Self {
151 Graph { nodes }
152 }
153
154 pub fn take_nodes(&mut self) -> Vec<GraphNode<T>> {
155 std::mem::take(&mut self.nodes)
156 }
157
158 pub fn push(&mut self, node: impl Into<GraphNode<T>>) {
159 self.nodes.push(node.into());
160 }
161
162 pub fn insert(&mut self, node_type: NodeType, val: T) -> usize {
163 self.push((self.len(), node_type, val));
164 self.len() - 1
165 }
166
167 pub fn pop(&mut self) -> Option<GraphNode<T>> {
168 self.nodes.pop()
169 }
170
171 pub fn len(&self) -> usize {
172 self.nodes.len()
173 }
174
175 pub fn is_empty(&self) -> bool {
176 self.nodes.is_empty()
177 }
178
179 pub fn get_mut(&mut self, index: usize) -> Option<&mut GraphNode<T>> {
180 self.nodes.get_mut(index)
181 }
182
183 pub fn get(&self, index: usize) -> Option<&GraphNode<T>> {
184 self.nodes.get(index)
185 }
186
187 pub fn iter(&self) -> impl Iterator<Item = &GraphNode<T>> {
188 self.nodes.iter()
189 }
190
191 pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut GraphNode<T>> {
192 self.nodes.iter_mut()
193 }
194
195 pub fn inputs(&self) -> impl Iterator<Item = &GraphNode<T>> {
196 self.get_nodes_of_type(NodeType::Input)
197 }
198
199 pub fn outputs(&self) -> impl Iterator<Item = &GraphNode<T>> {
200 self.get_nodes_of_type(NodeType::Output)
201 }
202
203 pub fn vertices(&self) -> impl Iterator<Item = &GraphNode<T>> {
204 self.get_nodes_of_type(NodeType::Vertex)
205 }
206
207 pub fn edges(&self) -> impl Iterator<Item = &GraphNode<T>> {
208 self.get_nodes_of_type(NodeType::Edge)
209 }
210
211 pub fn attach(&mut self, incoming: usize, outgoing: usize) -> &mut Self {
229 self.as_mut()[incoming].insert_outgoing(outgoing);
230 self.as_mut()[outgoing].insert_incoming(incoming);
231 self
232 }
233 pub fn detach(&mut self, incoming: usize, outgoing: usize) -> &mut Self {
242 self.as_mut()[incoming].remove_outgoing(&outgoing);
243 self.as_mut()[outgoing].remove_incoming(&incoming);
244 self
245 }
246
247 #[inline]
254 pub fn try_modify<F>(&mut self, mutation: F) -> TransactionResult<T>
255 where
256 F: FnOnce(GraphTransaction<T>) -> TransactionResult<T>,
257 T: Clone,
258 {
259 mutation(GraphTransaction::new(self))
260 }
261
262 #[inline]
267 pub fn set_cycles(&mut self, indecies: Vec<usize>) {
268 if indecies.is_empty() {
269 let all_indices = self
270 .as_ref()
271 .iter()
272 .map(|node| node.index())
273 .collect::<Vec<usize>>();
274
275 return self.set_cycles(all_indices);
276 }
277
278 for idx in indecies {
279 let cycles = self.get_cycles(idx);
280
281 if cycles.is_empty() {
282 if let Some(node) = self.get_mut(idx) {
283 node.set_direction(Direction::Forward);
284 }
285 } else {
286 for cycle in cycles {
287 if let Some(node) = self.get_mut(cycle) {
288 node.set_direction(Direction::Backward);
289 }
290 }
291 }
292 }
293 }
294
295 #[inline]
300 pub fn get_cycles(&self, from: usize) -> std::collections::HashSet<usize> {
301 let n = self.len();
302 let mut on_stack = vec![false; n];
303 let mut visited = vec![false; n];
304 let mut cycles = vec![false; n];
305 let mut stack = Vec::with_capacity(n.min(64));
306
307 fn dfs<T>(
308 g: &Graph<T>,
309 u: usize,
310 visited: &mut [bool],
311 on_stack: &mut [bool],
312 cycles: &mut [bool],
313 stack: &mut Vec<usize>,
314 ) {
315 visited[u] = true;
316 on_stack[u] = true;
317 stack.push(u);
318
319 for &v in g.get(u).unwrap().outgoing() {
320 if !visited[v] {
321 dfs(g, v, visited, on_stack, cycles, stack);
322 } else if on_stack[v] {
323 let start = stack.iter().rposition(|&x| x == v).unwrap();
324 for &w in &stack[start..] {
325 cycles[w] = true;
326 }
327 }
328 }
329
330 stack.pop();
331 on_stack[u] = false;
332 }
333
334 dfs(
335 self,
336 from,
337 &mut visited,
338 &mut on_stack,
339 &mut cycles,
340 &mut stack,
341 );
342
343 let mut out = HashSet::with_capacity(stack.len());
344 for (i, &c) in cycles.iter().enumerate() {
345 if c {
346 out.insert(i);
347 }
348 }
349 out
350 }
351}
352
353impl<T> Valid for Graph<T> {
354 #[inline]
355 fn is_valid(&self) -> bool {
356 self.iter().all(|node| node.is_valid())
357 }
358}
359
360impl<T> AsRef<[GraphNode<T>]> for Graph<T> {
361 fn as_ref(&self) -> &[GraphNode<T>] {
362 &self.nodes
363 }
364}
365
366impl<T> AsMut<[GraphNode<T>]> for Graph<T> {
367 fn as_mut(&mut self) -> &mut [GraphNode<T>] {
368 &mut self.nodes
369 }
370}
371
372impl<T> Index<usize> for Graph<T> {
373 type Output = GraphNode<T>;
374
375 fn index(&self, index: usize) -> &Self::Output {
376 &self.nodes[index]
377 }
378}
379
380impl<T> IndexMut<usize> for Graph<T> {
381 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
382 &mut self.nodes[index]
383 }
384}
385
386impl<T> IntoIterator for Graph<T> {
387 type Item = GraphNode<T>;
388 type IntoIter = std::vec::IntoIter<GraphNode<T>>;
389
390 fn into_iter(self) -> Self::IntoIter {
391 self.nodes.into_iter()
392 }
393}
394
395impl<T> FromIterator<GraphNode<T>> for Graph<T> {
396 fn from_iter<I: IntoIterator<Item = GraphNode<T>>>(iter: I) -> Self {
397 Graph {
398 nodes: iter.into_iter().collect(),
399 }
400 }
401}
402
403impl<T> Default for Graph<T> {
404 fn default() -> Self {
405 Graph { nodes: Vec::new() }
406 }
407}
408
409impl<T: Hash> Hash for Graph<T> {
410 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
411 for node in self.as_ref() {
412 node.hash(state);
413 }
414 }
415}
416
417impl<T: Debug> Debug for Graph<T> {
418 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
419 writeln!(f, "Graph {{")?;
420 for node in self.as_ref() {
421 writeln!(f, " {:?},", node)?;
422 }
423 write!(f, "}}")
424 }
425}
426
427#[cfg(test)]
428mod test {
429 use super::*;
430 use crate::{Arity, Node, Op};
431
432 #[test]
433 fn test_graph_is_valid() {
434 let mut graph_one = Graph::default();
435 graph_one.push((0, NodeType::Input, 123));
436 graph_one.push((1, NodeType::Output, 42));
437 graph_one.attach(0, 1);
438
439 let mut graph_two = Graph::default();
440 graph_two.push((0, NodeType::Input, 0));
441 graph_two.push((1, NodeType::Vertex, 1));
442
443 assert!(graph_one.is_valid());
444 assert!(!graph_two.is_valid());
445 }
446
447 #[test]
448 fn test_graph_attach() {
449 let mut graph = Graph::default();
450 graph.push((0, NodeType::Input, 0));
451 graph.push((1, NodeType::Output, 1));
452 graph.attach(0, 1);
453
454 assert_eq!(graph[0].outgoing(), &[1]);
455 assert_eq!(graph[1].incoming(), &[0]);
456 }
457
458 #[test]
459 fn test_graph_node_creations() {
460 let mut graph_one = Graph::from_iter(vec![
461 GraphNode::new(0, NodeType::Input, 0),
462 GraphNode::new(1, NodeType::Vertex, 1),
463 GraphNode::new(2, NodeType::Output, 1),
464 ]);
465
466 graph_one.attach(0, 1).attach(1, 2);
467
468 assert_eq!(graph_one.len(), 3);
469 assert!(graph_one.is_valid());
470 assert_eq!(graph_one[0].arity(), Arity::Zero);
471 assert_eq!(graph_one[1].arity(), Arity::Any);
472 assert_eq!(graph_one[2].arity(), Arity::Any);
473
474 let mut graph_two = Graph::new(vec![
475 GraphNode::new(0, NodeType::Input, Op::var(0)),
476 GraphNode::new(1, NodeType::Input, Op::constant(5.0)),
477 GraphNode::with_arity(2, NodeType::Vertex, Op::add(), Arity::Exact(2)),
478 GraphNode::new(3, NodeType::Output, Op::linear()),
479 ]);
480
481 graph_two.attach(0, 2).attach(1, 2).attach(2, 3);
482
483 assert_eq!(graph_two.len(), 4);
484 assert!(graph_two.is_valid());
485 assert_eq!(graph_two[0].arity(), Arity::Zero);
486 assert_eq!(graph_two[1].arity(), Arity::Zero);
487 assert_eq!(graph_two[2].arity(), Arity::Exact(2));
488 assert_eq!(graph_two[3].arity(), Arity::Any);
489 }
490
491 #[test]
492 fn test_simple_graph() {
493 let mut graph = Graph::<i32>::default();
494
495 let idx_one = graph.insert(NodeType::Input, 0);
496 let idx_two = graph.insert(NodeType::Vertex, 1);
497 let idx_three = graph.insert(NodeType::Output, 2);
498
499 graph.attach(idx_one, idx_two).attach(idx_two, idx_three);
500
501 assert_eq!(graph.len(), 3);
502
503 assert!(graph.is_valid());
504 assert!(graph[0].is_valid());
505 assert!(graph[1].is_valid());
506 assert!(graph[2].is_valid());
507
508 assert_eq!(graph[0].incoming().len(), 0);
509 assert_eq!(graph[0].outgoing().len(), 1);
510 assert_eq!(graph[1].incoming().len(), 1);
511 assert_eq!(graph[1].outgoing().len(), 1);
512 assert_eq!(graph[2].incoming().len(), 1);
513 assert_eq!(graph[2].outgoing().len(), 0);
514 }
515
516 #[test]
517 fn test_graph_with_cycles() {
518 let mut graph = Graph::<i32>::default();
519
520 graph.insert(NodeType::Input, 0);
521 graph.insert(NodeType::Vertex, 1);
522 graph.insert(NodeType::Vertex, 2);
523 graph.insert(NodeType::Output, 3);
524
525 graph.attach(0, 1).attach(1, 2).attach(2, 1).attach(2, 3);
526
527 assert_eq!(graph.len(), 4);
528
529 assert!(graph.is_valid());
530 assert!(graph[0].is_valid());
531 assert!(graph[1].is_valid());
532 assert!(graph[2].is_valid());
533 assert!(graph[3].is_valid());
534
535 assert_eq!(graph[0].incoming().len(), 0);
536 assert_eq!(graph[0].outgoing().len(), 1);
537 assert_eq!(graph[1].incoming().len(), 2);
538 assert_eq!(graph[1].outgoing().len(), 1);
539 assert_eq!(graph[2].incoming().len(), 1);
540 assert_eq!(graph[2].outgoing().len(), 2);
541 assert_eq!(graph[3].incoming().len(), 1);
542 assert_eq!(graph[3].outgoing().len(), 0);
543 }
544
545 #[test]
546 fn test_graph_with_cycles_and_recurrent_nodes() {
547 let mut graph = Graph::<i32>::default();
548
549 let idx_one = graph.insert(NodeType::Input, 0);
550 let idx_two = graph.insert(NodeType::Vertex, 1);
551 let idx_three = graph.insert(NodeType::Vertex, 2);
552 let idx_four = graph.insert(NodeType::Output, 3);
553
554 graph
555 .attach(idx_one, idx_two)
556 .attach(idx_two, idx_three)
557 .attach(idx_three, idx_two)
558 .attach(idx_three, idx_four)
559 .attach(idx_four, idx_two);
560
561 graph.set_cycles(vec![]);
562
563 assert_eq!(graph.len(), 4);
564
565 assert!(graph.is_valid());
566 assert!(graph[0].is_valid());
567 assert!(graph[1].is_valid());
568 assert!(graph[2].is_valid());
569 assert!(graph[3].is_valid());
570
571 assert_eq!(graph[0].incoming().len(), 0);
572 assert_eq!(graph[0].outgoing().len(), 1);
573 assert_eq!(graph[1].incoming().len(), 3);
574 assert_eq!(graph[1].outgoing().len(), 1);
575 assert_eq!(graph[2].incoming().len(), 1);
576 assert_eq!(graph[2].outgoing().len(), 2);
577 assert_eq!(graph[3].incoming().len(), 1);
578 assert_eq!(graph[3].outgoing().len(), 1);
579
580 assert_eq!(graph[0].direction(), Direction::Forward);
581 assert_eq!(graph[1].direction(), Direction::Backward);
582 assert_eq!(graph[2].direction(), Direction::Backward);
583 assert_eq!(graph[3].direction(), Direction::Backward);
584 }
585
586 #[test]
587 fn test_graph_set_cycles() {
588 let mut graph = Graph::<i32>::default();
589
590 let idx_one = graph.insert(NodeType::Input, 0);
591 let idx_two = graph.insert(NodeType::Vertex, 1);
592 let idx_three = graph.insert(NodeType::Vertex, 2);
593 let idx_four = graph.insert(NodeType::Output, 3);
594
595 graph
596 .attach(idx_one, idx_two)
597 .attach(idx_two, idx_three)
598 .attach(idx_three, idx_two)
599 .attach(idx_two, idx_four);
600
601 for node in graph.iter() {
602 assert!(node.is_valid());
603 assert_eq!(node.direction(), Direction::Forward);
604 }
605
606 graph.set_cycles(vec![]);
607
608 for node in graph.iter() {
609 assert!(node.is_valid());
610 if node.node_type() == NodeType::Vertex {
611 assert_eq!(node.direction(), Direction::Backward);
612 } else {
613 assert_eq!(node.direction(), Direction::Forward);
614 }
615 }
616 }
617
618 #[test]
619 fn test_graph_clone_and_partial_eq() {
620 let mut graph1 = Graph::default();
621 let input_idx = graph1.insert(NodeType::Input, 42);
622 let output_idx = graph1.insert(NodeType::Output, 24);
623 graph1.attach(input_idx, output_idx);
624
625 let graph2 = graph1.clone();
626 assert_eq!(graph1, graph2);
627
628 let mut graph3 = graph1.clone();
629 graph3[input_idx].set_direction(Direction::Backward);
630 assert_ne!(graph1, graph3);
631
632 let mut graph4 = graph1.clone();
633 if let Some(node) = graph4.get_mut(input_idx) {
634 *node.value_mut() = 100;
635 }
636 assert_ne!(graph1, graph4);
637 }
638
639 #[test]
640 fn test_graph_arity_validation() {
641 let mut graph = Graph::default();
642 let input_idx = graph.insert(NodeType::Input, 0);
643 graph.push((1, NodeType::Vertex, 1, Arity::Exact(2)));
644 let output_idx = graph.insert(NodeType::Output, 2);
645
646 graph.attach(input_idx, 1);
647 graph.attach(1, output_idx);
648
649 assert!(!graph.is_valid());
651
652 graph.attach(input_idx, 1);
655 assert!(!graph.is_valid());
656
657 let input3_idx = graph.insert(NodeType::Input, 3);
659 graph.attach(input3_idx, 1);
660 println!("{:?}", graph);
661 assert!(graph.is_valid());
662 }
663
664 #[test]
665 fn test_graph_indexing() {
666 let mut graph = Graph::default();
667 let input_idx = graph.insert(NodeType::Input, 42);
668 let output_idx = graph.insert(NodeType::Output, 24);
669
670 assert_eq!(graph[input_idx].value(), &42);
672 assert_eq!(graph[output_idx].value(), &24);
673
674 graph[input_idx].set_direction(Direction::Backward);
676 assert_eq!(graph[input_idx].direction(), Direction::Backward);
677
678 assert_eq!(graph.get(input_idx).unwrap().value(), &42);
680 assert_eq!(graph.get_mut(output_idx).unwrap().value(), &24);
681
682 assert!(graph.get(999).is_none());
684 assert!(graph.get_mut(999).is_none());
685 }
686
687 #[test]
688 fn test_graph_node_type_queries() {
689 let mut graph = Graph::default();
690 graph.insert(NodeType::Input, 0);
691 graph.insert(NodeType::Input, 1);
692 graph.insert(NodeType::Vertex, 2);
693 graph.insert(NodeType::Vertex, 3);
694 graph.insert(NodeType::Output, 4);
695 graph.insert(NodeType::Output, 5);
696
697 let inputs = graph.inputs().collect::<Vec<_>>();
699 assert_eq!(inputs.len(), 2);
700 assert!(
701 inputs
702 .iter()
703 .all(|node| node.node_type() == NodeType::Input)
704 );
705
706 let vertices = graph.vertices().collect::<Vec<_>>();
708 assert_eq!(vertices.len(), 2);
709 assert!(
710 vertices
711 .iter()
712 .all(|node| node.node_type() == NodeType::Vertex)
713 );
714
715 let outputs = graph.outputs().collect::<Vec<_>>();
717 assert_eq!(outputs.len(), 2);
718 assert!(
719 outputs
720 .iter()
721 .all(|node| node.node_type() == NodeType::Output)
722 );
723 }
724
725 #[test]
726 fn test_graph_iterators() {
727 let mut graph = Graph::default();
728 let input_idx = graph.insert(NodeType::Input, 0);
729 let vertex_idx = graph.insert(NodeType::Vertex, 1);
730 let output_idx = graph.insert(NodeType::Output, 2);
731
732 graph.attach(input_idx, vertex_idx);
733 graph.attach(vertex_idx, output_idx);
734
735 let nodes: Vec<_> = graph.iter().collect();
737 assert_eq!(nodes.len(), 3);
738 assert_eq!(nodes[0].value(), &0);
739 assert_eq!(nodes[1].value(), &1);
740 assert_eq!(nodes[2].value(), &2);
741
742 for node in graph.iter_mut() {
744 if node.node_type() == NodeType::Vertex {
745 node.set_direction(Direction::Backward);
746 }
747 }
748 assert_eq!(graph[vertex_idx].direction(), Direction::Backward);
749
750 let values: Vec<_> = graph.into_iter().map(|node| *node.value()).collect();
752 assert_eq!(values, vec![0, 1, 2]);
753 }
754
755 #[test]
756 fn test_graph_detach() {
757 let mut graph = Graph::default();
758 let input_idx = graph.insert(NodeType::Input, 0);
759 let output_idx = graph.insert(NodeType::Output, 1);
760
761 graph.attach(input_idx, output_idx);
763 assert!(graph[input_idx].outgoing().contains(&output_idx));
764 assert!(graph[output_idx].incoming().contains(&input_idx));
765
766 graph.detach(input_idx, output_idx);
767 assert!(!graph[input_idx].outgoing().contains(&output_idx));
768 assert!(!graph[output_idx].incoming().contains(&input_idx));
769
770 graph.detach(input_idx, output_idx); }
773
774 #[test]
775 #[cfg(feature = "serde")]
776 fn test_graph_eval_serde() {
777 use crate::Eval;
778
779 let mut graph = Graph::default();
780
781 graph.insert(NodeType::Input, 0);
782 graph.insert(NodeType::Vertex, 1);
783 graph.insert(NodeType::Output, 2);
784 graph.attach(0, 1);
785 graph.attach(1, 2);
786
787 let serialized = serde_json::to_string(&graph).unwrap();
788 let deserialized: Graph<i32> = serde_json::from_str(&serialized).unwrap();
789
790 assert_eq!(graph, deserialized);
791
792 let values = vec![
793 (NodeType::Input, vec![Op::var(0), Op::var(1)]),
794 (NodeType::Edge, vec![Op::weight()]),
795 (NodeType::Vertex, vec![Op::sub(), Op::mul(), Op::linear()]),
796 (NodeType::Output, vec![Op::linear()]),
797 ];
798
799 let op_graph = Graph::directed(2, 2, values);
800 let eval_one = op_graph.eval(&vec![vec![0.5, 1.5]]);
801
802 let serialized_op = serde_json::to_string(&op_graph).unwrap();
803 let deserialized_op: Graph<Op<f32>> = serde_json::from_str(&serialized_op).unwrap();
804
805 let deserialized_eval = deserialized_op.eval(&vec![vec![0.5, 1.5]]);
806
807 assert_eq!(eval_one, deserialized_eval);
808 assert_eq!(op_graph, deserialized_op);
809 }
810
811 #[test]
812 #[cfg(feature = "serde")]
813 fn test_graph_pre_built_serde() {
814 use crate::Eval;
815
816 let mut graph = Graph::<Op<f32>>::default();
817
818 let idx_one = graph.insert(NodeType::Input, Op::var(0));
819 let idx_two = graph.insert(NodeType::Input, Op::constant(5_f32));
820 let idx_three = graph.insert(NodeType::Vertex, Op::add());
821 let idx_four = graph.insert(NodeType::Output, Op::linear());
822
823 graph
824 .attach(idx_one, idx_three)
825 .attach(idx_two, idx_three)
826 .attach(idx_three, idx_four);
827
828 let eval_to_six_one = graph.eval(&vec![vec![1_f32]]);
829 let eval_to_seven_one = graph.eval(&vec![vec![2_f32]]);
830 let eval_to_eight_one = graph.eval(&vec![vec![3_f32]]);
831
832 assert_eq!(eval_to_six_one, &[&[6_f32]]);
833 assert_eq!(eval_to_seven_one, &[&[7_f32]]);
834 assert_eq!(eval_to_eight_one, &[&[8_f32]]);
835 assert_eq!(graph.len(), 4);
836
837 let serialized = serde_json::to_string(&graph).unwrap();
838 let deserialized: Graph<Op<f32>> = serde_json::from_str(&serialized).unwrap();
839
840 assert_eq!(graph, deserialized);
841
842 let eval_to_six_two = deserialized.eval(&vec![vec![1_f32]]);
843 let eval_to_seven_two = deserialized.eval(&vec![vec![2_f32]]);
844 let eval_to_eight_two = deserialized.eval(&vec![vec![3_f32]]);
845
846 assert_eq!(eval_to_six_two, &[&[6_f32]]);
847 assert_eq!(eval_to_seven_two, &[&[7_f32]]);
848 assert_eq!(eval_to_eight_two, &[&[8_f32]]);
849 assert_eq!(deserialized.len(), 4);
850 }
851}