use super::*;
#[test]
fn event_decompose_basic() {
let b = lb("goes(me).");
assert!(matches!(root(&b), LogicNode::ExistsNode(_)));
let type_args = pred_args(&b, "goes").unwrap();
let x1_args = pred_args(&b, "goes_x1").unwrap();
assert!(matches!(x1_args.as_slice(), [_, LogicalTerm::Constant(c)] if c == "me"));
assert_eq!(
type_args[0], x1_args[0],
"type-pred and role share the event var"
);
assert!(matches!(type_args[0], LogicalTerm::Variable(_)));
}
#[test]
fn all_five_roles_emitted_for_known_arity() {
let b = lb("goes(me).");
for r in ["goes_x1", "goes_x2", "goes_x3", "goes_x4", "goes_x5"] {
assert!(has_pred(&b, r), "missing {r}");
}
assert!(
!has_pred(&b, "goes_x6"),
"arity-5 predicate must not emit x6"
);
}
#[test]
fn pair_shares_event_var() {
let b = lb("fast dog(me).");
assert!(has_pred(&b, "dog"));
let dog_x1 = pred_args(&b, "dog_x1").unwrap();
let fast_x1 = pred_args(&b, "fast_x1").unwrap();
assert_eq!(
dog_x1[0], fast_x1[0],
"head and modifier share the event var"
);
assert!(role_is_const(&b, "dog_x1", "me"));
assert!(role_is_const(&b, "fast_x1", "me"));
}
#[test]
fn pair_emits_no_intersective_type_predicate() {
let b = lb("big dog(me).");
assert!(
!has_pred(&b, "big"),
"modifier must not emit a standalone type pred"
);
assert!(has_pred(&b, "big_x1"));
}
#[test]
fn three_unit_stack_keeps_every_modifier() {
let b = lb("big fast dog(me).");
assert!(has_pred(&b, "dog"));
let dog_x1 = pred_args(&b, "dog_x1").unwrap();
let big_x1 = pred_args(&b, "big_x1").unwrap();
let fast_x1 = pred_args(&b, "fast_x1").unwrap();
assert_eq!(
dog_x1[0], big_x1[0],
"head and first modifier share the event var"
);
assert_eq!(
dog_x1[0], fast_x1[0],
"head and second modifier share the event var"
);
assert!(role_is_const(&b, "big_x1", "me"));
assert!(role_is_const(&b, "fast_x1", "me"));
assert!(
!has_pred(&b, "big"),
"modifier must not emit a standalone type pred"
);
assert!(
!has_pred(&b, "fast"),
"modifier must not emit a standalone type pred"
);
}
#[test]
fn bracketed_stack_compiles_like_unbracketed() {
let bracketed = lb("[big fast] dog(me).");
let unbracketed = lb("big fast dog(me).");
assert_eq!(
bracketed, unbracketed,
"grouping must not drop or reorder units"
);
for r in ["dog", "dog_x1", "big_x1", "fast_x1"] {
assert!(has_pred(&bracketed, r), "missing {r}");
}
assert!(!has_pred(&bracketed, "big"));
assert!(!has_pred(&bracketed, "fast"));
}
#[test]
fn observative_with_modifier_compiles() {
let b = lb("big rain().");
assert!(has_pred(&b, "rain"));
assert!(has_pred(&b, "rain_x1"));
assert!(
has_pred(&b, "big_x1"),
"modifier roles must emit on an observative"
);
assert!(
!has_pred(&b, "big"),
"modifier must not emit a standalone type pred"
);
assert_eq!(role_filler(&b, "big_x1"), Some(LogicalTerm::Unspecified));
assert_eq!(role_filler(&b, "rain_x1"), Some(LogicalTerm::Unspecified));
}
#[test]
fn decompose_with_quantified_argument() {
let b = lb("goes(some dog).");
assert!(matches!(root(&b), LogicNode::ExistsNode(_)));
for r in ["dog", "goes", "dog_x1", "goes_x1"] {
assert!(has_pred(&b, r), "missing {r}");
}
}
#[test]
fn conversion_routes_places() {
let b = lb("owned(Rex, Adam).");
assert!(role_is_const(&b, "owns_x1", "adam"));
assert!(role_is_const(&b, "owns_x2", "rex"));
}