use symbolic_mgu::{
EnumTerm, EnumTermFactory, MetaByte, MetaByteFactory, MetavariableFactory, MguError, NodeByte,
SimpleType, Term, TermFactory,
};
#[test]
fn children_count_invariant() -> Result<(), MguError> {
let term_factory = EnumTermFactory::<SimpleType, MetaByte, NodeByte>::new();
let var_factory = MetaByteFactory();
let var = var_factory
.list_metavariables_by_type(&SimpleType::Boolean)
.next()
.unwrap();
let leaf: EnumTerm<SimpleType, MetaByte, NodeByte> = term_factory.create_leaf(var)?;
assert_eq!(leaf.get_n_children(), leaf.get_children().count());
assert_eq!(leaf.get_n_children(), 0);
let nullary = term_factory.create_node(NodeByte::True, vec![])?;
assert_eq!(nullary.get_n_children(), nullary.get_children().count());
assert_eq!(nullary.get_n_children(), 0);
let unary = term_factory.create_node(NodeByte::Not, vec![leaf.clone()])?;
assert_eq!(unary.get_n_children(), unary.get_children().count());
assert_eq!(unary.get_n_children(), 1);
let binary = term_factory.create_node(NodeByte::And, vec![leaf.clone(), leaf.clone()])?;
assert_eq!(binary.get_n_children(), binary.get_children().count());
assert_eq!(binary.get_n_children(), 2);
let ternary = term_factory.create_node(
NodeByte::LogicalIf,
vec![leaf.clone(), leaf.clone(), leaf.clone()],
)?;
assert_eq!(ternary.get_n_children(), ternary.get_children().count());
assert_eq!(ternary.get_n_children(), 3);
Ok(())
}
#[test]
fn children_indexing_invariant() -> Result<(), MguError> {
let term_factory = EnumTermFactory::<SimpleType, MetaByte, NodeByte>::new();
let var_factory = MetaByteFactory();
let var1 = var_factory
.list_metavariables_by_type(&SimpleType::Boolean)
.next()
.unwrap();
let var2 = var_factory
.list_metavariables_by_type(&SimpleType::Boolean)
.nth(1)
.unwrap();
let var3 = var_factory
.list_metavariables_by_type(&SimpleType::Boolean)
.nth(2)
.unwrap();
let leaf1 = term_factory.create_leaf(var1)?;
let leaf2 = term_factory.create_leaf(var2)?;
let leaf3 = term_factory.create_leaf(var3)?;
let ternary = term_factory.create_node(
NodeByte::LogicalIf,
vec![leaf1.clone(), leaf2.clone(), leaf3.clone()],
)?;
for i in 0..ternary.get_n_children() {
let via_index = ternary.get_child(i);
let via_iter = ternary.get_children().nth(i);
assert_eq!(via_index, via_iter);
}
assert_eq!(ternary.get_child(100), None);
Ok(())
}
#[test]
fn factory_terms_are_valid() -> Result<(), MguError> {
let term_factory = EnumTermFactory::<SimpleType, MetaByte, NodeByte>::new();
let var_factory = MetaByteFactory();
let var = var_factory
.list_metavariables_by_type(&SimpleType::Boolean)
.next()
.unwrap();
let leaf = term_factory.create_leaf(var)?;
assert!(leaf.is_valid_sentence()?);
let not_term = term_factory.create_node(NodeByte::Not, vec![leaf.clone()])?;
assert!(not_term.is_valid_sentence()?);
let and_term = term_factory.create_node(NodeByte::And, vec![leaf.clone(), leaf.clone()])?;
assert!(and_term.is_valid_sentence()?);
Ok(())
}
#[test]
fn metavariable_type_consistency() -> Result<(), MguError> {
let term_factory = EnumTermFactory::<SimpleType, MetaByte, NodeByte>::new();
let var_factory = MetaByteFactory();
let bool_var = var_factory
.list_metavariables_by_type(&SimpleType::Boolean)
.next()
.unwrap();
let bool_leaf = term_factory.create_leaf(bool_var)?;
assert_eq!(bool_leaf.get_type()?, SimpleType::Boolean);
let setvar = var_factory
.list_metavariables_by_type(&SimpleType::Setvar)
.next()
.unwrap();
let setvar_leaf = term_factory.create_leaf(setvar)?;
assert_eq!(setvar_leaf.get_type()?, SimpleType::Setvar);
let class = var_factory
.list_metavariables_by_type(&SimpleType::Class)
.next()
.unwrap();
let class_leaf = term_factory.create_leaf(class)?;
assert_eq!(class_leaf.get_type()?, SimpleType::Class);
Ok(())
}
#[test]
fn node_type_consistency() -> Result<(), MguError> {
let term_factory = EnumTermFactory::<SimpleType, MetaByte, NodeByte>::new();
let var_factory = MetaByteFactory();
let bool_var = var_factory
.list_metavariables_by_type(&SimpleType::Boolean)
.next()
.unwrap();
let leaf = term_factory.create_leaf(bool_var)?;
let not_term = term_factory.create_node(NodeByte::Not, vec![leaf.clone()])?;
assert_eq!(not_term.get_type()?, SimpleType::Boolean);
let and_term = term_factory.create_node(NodeByte::And, vec![leaf.clone(), leaf.clone()])?;
assert_eq!(and_term.get_type()?, SimpleType::Boolean);
Ok(())
}
#[test]
fn collect_metavariables_completeness() -> Result<(), MguError> {
use std::collections::HashSet;
let term_factory = EnumTermFactory::<SimpleType, MetaByte, NodeByte>::new();
let var_factory = MetaByteFactory();
let var1 = var_factory
.list_metavariables_by_type(&SimpleType::Boolean)
.next()
.unwrap();
let var2 = var_factory
.list_metavariables_by_type(&SimpleType::Boolean)
.nth(1)
.unwrap();
let var3 = var_factory
.list_metavariables_by_type(&SimpleType::Boolean)
.nth(2)
.unwrap();
let leaf1 = term_factory.create_leaf(var1)?;
let mut vars = HashSet::new();
leaf1.collect_metavariables(&mut vars)?;
assert_eq!(vars.len(), 1);
assert!(vars.contains(&var1));
let leaf2 = term_factory.create_leaf(var2)?;
let leaf3 = term_factory.create_leaf(var3)?;
let and_term = term_factory.create_node(NodeByte::And, vec![leaf2.clone(), leaf3.clone()])?;
vars.clear();
and_term.collect_metavariables(&mut vars)?;
assert_eq!(vars.len(), 2);
assert!(vars.contains(&var2));
assert!(vars.contains(&var3));
let inner_and = term_factory.create_node(NodeByte::And, vec![leaf2.clone(), leaf1.clone()])?;
let outer_and = term_factory.create_node(NodeByte::And, vec![leaf1.clone(), inner_and])?;
vars.clear();
outer_and.collect_metavariables(&mut vars)?;
assert_eq!(vars.len(), 2); assert!(vars.contains(&var1));
assert!(vars.contains(&var2));
Ok(())
}
#[test]
fn children_slice_matches_iterator() -> Result<(), MguError> {
let term_factory = EnumTermFactory::<SimpleType, MetaByte, NodeByte>::new();
let var_factory = MetaByteFactory();
let var1 = var_factory
.list_metavariables_by_type(&SimpleType::Boolean)
.next()
.unwrap();
let var2 = var_factory
.list_metavariables_by_type(&SimpleType::Boolean)
.nth(1)
.unwrap();
let leaf1 = term_factory.create_leaf(var1)?;
let leaf2 = term_factory.create_leaf(var2)?;
let and_term = term_factory.create_node(NodeByte::And, vec![leaf1, leaf2])?;
let slice = and_term.get_children_as_slice();
let vec: Vec<_> = and_term.get_children().collect();
assert_eq!(slice.len(), vec.len());
for (i, item) in vec.iter().enumerate() {
assert_eq!(&slice[i], *item);
}
Ok(())
}
#[test]
fn is_metavariable_correctness() -> Result<(), MguError> {
let term_factory = EnumTermFactory::<SimpleType, MetaByte, NodeByte>::new();
let var_factory = MetaByteFactory();
let var = var_factory
.list_metavariables_by_type(&SimpleType::Boolean)
.next()
.unwrap();
let leaf = term_factory.create_leaf(var)?;
assert!(leaf.is_metavariable());
assert!(leaf.get_metavariable().is_some());
assert!(leaf.get_node().is_none());
let not_term = term_factory.create_node(NodeByte::Not, vec![leaf])?;
assert!(!not_term.is_metavariable());
assert!(not_term.get_metavariable().is_none());
assert!(not_term.get_node().is_some());
Ok(())
}
#[test]
fn metavariable_node_mutual_exclusion() -> Result<(), MguError> {
let term_factory = EnumTermFactory::<SimpleType, MetaByte, NodeByte>::new();
let var_factory = MetaByteFactory();
let var = var_factory
.list_metavariables_by_type(&SimpleType::Boolean)
.next()
.unwrap();
let leaf = term_factory.create_leaf(var)?;
let node_term = term_factory.create_node(NodeByte::True, vec![])?;
assert!(leaf.get_metavariable().is_some());
assert!(leaf.get_node().is_none());
assert!(node_term.get_metavariable().is_none());
assert!(node_term.get_node().is_some());
Ok(())
}