use super::*;
#[test]
fn test_subsumption_identical() {
let p_a = Literal::positive(TLExpr::pred("P", vec![Term::constant("a")]));
let c = Clause::unit(p_a);
assert!(c.subsumes(&c));
}
#[test]
fn test_subsumption_variable_to_constant() {
let p_x = Literal::positive(TLExpr::pred("P", vec![Term::var("x")]));
let p_a = Literal::positive(TLExpr::pred("P", vec![Term::constant("a")]));
let c_general = Clause::unit(p_x);
let c_specific = Clause::unit(p_a);
assert!(c_general.subsumes(&c_specific));
}
#[test]
fn test_subsumption_not_reverse() {
let p_x = Literal::positive(TLExpr::pred("P", vec![Term::var("x")]));
let p_a = Literal::positive(TLExpr::pred("P", vec![Term::constant("a")]));
let c_general = Clause::unit(p_x);
let c_specific = Clause::unit(p_a);
assert!(!c_specific.subsumes(&c_general));
}
#[test]
fn test_subsumption_smaller_clause() {
let p_x = Literal::positive(TLExpr::pred("P", vec![Term::var("x")]));
let p_a = Literal::positive(TLExpr::pred("P", vec![Term::constant("a")]));
let q_a = Literal::positive(TLExpr::pred("Q", vec![Term::constant("a")]));
let c1 = Clause::unit(p_x);
let c2 = Clause::from_literals(vec![p_a, q_a]);
assert!(c1.subsumes(&c2));
}
#[test]
fn test_subsumption_multiple_literals() {
let p_x = Literal::positive(TLExpr::pred("P", vec![Term::var("x")]));
let q_x = Literal::positive(TLExpr::pred("Q", vec![Term::var("x")]));
let c1 = Clause::from_literals(vec![p_x, q_x]);
let p_a = Literal::positive(TLExpr::pred("P", vec![Term::constant("a")]));
let q_a = Literal::positive(TLExpr::pred("Q", vec![Term::constant("a")]));
let r_a = Literal::positive(TLExpr::pred("R", vec![Term::constant("a")]));
let c2 = Clause::from_literals(vec![p_a, q_a, r_a]);
assert!(c1.subsumes(&c2));
}
#[test]
fn test_subsumption_fails_different_pred() {
let p_x = Literal::positive(TLExpr::pred("P", vec![Term::var("x")]));
let q_a = Literal::positive(TLExpr::pred("Q", vec![Term::constant("a")]));
let c1 = Clause::unit(p_x);
let c2 = Clause::unit(q_a);
assert!(!c1.subsumes(&c2));
}
#[test]
fn test_subsumption_fails_too_many_literals() {
let p_x = Literal::positive(TLExpr::pred("P", vec![Term::var("x")]));
let q_x = Literal::positive(TLExpr::pred("Q", vec![Term::var("x")]));
let r_x = Literal::positive(TLExpr::pred("R", vec![Term::var("x")]));
let c1 = Clause::from_literals(vec![p_x, q_x, r_x]);
let p_a = Literal::positive(TLExpr::pred("P", vec![Term::constant("a")]));
let q_a = Literal::positive(TLExpr::pred("Q", vec![Term::constant("a")]));
let c2 = Clause::from_literals(vec![p_a, q_a]);
assert!(!c1.subsumes(&c2));
}
#[test]
fn test_subsumption_empty_clause() {
let empty = Clause::empty();
let p_a = Literal::positive(TLExpr::pred("P", vec![Term::constant("a")]));
let non_empty = Clause::unit(p_a);
assert!(empty.subsumes(&empty));
assert!(!empty.subsumes(&non_empty));
assert!(!non_empty.subsumes(&empty));
}
#[test]
fn test_subsumption_polarity_matters() {
let p_x = Literal::positive(TLExpr::pred("P", vec![Term::var("x")]));
let not_p_a = Literal::negative(TLExpr::pred("P", vec![Term::constant("a")]));
let c1 = Clause::unit(p_x);
let c2 = Clause::unit(not_p_a);
assert!(!c1.subsumes(&c2));
}
#[test]
fn test_subsumption_two_variables() {
let p_xy = Literal::positive(TLExpr::pred("P", vec![Term::var("x"), Term::var("y")]));
let p_ab = Literal::positive(TLExpr::pred(
"P",
vec![Term::constant("a"), Term::constant("b")],
));
let c1 = Clause::unit(p_xy);
let c2 = Clause::unit(p_ab);
assert!(c1.subsumes(&c2));
}
#[test]
fn test_subsumption_in_prover() {
let mut prover = ResolutionProver::new();
let p_x = Literal::positive(TLExpr::pred("P", vec![Term::var("x")]));
let q_x = Literal::positive(TLExpr::pred("Q", vec![Term::var("x")]));
prover.add_clause(Clause::from_literals(vec![p_x, q_x]));
let p_a = Literal::positive(TLExpr::pred("P", vec![Term::constant("a")]));
let q_a = Literal::positive(TLExpr::pred("Q", vec![Term::constant("a")]));
let r_a = Literal::positive(TLExpr::pred("R", vec![Term::constant("a")]));
let subsumed_clause = Clause::from_literals(vec![p_a, q_a, r_a]);
assert!(prover.clauses[0].subsumes(&subsumed_clause));
}