use super::*;
fn make_exists_query(entity: &str, predicate: &str) -> LogicBuffer {
let mut nodes = Vec::new();
let body = pred(
&mut nodes,
predicate,
vec![
LogicalTerm::Constant(entity.to_string()),
LogicalTerm::Variable("_v1".to_string()),
LogicalTerm::Unspecified,
],
);
let root = exists(&mut nodes, "_v1", body);
LogicBuffer {
nodes,
roots: vec![root],
}
}
#[test]
fn test_dependent_skolem_native_rule() {
let kb = new_kb();
assert_buf(&kb, make_assertion("alis", "prenu"));
assert_buf(&kb, make_dependent_skolem_universal("prenu", "zdani"));
assert!(query(&kb, make_exists_query("alis", "zdani")));
}
#[test]
fn test_dependent_skolem_entity_after_rule() {
let kb = new_kb();
assert_buf(&kb, make_dependent_skolem_universal("prenu", "zdani"));
assert_buf(&kb, make_assertion("alis", "prenu"));
assert!(query(&kb, make_exists_query("alis", "zdani")));
}
#[test]
fn test_dependent_skolem_query_existential() {
let kb = new_kb();
assert_buf(&kb, make_assertion("alis", "prenu"));
assert_buf(&kb, make_dependent_skolem_universal("prenu", "zdani"));
assert!(query(&kb, make_exists_query("alis", "zdani")));
assert!(query_false(&kb, make_exists_query("bob", "zdani")));
}
#[test]
fn test_skolem_fn_multiple_entities() {
let kb = new_kb();
assert_buf(&kb, make_assertion("alis", "prenu"));
assert_buf(&kb, make_assertion("bob", "prenu"));
assert_buf(&kb, make_dependent_skolem_universal("prenu", "zdani"));
assert!(query(&kb, make_exists_query("alis", "zdani")));
assert!(query(&kb, make_exists_query("bob", "zdani")));
}
#[test]
fn test_skolem_fn_registry_populated() {
let kb = new_kb();
assert_buf(&kb, make_dependent_skolem_universal("prenu", "zdani"));
let inner = kb.inner.borrow();
assert!(
!inner.skolem_fn_registry.is_empty(),
"SkolemFn registry should have entries"
);
assert_eq!(inner.skolem_fn_registry[0].base_name, "sk_0");
assert_eq!(inner.skolem_fn_registry[0].dep_count, 1);
}
fn make_multi_dep_skolem_universal() -> LogicBuffer {
let mut nodes = Vec::new();
let p = pred(
&mut nodes,
"prenu",
vec![
LogicalTerm::Variable("_v0".to_string()),
LogicalTerm::Unspecified,
],
);
let q = pred(
&mut nodes,
"mlatu",
vec![
LogicalTerm::Variable("_v1".to_string()),
LogicalTerm::Unspecified,
],
);
let conj = and(&mut nodes, p, q);
let body = pred(
&mut nodes,
"zdani",
vec![
LogicalTerm::Variable("_v0".to_string()),
LogicalTerm::Variable("_v1".to_string()),
LogicalTerm::Variable("_v2".to_string()),
],
);
let ex = exists(&mut nodes, "_v2", body);
let neg = not(&mut nodes, conj);
let disj = or(&mut nodes, neg, ex);
let inner_forall = forall(&mut nodes, "_v1", disj);
let root = forall(&mut nodes, "_v0", inner_forall);
LogicBuffer {
nodes,
roots: vec![root],
}
}
fn make_multi_dep_exists_query(entity_a: &str, entity_b: &str) -> LogicBuffer {
let mut nodes = Vec::new();
let body = pred(
&mut nodes,
"zdani",
vec![
LogicalTerm::Constant(entity_a.to_string()),
LogicalTerm::Constant(entity_b.to_string()),
LogicalTerm::Variable("_v2".to_string()),
],
);
let root = exists(&mut nodes, "_v2", body);
LogicBuffer {
nodes,
roots: vec![root],
}
}
#[test]
fn test_multi_dep_skolem_two_universals() {
let kb = new_kb();
assert_buf(&kb, make_assertion("alis", "prenu"));
assert_buf(&kb, make_assertion("felix", "mlatu"));
assert_buf(&kb, make_multi_dep_skolem_universal());
assert!(query(&kb, make_multi_dep_exists_query("alis", "felix")));
}
#[test]
fn test_multi_dep_skolem_registry() {
let kb = new_kb();
assert_buf(&kb, make_multi_dep_skolem_universal());
let inner = kb.inner.borrow();
assert!(!inner.skolem_fn_registry.is_empty());
assert_eq!(inner.skolem_fn_registry[0].dep_count, 2);
}
fn make_cyp_shape_universal() -> LogicBuffer {
let mut nodes = Vec::new();
let p = pred(
&mut nodes,
"prenu",
vec![
LogicalTerm::Variable("_v0".to_string()),
LogicalTerm::Unspecified,
],
);
let q = pred(
&mut nodes,
"mlatu",
vec![
LogicalTerm::Variable("_v1".to_string()),
LogicalTerm::Unspecified,
],
);
let r = pred(
&mut nodes,
"gerku",
vec![
LogicalTerm::Variable("_v3".to_string()),
LogicalTerm::Unspecified,
],
);
let conj_pq = and(&mut nodes, p, q);
let conj = and(&mut nodes, conj_pq, r);
let body = pred(
&mut nodes,
"zdani",
vec![
LogicalTerm::Variable("_v1".to_string()),
LogicalTerm::Variable("_v2".to_string()),
],
);
let ex = exists(&mut nodes, "_v2", body);
let neg = not(&mut nodes, conj);
let disj = or(&mut nodes, neg, ex);
let f3 = forall(&mut nodes, "_v3", disj);
let f1 = forall(&mut nodes, "_v1", f3);
let root = forall(&mut nodes, "_v0", f1);
LogicBuffer {
nodes,
roots: vec![root],
}
}
#[test]
fn test_dependent_skolem_precise_deps_single_universal() {
let kb = new_kb();
assert_buf(&kb, make_cyp_shape_universal());
let inner = kb.inner.borrow();
assert!(!inner.skolem_fn_registry.is_empty());
assert_eq!(inner.skolem_fn_registry[0].dep_count, 1);
}
#[test]
fn test_multi_dep_skolem_different_entities() {
let kb = new_kb();
assert_buf(&kb, make_assertion("alis", "prenu"));
assert_buf(&kb, make_assertion("bob", "prenu"));
assert_buf(&kb, make_assertion("felix", "mlatu"));
assert_buf(&kb, make_assertion("garfield", "mlatu"));
assert_buf(&kb, make_multi_dep_skolem_universal());
assert!(query(&kb, make_multi_dep_exists_query("alis", "felix")));
assert!(query(&kb, make_multi_dep_exists_query("alis", "garfield")));
assert!(query(&kb, make_multi_dep_exists_query("bob", "felix")));
assert!(query(&kb, make_multi_dep_exists_query("bob", "garfield")));
assert!(query_false(
&kb,
make_multi_dep_exists_query("felix", "alis")
));
}
#[test]
fn test_multi_dep_skolem_rule_before_facts() {
let kb = new_kb();
assert_buf(&kb, make_multi_dep_skolem_universal());
assert_buf(&kb, make_assertion("alis", "prenu"));
assert_buf(&kb, make_assertion("felix", "mlatu"));
assert!(query(&kb, make_multi_dep_exists_query("alis", "felix")));
}