use super::*;
#[test]
fn test_td_to_vtree_isolated_vars() {
let td = make_td(vec![vec![0, 1]], vec![], 2);
let vtree = td_to_vtree(&td, 3);
assert_eq!(vtree.num_leaves(), 3);
}
#[test]
fn test_td_to_vtree_single_var_single_bag() {
let td = make_td(vec![vec![0]], vec![], 1);
let vtree = td_to_vtree(&td, 1);
assert_covers_all_vars(&vtree, 1, "one bag holding one variable");
}
#[test]
fn test_td_to_vtree_multi_component_plus_isolated_var() {
let td = make_td(vec![vec![0, 1], vec![2, 3]], vec![], 4);
let vtree = td_to_vtree(&td, 5);
assert_covers_all_vars(&vtree, 5, "two components plus a variable no bag holds");
}
#[test]
fn test_td_to_vtree_single_wide_bag() {
let all_vars: Vec<u32> = (0..16).collect();
let td = make_td(vec![all_vars], vec![], 16);
let vtree = td_to_vtree(&td, 16);
assert_covers_all_vars(&vtree, 16, "one bag holding every variable");
}
#[test]
fn test_td_to_vtree_hypergraph_binarization() {
let td = make_td(vec![vec![0, 1, 2], vec![2, 3]], vec![(0, 1)], 4);
let reading = Reading {
root: Some(Root::First),
place: Some(Place::Deep),
binarize: Some(Binarization::Hypergraph),
};
let vtree = td_to_vtree_reading(&td, 4, reading, None, None);
assert_eq!(vtree.num_leaves(), 4);
}
#[test]
fn equivalent_bag_edge_orders_convert_to_the_same_vtree() {
let bags = vec![vec![0], vec![0, 1], vec![0, 2], vec![0, 3], vec![0, 4]];
let ascending = make_td(bags.clone(), vec![(0, 1), (0, 2), (0, 3), (0, 4)], 5);
let descending = make_td(bags, vec![(0, 4), (0, 3), (0, 2), (0, 1)], 5);
let reading = Reading {
root: Some(Root::First),
place: Some(Place::Deep),
binarize: Some(Binarization::Balanced),
};
let first = td_to_vtree_reading(&ascending, 5, reading, None, None);
let second = td_to_vtree_reading(&descending, 5, reading, None, None);
assert!(
first.same_tree(&second),
"equivalent undirected bag trees must not encode edge insertion order",
);
}
#[test]
fn every_reading_gives_one_leaf_per_variable() {
let path = make_td(
vec![vec![0, 1], vec![1, 2], vec![2, 3], vec![3, 4]],
vec![(0, 1), (1, 2), (2, 3)],
5,
);
let split = make_td(vec![vec![0, 1, 2], vec![3, 4], vec![5, 6]], vec![(1, 2)], 7);
let path_formula = make_formula(5, vec![vec![1, 2], vec![2, 3], vec![3, 4], vec![4, 5]]);
let split_formula = make_formula(7, vec![vec![1, 2, 3], vec![4, 5], vec![6, 7], vec![-4, 6]]);
for (shape, td, num_vars, formula) in [
("a path", &path, 5u32, &path_formula),
("two components", &split, 7, &split_formula),
] {
for place in [Place::Shallow, Place::Deep] {
for root in [Root::First, Root::Centroid, Root::Leaf] {
for binarize in [
Binarization::Edge,
Binarization::Hypergraph,
Binarization::Balanced,
] {
let reading = Reading {
root: Some(root),
place: Some(place),
binarize: Some(binarize),
};
for read_formula in [None, Some(formula)] {
let vtree = td_to_vtree_reading(td, num_vars, reading, read_formula, None);
let what = format!(
"{shape} under {reading:?} (formula: {})",
read_formula.is_some(),
);
assert_eq!(
vtree.num_leaves(),
num_vars,
"{what} changed the leaf count"
);
assert_covers_all_vars(&vtree, num_vars, &what);
}
}
}
}
}
}