cairn_knowledge_graph/operations/selection/operators/
or.rs1use once_cell::sync::Lazy;
2
3use graphblas_sparse_linear_algebra::operators::{
4 element_wise_addition::ElementWiseVectorAdditionMonoidOperator, monoid::LogicalOr,
5 options::OperatorOptions,
6};
7
8use crate::error::GraphComputingError;
9
10use crate::operations::selection::vertex_selection::VertexSelection;
11
12static DEFAULT_GRAPHBLAS_OPERATOR_OPTIONS: Lazy<OperatorOptions> =
13 Lazy::new(|| OperatorOptions::new_default());
14
15static GRAPHBLAS_VECTOR_OR_OPERATOR: Lazy<ElementWiseVectorAdditionMonoidOperator<bool>> =
16 Lazy::new(|| {
17 ElementWiseVectorAdditionMonoidOperator::<bool>::new(
18 &LogicalOr::<bool>::new(),
19 &DEFAULT_GRAPHBLAS_OPERATOR_OPTIONS,
20 None,
21 )
22 });
23
24pub trait OrOperator<RightHandSide = Self> {
25 type Output;
26 fn or(&self, right_hand_side: &RightHandSide) -> Result<Self::Output, GraphComputingError>;
27 fn or_with_mask(
28 &self,
29 right_hand_side: &RightHandSide,
30 mask: &RightHandSide,
31 ) -> Result<Self::Output, GraphComputingError>;
32}
33
34impl<'g> OrOperator for VertexSelection<'g> {
35 type Output = VertexSelection<'g>;
36
37 fn or(&self, right_hand_side: &Self) -> Result<Self, GraphComputingError> {
38 let mut resulting_vertex_selection = self.clone();
41 GRAPHBLAS_VECTOR_OR_OPERATOR.apply(
42 self.vertex_mask_ref(),
43 right_hand_side.vertex_mask_ref(),
44 resulting_vertex_selection.vertex_mask_mut_ref(),
45 )?;
46 Ok(resulting_vertex_selection)
47 }
48
49 fn or_with_mask(
52 &self,
53 right_hand_side: &Self,
54 mask: &Self,
55 ) -> Result<Self, GraphComputingError> {
56 let mut resulting_vertex_selection = self.clone();
59 GRAPHBLAS_VECTOR_OR_OPERATOR.apply_with_mask(
60 mask.vertex_mask_ref(),
61 self.vertex_mask_ref(),
62 right_hand_side.vertex_mask_ref(),
63 resulting_vertex_selection.vertex_mask_mut_ref(),
64 )?;
65 Ok(resulting_vertex_selection)
66 }
67}
68
69#[cfg(test)]
70mod tests {
71 use super::*;
72
73 use crate::graph::vertex::VertexValue;
74 use crate::operations::select_vertex::SelectVertex;
75
76 use crate::tests::standard_graph_for_testing::standard_graph_for_testing;
77
78 #[test]
79 fn test_or_operator_for_vertex_selection() {
80 let graph = standard_graph_for_testing();
81
82 let larger_than_one_selection = graph
83 .select_vertices_connected_to_vertex_by_key(String::from("larger_than"), &"1")
84 .unwrap();
85 let equal_to_one_selection = graph
86 .select_vertices_connected_to_vertex_by_key(String::from("equal_to"), &"1_duplicate")
87 .unwrap();
88
89 let larger_than_or_equal_to_one_selection = larger_than_one_selection
90 .or(&equal_to_one_selection)
91 .unwrap();
92 let mut larger_than_or_equal_to_one = larger_than_or_equal_to_one_selection
93 .vertex_values_ref()
94 .unwrap();
95
96 larger_than_or_equal_to_one.sort_unstable_by(|a, b| a.partial_cmp(b).unwrap());
97 ();
98 larger_than_or_equal_to_one.dedup();
99
100 assert_eq!(larger_than_or_equal_to_one.len(), 4);
101 assert!(larger_than_or_equal_to_one.contains(&&VertexValue::UnsignedInteger8Bit(1)));
102 assert!(larger_than_or_equal_to_one.contains(&&VertexValue::FloatingPoint32Bit(1.1)));
103 assert!(larger_than_or_equal_to_one.contains(&&VertexValue::FloatingPoint32Bit(1.2)));
104 assert!(larger_than_or_equal_to_one.contains(&&VertexValue::UnsignedInteger8Bit(2)));
105 }
106
107 #[test]
108 fn test_or_operator_for_vertex_selection_with_mask() {
109 let graph = standard_graph_for_testing();
110
111 let larger_than_one_selection = graph
112 .select_vertices_connected_to_vertex_by_key(String::from("larger_than"), &"1")
113 .unwrap();
114 let equal_to_one_selection = graph
115 .select_vertices_connected_to_vertex_by_key(String::from("equal_to"), &"1_duplicate")
116 .unwrap();
117 let integer_selection = graph
118 .select_vertices_connected_to_vertex_by_key(String::from("is_a"), &"integer")
119 .unwrap();
120
121 let selection_of_integers_equal_to_or_larger_than_one = equal_to_one_selection
122 .or_with_mask(&larger_than_one_selection, &integer_selection)
123 .unwrap();
124 let mut integers_equal_to_or_larger_than_one =
125 selection_of_integers_equal_to_or_larger_than_one
126 .vertex_values_ref()
127 .unwrap();
128
129 integers_equal_to_or_larger_than_one.sort_unstable_by(|a, b| a.partial_cmp(b).unwrap());
130 ();
131 integers_equal_to_or_larger_than_one.dedup();
132
133 assert_eq!(integers_equal_to_or_larger_than_one.len(), 2);
134 assert!(
135 integers_equal_to_or_larger_than_one.contains(&&VertexValue::UnsignedInteger8Bit(1))
136 );
137 assert!(
138 integers_equal_to_or_larger_than_one.contains(&&VertexValue::UnsignedInteger8Bit(2))
139 );
140 }
141}