use open_hypergraphs::array::vec::*;
use open_hypergraphs::finite_function::FiniteFunction;
use open_hypergraphs::indexed_coproduct::IndexedCoproduct;
use open_hypergraphs::lax::{Hyperedge, Hypergraph as LaxHypergraph, NodeId};
use open_hypergraphs::semifinite::SemifiniteFunction;
use open_hypergraphs::strict::hypergraph::*;
use super::strategy::{DiscreteSpan, Labels};
use proptest::proptest;
use crate::theory::meaningless::*;
proptest! {
#[test]
fn test_new(h in arb_hypergraph()) {
let _ = Hypergraph::new(h.s, h.t, h.w, h.x).unwrap();
}
#[test]
fn test_discrete(Labels { w, .. } in arb_labels()) {
let num_obj = w.len();
let h: Hypergraph<VecKind, Obj, Arr> = Hypergraph::discrete(w);
assert_eq!(h.x.len(), 0);
assert_eq!(h.w.len(), num_obj);
assert!(h.is_discrete());
}
#[test]
fn test_coproduct(h0 in arb_hypergraph(), h1 in arb_hypergraph()) {
let h = h0.coproduct(&h1);
assert_eq!(h.s.len(), h0.s.len() + h1.s.len());
assert_eq!(h.t.len(), h0.t.len() + h1.t.len());
assert_eq!(h.s.values, &h0.s.values | &h1.s.values);
assert_eq!(h.t.values, &h0.t.values | &h1.t.values);
assert_eq!(h.w, h0.w + h1.w);
assert_eq!(h.x, h0.x + h1.x);
}
#[test]
fn test_inclusion(_ in arb_inclusion()) {}
#[test]
fn test_discrete_span(_ in arb_discrete_span()) {}
#[test]
fn test_coequalize_vertices(DiscreteSpan{l, h, r} in arb_discrete_span()) {
let gl = l.target;
let gr = r.target;
let g = gl.coproduct(&gr);
let q = l.w.inject0(gr.w.len()).coequalizer(&r.w.inject1(gl.w.len()))
.expect("construct coequalizer");
let k = g.coequalize_vertices(&q).expect("coequalize vertices");
assert_eq!(k.w.len(), g.w.len() - h.w.len());
assert_eq!(k.x.len(), g.x.len());
}
}
#[test]
fn test_empty() {
let e: Hypergraph<VecKind, usize, usize> = Hypergraph::empty();
assert_eq!(e.w.len(), 0);
assert_eq!(e.x.len(), 0);
}
fn build_hypergraph(
node_count: usize,
edges: &[(Vec<usize>, Vec<usize>)],
) -> Hypergraph<VecKind, Obj, Arr> {
let mut h = LaxHypergraph::empty();
h.nodes = vec![0; node_count];
for (sources, targets) in edges {
let edge = Hyperedge {
sources: sources.iter().map(|&i| NodeId(i)).collect(),
targets: targets.iter().map(|&i| NodeId(i)).collect(),
};
h.new_edge(0, edge);
}
h.to_hypergraph()
}
#[test]
fn test_is_acyclic_true() {
let h = build_hypergraph(3, &[(vec![0], vec![1]), (vec![1], vec![2])]);
assert!(h.is_acyclic());
}
#[test]
fn test_is_acyclic_false_cycle() {
let h = build_hypergraph(2, &[(vec![0], vec![1]), (vec![1], vec![0])]);
assert!(!h.is_acyclic());
}
#[test]
fn test_is_acyclic_false_self_loop() {
let h = build_hypergraph(1, &[(vec![0], vec![0])]);
assert!(!h.is_acyclic());
}
#[test]
fn test_in_out_degree_counts_multiplicity() {
let sources = IndexedCoproduct::from_semifinite(
SemifiniteFunction(VecArray(vec![3, 1])),
FiniteFunction::new(VecArray(vec![0, 1, 1, 2]), 3).unwrap(),
)
.unwrap();
let targets = IndexedCoproduct::from_semifinite(
SemifiniteFunction(VecArray(vec![2, 2])),
FiniteFunction::new(VecArray(vec![2, 0, 1, 1]), 3).unwrap(),
)
.unwrap();
let w = SemifiniteFunction(VecArray(vec![1i8, 2i8, 3i8]));
let x = SemifiniteFunction(VecArray(vec![10u8, 20u8]));
let h: Hypergraph<VecKind, Obj, Arr> = Hypergraph::new(sources, targets, w, x).unwrap();
assert_eq!(h.in_degree(0), 1);
assert_eq!(h.out_degree(0), 1);
assert_eq!(h.in_degree(1), 2);
assert_eq!(h.out_degree(1), 2);
assert_eq!(h.in_degree(2), 1);
assert_eq!(h.out_degree(2), 1);
}