1pub trait Star {
69 #[must_use]
137 fn star(order: usize) -> Self;
138}
139
140#[macro_export]
142macro_rules! test_star {
143 ($type:ty) => {
144 #[test]
145 #[should_panic(expected = "a digraph has at least one vertex")]
146 fn star_0() {
147 drop(<$type>::star(0));
148 }
149
150 #[test]
151 fn star_1() {
152 let digraph = <$type>::star(1);
153
154 assert_eq!(digraph.order(), 1);
155 assert!(digraph.arcs().eq([]));
156 }
157
158 #[test]
159 fn star_1_complement() {
160 let digraph = <$type>::star(1).complement();
161
162 assert_eq!(digraph.order(), 1);
163 assert!(digraph.arcs().eq([]));
164 }
165
166 #[test]
167 fn star_2() {
168 let digraph = <$type>::star(2);
169
170 assert_eq!(digraph.order(), 2);
171 assert!(digraph.arcs().eq([(0, 1), (1, 0)]));
172 }
173
174 #[test]
175 fn star_2_complement() {
176 let digraph = <$type>::star(2).complement();
177
178 assert_eq!(digraph.order(), 2);
179 assert!(digraph.arcs().eq([]));
180 }
181
182 #[test]
183 fn star_3() {
184 let digraph = <$type>::star(3);
185
186 assert_eq!(digraph.order(), 3);
187 assert!(digraph.arcs().eq([(0, 1), (0, 2), (1, 0), (2, 0)]));
188 }
189
190 #[test]
191 fn star_3_complement() {
192 let digraph = <$type>::star(3).complement();
193
194 assert_eq!(digraph.order(), 3);
195 assert!(digraph.arcs().eq([(1, 2), (2, 1)]));
196 }
197 };
198}
199
200#[macro_export]
202macro_rules! proptest_star {
203 ($type:ty) => {
204 use {
205 proptest::proptest,
206 $crate::{
207 Degree,
208 IsBalanced,
209 IsIsolated,
210 IsOriented,
211 IsPendant,
212 IsSpanningSubdigraph,
213 IsSubdigraph,
214 IsSuperdigraph,
215 IsSymmetric,
216 OutdegreeSequence,
217 Sinks,
218 Sources,
219 },
220 };
221
222 proptest! {
223 #[test]
224 fn star_complement_size(order in 1..5_usize) {
225 assert_eq!(
226 <$type>::star(order).complement().size(),
227 (order - 1) * order.saturating_sub(2)
228 );
229 }
230
231 #[test]
232 fn star_degree(order in 1..5_usize) {
233 let digraph = <$type>::star(order);
234
235 assert_eq!(digraph.degree(0), (order - 1) * 2);
236 assert!((1..order).all(|u| digraph.degree(u) == 2));
237 }
238
239 #[test]
240 fn star_degree_sequence(order in 1..5_usize) {
241 let digraph = <$type>::star(order);
242 let degree_sequence = &mut digraph.degree_sequence();
243
244 assert_eq!(degree_sequence.next(), Some((order - 1) * 2));
245 assert!(degree_sequence.all(|d| d == 2));
246 }
247
248 #[test]
249 fn star_degree_sum_equals_2size(order in 1..5_usize) {
250 let digraph = <$type>::star(order);
251
252 assert_eq!(
253 digraph
254 .vertices()
255 .fold(0, |acc, u| acc + digraph.degree(u)),
256 2 * digraph.size()
257 );
258 }
259
260 #[test]
261 fn star_even_number_odd_degrees(order in 1..5_usize) {
262 let digraph = <$type>::star(order);
263
264 assert_eq!(
265 digraph
266 .vertices()
267 .filter(|&u| digraph.degree(u) % 2 == 1)
268 .count()
269 % 2,
270 0
271 );
272 }
273
274 #[test]
275 fn star_has_edge(order in 1..5_usize) {
276 let digraph = <$type>::star(order);
277
278 assert!((1..order).all(|u| digraph.has_edge(0, u)
279 && (u..order).all(|v| !digraph.has_edge(u, v))));
280 }
281
282 #[test]
283 fn star_indegree(order in 1..5_usize) {
284 let digraph = <$type>::star(order);
285
286 assert_eq!(digraph.indegree(0), order - 1);
287 assert!((1..order).all(|u| digraph.indegree(u) == 1));
288 }
289
290 #[test]
291 fn star_indegree_sequence(order in 1..5_usize) {
292 let digraph = <$type>::star(order);
293 let indegree_sequence = &mut digraph.indegree_sequence();
294
295 assert_eq!(indegree_sequence.next(), Some(order - 1));
296 assert!(indegree_sequence.all(|d| d == 1));
297 }
298
299 #[test]
300 fn star_is_balanced(order in 1..5_usize) {
301 assert!(<$type>::star(order).is_balanced());
302 }
303
304 #[test]
305 fn star_is_complete(order in 1..5_usize) {
306 assert!((order < 3) == <$type>::star(order).is_complete());
307 }
308
309 #[test]
310 fn star_is_isolated(order in 1..5_usize) {
311 let digraph = <$type>::star(order);
312
313 assert!(digraph
314 .vertices()
315 .all(|u| (order == 1) == digraph.is_isolated(u)));
316 }
317
318 #[test]
319 fn star_is_oriented(order in 1..5_usize) {
320 assert!((order == 1) == <$type>::star(order).is_oriented());
321 }
322
323 #[test]
324 fn star_is_pendant(order in 1..5_usize) {
325 let digraph = <$type>::star(order);
326
327 assert!(digraph.vertices().all(|u| !digraph.is_pendant(u)));
328 }
329
330 #[test]
331 fn star_is_regular(order in 1..5_usize) {
332 assert!((order < 3) == <$type>::star(order).is_regular());
333 }
334
335 #[test]
336 fn star_is_semicomplete(order in 1..5_usize) {
337 assert!((order < 3) == <$type>::star(order).is_semicomplete());
338 }
339
340 #[test]
341 fn star_is_simple(order in 1..5_usize) {
342 assert!(<$type>::star(order).is_simple());
343 }
344
345 #[test]
346 fn star_is_sink(order in 1..5_usize) {
347 let digraph = <$type>::star(order);
348
349 assert!(digraph
350 .vertices()
351 .all(|u| (order == 1) == digraph.is_sink(u)));
352 }
353
354 #[test]
355 fn star_is_source(order in 1..5_usize) {
356 let digraph = <$type>::star(order);
357
358 assert!(digraph
359 .vertices()
360 .all(|u| (order == 1) == digraph.is_source(u)));
361 }
362
363 #[test]
364 fn star_is_spanning_subdigraph(order in 1..5_usize) {
365 let digraph = <$type>::star(order);
366
367 assert!(digraph.is_spanning_subdigraph(&digraph));
368 }
369
370 #[test]
371 fn star_is_subdigraph(order in 1..5_usize) {
372 let digraph = <$type>::star(order);
373
374 assert!(digraph.is_subdigraph(&digraph));
375 }
376
377 #[test]
378 fn star_is_superdigraph(order in 1..5_usize) {
379 let digraph = <$type>::star(order);
380
381 assert!(digraph.is_superdigraph(&digraph));
382 }
383
384 #[test]
385 fn star_is_symmetric(order in 1..5_usize) {
386 assert!(<$type>::star(order).is_symmetric());
387 }
388
389 #[test]
390 fn star_is_tournament(order in 1..5_usize) {
391 assert!((order == 1) == <$type>::star(order).is_tournament());
392 }
393
394 #[test]
395 fn star_max_degree(order in 1..5_usize) {
396 assert_eq!(
397 <$type>::star(order).max_degree(),
398 (order - 1) * 2
399 );
400 }
401
402 #[test]
403 fn star_max_indegree(order in 1..5_usize) {
404 assert_eq!(<$type>::star(order).max_indegree(), order - 1);
405 }
406
407 #[test]
408 fn star_max_outdegree(order in 1..5_usize) {
409 assert_eq!(<$type>::star(order).max_outdegree(), order - 1);
410 }
411
412 #[test]
413 fn star_min_degree(order in 1..5_usize) {
414 assert_eq!(
415 <$type>::star(order).min_degree(),
416 if order == 1 { 0 } else { 2 }
417 );
418 }
419
420 #[test]
421 fn star_min_indegree(order in 1..5_usize) {
422 assert_eq!(
423 <$type>::star(order).min_indegree(),
424 if order == 1 { 0 } else { 1 }
425 );
426 }
427
428 #[test]
429 fn star_min_outdegree(order in 1..5_usize) {
430 assert_eq!(
431 <$type>::star(order).min_outdegree(),
432 if order == 1 { 0 } else { 1 }
433 );
434 }
435
436 #[test]
437 fn star_outdegree(order in 1..5_usize) {
438 let digraph = <$type>::star(order);
439
440 assert_eq!(digraph.outdegree(0), order - 1);
441 assert!((1..order).all(|u| digraph.outdegree(u) == 1));
442 }
443
444 #[test]
445 fn star_outdegree_sequence(order in 1..5_usize) {
446 let digraph = <$type>::star(order);
447 let outdegree_sequence = &mut digraph.outdegree_sequence();
448
449 assert_eq!(outdegree_sequence.next(), Some(order - 1));
450 assert!(outdegree_sequence.all(|d| d == 1));
451 }
452
453 #[test]
454 fn star_semidegree_sequence(order in 1..5_usize) {
455 let digraph = <$type>::star(order);
456 let mut semidegree_sequence = digraph.semidegree_sequence();
457
458 assert_eq!(
459 semidegree_sequence.next(),
460 Some((order - 1, order - 1))
461 );
462
463 assert!(semidegree_sequence.all(|d| d == (1, 1)));
464 }
465
466 #[test]
467 fn star_sinks(order in 1..5_usize) {
468 assert!(if order == 1 {
469 <$type>::star(order).sinks().eq([0])
470 } else {
471 <$type>::star(order).sinks().eq([])
472 });
473 }
474
475 #[test]
476 fn star_size(order in 1..5_usize) {
477 assert_eq!(<$type>::star(order).size(), (order - 1) * 2);
478 }
479
480 #[test]
481 fn star_sources(order in 1..5_usize) {
482 assert!(if order == 1 {
483 <$type>::star(order).sources().eq([0])
484 } else {
485 <$type>::star(order).sources().eq([])
486 });
487 }
488 }
489 };
490}