rust_igraph/algorithms/properties/
is_co_chordal.rs1use crate::algorithms::chordality::is_chordal;
12use crate::core::{Graph, IgraphResult};
13
14pub fn is_co_chordal(graph: &Graph) -> IgraphResult<bool> {
44 let n = graph.vcount();
45 if n <= 3 {
46 return Ok(true);
47 }
48
49 let n_usize = n as usize;
50 let mut adj = vec![vec![false; n_usize]; n_usize];
51 for v in 0..n {
52 let nbrs = graph.neighbors(v)?;
53 for &w in &nbrs {
54 adj[v as usize][w as usize] = true;
55 adj[w as usize][v as usize] = true;
56 }
57 }
58
59 let mut comp = Graph::with_vertices(n);
60 for v in 0..n {
61 for w in (v + 1)..n {
62 if !adj[v as usize][w as usize] {
63 comp.add_edge(v, w)?;
64 }
65 }
66 }
67
68 Ok(is_chordal(&comp, None)?.chordal)
69}
70
71#[cfg(test)]
72mod tests {
73 use super::*;
74
75 #[test]
76 fn empty_graph() {
77 let g = Graph::with_vertices(0);
78 assert!(is_co_chordal(&g).unwrap());
79 }
80
81 #[test]
82 fn single_vertex() {
83 let g = Graph::with_vertices(1);
84 assert!(is_co_chordal(&g).unwrap());
85 }
86
87 #[test]
88 fn single_edge() {
89 let mut g = Graph::with_vertices(2);
90 g.add_edge(0, 1).unwrap();
91 assert!(is_co_chordal(&g).unwrap());
92 }
93
94 #[test]
95 fn triangle() {
96 let mut g = Graph::with_vertices(3);
97 g.add_edge(0, 1).unwrap();
98 g.add_edge(1, 2).unwrap();
99 g.add_edge(2, 0).unwrap();
100 assert!(is_co_chordal(&g).unwrap());
101 }
102
103 #[test]
104 fn k4() {
105 let mut g = Graph::with_vertices(4);
106 for i in 0..4u32 {
107 for j in (i + 1)..4 {
108 g.add_edge(i, j).unwrap();
109 }
110 }
111 assert!(is_co_chordal(&g).unwrap());
112 }
113
114 #[test]
115 fn k5() {
116 let mut g = Graph::with_vertices(5);
117 for i in 0..5u32 {
118 for j in (i + 1)..5 {
119 g.add_edge(i, j).unwrap();
120 }
121 }
122 assert!(is_co_chordal(&g).unwrap());
123 }
124
125 #[test]
126 fn edgeless_5() {
127 let g = Graph::with_vertices(5);
129 assert!(is_co_chordal(&g).unwrap());
130 }
131
132 #[test]
133 fn c4() {
134 let mut g = Graph::with_vertices(4);
136 g.add_edge(0, 1).unwrap();
137 g.add_edge(1, 2).unwrap();
138 g.add_edge(2, 3).unwrap();
139 g.add_edge(3, 0).unwrap();
140 assert!(is_co_chordal(&g).unwrap());
141 }
142
143 #[test]
144 fn c5_not_co_chordal() {
145 let mut g = Graph::with_vertices(5);
147 g.add_edge(0, 1).unwrap();
148 g.add_edge(1, 2).unwrap();
149 g.add_edge(2, 3).unwrap();
150 g.add_edge(3, 4).unwrap();
151 g.add_edge(4, 0).unwrap();
152 assert!(!is_co_chordal(&g).unwrap());
153 }
154
155 #[test]
156 fn c6_not_co_chordal() {
157 let mut g = Graph::with_vertices(6);
159 for i in 0..6u32 {
160 g.add_edge(i, (i + 1) % 6).unwrap();
161 }
162 assert!(!is_co_chordal(&g).unwrap());
163 }
164
165 #[test]
166 fn path_p5() {
167 let mut g = Graph::with_vertices(5);
177 g.add_edge(0, 1).unwrap();
178 g.add_edge(1, 2).unwrap();
179 g.add_edge(2, 3).unwrap();
180 g.add_edge(3, 4).unwrap();
181 assert!(!is_co_chordal(&g).unwrap());
182 }
183
184 #[test]
185 fn star_s4() {
186 let mut g = Graph::with_vertices(5);
190 g.add_edge(0, 1).unwrap();
191 g.add_edge(0, 2).unwrap();
192 g.add_edge(0, 3).unwrap();
193 g.add_edge(0, 4).unwrap();
194 assert!(is_co_chordal(&g).unwrap());
195 }
196
197 #[test]
198 fn directed_treated_as_undirected() {
199 let mut g = Graph::new(4, true).unwrap();
200 g.add_edge(0, 1).unwrap();
201 g.add_edge(1, 2).unwrap();
202 g.add_edge(2, 3).unwrap();
203 g.add_edge(3, 0).unwrap();
204 assert!(is_co_chordal(&g).unwrap());
205 }
206}