use std::ops::{Add, BitAnd, BitOr, Not, Sub};
use super::graph::Graph;
use crate::algorithms::operators::complementer::complementer;
use crate::algorithms::operators::difference::difference;
use crate::algorithms::operators::disjoint_union::disjoint_union;
use crate::algorithms::operators::intersection::intersection;
use crate::algorithms::operators::union::union;
impl Add for Graph {
type Output = Graph;
fn add(self, rhs: Graph) -> Graph {
disjoint_union(&self, &rhs).expect("disjoint_union failed (directedness mismatch?)")
}
}
impl Add for &Graph {
type Output = Graph;
fn add(self, rhs: &Graph) -> Graph {
disjoint_union(self, rhs).expect("disjoint_union failed (directedness mismatch?)")
}
}
impl BitOr for Graph {
type Output = Graph;
fn bitor(self, rhs: Graph) -> Graph {
union(&self, &rhs).expect("union failed (directedness mismatch?)")
}
}
impl BitOr for &Graph {
type Output = Graph;
fn bitor(self, rhs: &Graph) -> Graph {
union(self, rhs).expect("union failed (directedness mismatch?)")
}
}
impl BitAnd for Graph {
type Output = Graph;
fn bitand(self, rhs: Graph) -> Graph {
intersection(&self, &rhs).expect("intersection failed (directedness mismatch?)")
}
}
impl BitAnd for &Graph {
type Output = Graph;
fn bitand(self, rhs: &Graph) -> Graph {
intersection(self, rhs).expect("intersection failed (directedness mismatch?)")
}
}
impl Sub for Graph {
type Output = Graph;
fn sub(self, rhs: Graph) -> Graph {
difference(&self, &rhs).expect("difference failed (directedness mismatch?)")
}
}
impl Sub for &Graph {
type Output = Graph;
fn sub(self, rhs: &Graph) -> Graph {
difference(self, rhs).expect("difference failed (directedness mismatch?)")
}
}
impl Not for Graph {
type Output = Graph;
fn not(self) -> Graph {
complementer(&self, false).expect("complementer failed")
}
}
impl Not for &Graph {
type Output = Graph;
fn not(self) -> Graph {
complementer(self, false).expect("complementer failed")
}
}
#[cfg(test)]
mod tests {
use super::*;
fn triangle() -> Graph {
let mut g = Graph::new(3, false).expect("graph");
g.add_edge(0, 1).expect("e");
g.add_edge(1, 2).expect("e");
g.add_edge(2, 0).expect("e");
g
}
fn path3() -> Graph {
let mut g = Graph::new(3, false).expect("graph");
g.add_edge(0, 1).expect("e");
g.add_edge(1, 2).expect("e");
g
}
#[test]
fn add_is_disjoint_union() {
let a = triangle();
let b = path3();
let c = &a + &b;
assert_eq!(c.vcount(), 6);
assert_eq!(c.ecount(), 5);
}
#[test]
fn bitor_is_union() {
let a = triangle();
let mut b = Graph::new(3, false).expect("graph");
b.add_edge(0, 1).expect("e");
let c = &a | &b;
assert_eq!(c.vcount(), 3);
assert_eq!(c.ecount(), 3);
}
#[test]
fn bitand_is_intersection() {
let a = triangle();
let b = path3();
let c = &a & &b;
assert_eq!(c.vcount(), 3);
assert_eq!(c.ecount(), 2);
}
#[test]
fn sub_is_difference() {
let a = triangle();
let b = path3();
let c = &a - &b;
assert_eq!(c.vcount(), 3);
assert_eq!(c.ecount(), 1);
}
#[test]
fn not_is_complement() {
let k3 = triangle();
let c = !&k3;
assert_eq!(c.vcount(), 3);
assert_eq!(c.ecount(), 0);
let empty = Graph::new(4, false).expect("graph");
let full = !∅
assert_eq!(full.ecount(), 6); }
#[test]
fn owned_operators_work() {
let a = triangle();
let b = path3();
let c = a + b;
assert_eq!(c.vcount(), 6);
}
}