use super::*;
#[test]
fn test_nested_description_implicit_kea_rejected() {
let predicates = vec![
Predicate::Root("dog".into()), Predicate::Root("cat".into()), Predicate::Root("big".into()), ];
let arguments = vec![
Argument::Description((Determiner::Indefinite, 0)), Argument::Description((Determiner::Indefinite, 1)), Argument::Restricted((
0,
RelClause {
kind: RelClauseKind::Restrictive,
body_sentence: 1,
},
)), ];
let sentences = vec![
Sentence::Simple(Proposition {
relation: 2, terms: vec![2], x1_present: true,
negated: false,
tense: None,
deontic: None,
}),
Sentence::Simple(Proposition {
relation: 2, terms: vec![1], x1_present: true,
negated: false,
tense: None,
deontic: None,
}),
];
let (_form, compiler) = compile_sentence_full(predicates, arguments, sentences);
assert!(
!compiler.errors.is_empty(),
"Expected an ambiguity/it error for an implicit-it nested description"
);
assert!(
compiler.errors.iter().any(|e| e.contains("explicit `it`")),
"Error should direct the user to an explicit `it`, got: {:?}",
compiler.errors
);
}
#[test]
fn test_single_predicate_injects_head_into_subject() {
let predicates = vec![
Predicate::Root("dog".into()), Predicate::Root("big".into()), Predicate::Root("goes".into()), ];
let arguments = vec![
Argument::Description((Determiner::Indefinite, 0)), Argument::Restricted((
0,
RelClause {
kind: RelClauseKind::Restrictive,
body_sentence: 1,
},
)), ];
let sentences = vec![
Sentence::Simple(Proposition {
relation: 2,
terms: vec![1],
x1_present: true,
negated: false,
tense: None,
deontic: None,
}),
Sentence::Simple(Proposition {
relation: 1,
terms: vec![],
x1_present: false,
negated: false,
tense: None,
deontic: None,
}),
];
let (form, compiler) = compile_sentence_full(predicates, arguments, sentences);
assert!(
compiler.errors.is_empty(),
"Expected no errors for a single-predicate clause, got: {:?}",
compiler.errors
);
let big_args =
get_pred_args(&form, "big_x1", &compiler).expect("big_x1 role predicate should be present");
let dog_args =
get_pred_args(&form, "dog_x1", &compiler).expect("dog_x1 role predicate should be present");
assert!(
matches!(big_args[1], IrTerm::Variable(_)),
"dog variable should be injected into big_x1, got {:?}",
big_args[1]
);
assert_eq!(
big_args[1], dog_args[1],
"big_x1 must bind the same variable as dog_x1 (the described dog)"
);
}
#[test]
fn test_nested_description_two_place_rejected() {
let predicates = vec![
Predicate::Root("dog".into()), Predicate::Root("cat".into()), Predicate::Root("bite".into()), ];
let arguments = vec![
Argument::Description((Determiner::Indefinite, 0)), Argument::Description((Determiner::Indefinite, 1)), Argument::Restricted((
0,
RelClause {
kind: RelClauseKind::Restrictive,
body_sentence: 1,
},
)), ];
let sentences = vec![
Sentence::Simple(Proposition {
relation: 2,
terms: vec![2],
x1_present: true,
negated: false,
tense: None,
deontic: None,
}),
Sentence::Simple(Proposition {
relation: 2,
terms: vec![1], x1_present: true,
negated: false,
tense: None,
deontic: None,
}),
];
let (_form, compiler) = compile_sentence_full(predicates, arguments, sentences);
assert!(
!compiler.errors.is_empty(),
"Expected an `it` error: the dog's bite_x2 place cannot be filled implicitly"
);
}
#[test]
fn test_count_unspecified_predicates_single() {
let mut compiler = SemanticCompiler::new();
let rel = compiler.interner.get_or_intern("dog");
let form = IrForm::Predicate {
relation: rel,
args: vec![IrTerm::Unspecified],
};
assert_eq!(
SemanticCompiler::count_unspecified_predicates(&form, &compiler.interner),
1
);
}
#[test]
fn test_count_unspecified_predicates_none() {
let mut compiler = SemanticCompiler::new();
let rel = compiler.interner.get_or_intern("dog");
let var = compiler.interner.get_or_intern("x");
let form = IrForm::Predicate {
relation: rel,
args: vec![IrTerm::Variable(var)],
};
assert_eq!(
SemanticCompiler::count_unspecified_predicates(&form, &compiler.interner),
0
);
}
#[test]
fn test_count_unspecified_predicates_conjunction() {
let mut compiler = SemanticCompiler::new();
let rel1 = compiler.interner.get_or_intern("dog");
let rel2 = compiler.interner.get_or_intern("cat");
let form = IrForm::And(
Box::new(IrForm::Predicate {
relation: rel1,
args: vec![IrTerm::Unspecified],
}),
Box::new(IrForm::Predicate {
relation: rel2,
args: vec![IrTerm::Unspecified],
}),
);
assert_eq!(
SemanticCompiler::count_unspecified_predicates(&form, &compiler.interner),
2
);
}
#[test]
fn test_inject_variable_fills_first_unspecified() {
let mut compiler = SemanticCompiler::new();
let rel = compiler.interner.get_or_intern("dog");
let var = compiler.interner.get_or_intern("_v0");
let form = IrForm::Predicate {
relation: rel,
args: vec![IrTerm::Unspecified, IrTerm::Unspecified],
};
let injected = SemanticCompiler::inject_variable(form, var, &compiler.interner);
match injected {
IrForm::Predicate { args, .. } => {
assert!(matches!(args[0], IrTerm::Variable(_)));
assert!(matches!(args[1], IrTerm::Unspecified));
}
other => panic!("expected Predicate, got {:?}", other),
}
}