use tensorlogic_ir::{DomainInfo, DomainRegistry, IrError, TLExpr, Term};
fn main() -> Result<(), IrError> {
println!("=== TensorLogic IR: Quantifiers ===\n");
let mut registry = DomainRegistry::with_builtins();
registry.register(DomainInfo::finite("Person", 100))?;
registry.register(DomainInfo::finite("City", 50))?;
println!("1. Existential Quantifier (∃):");
let _exists_person =
TLExpr::exists("x", "Person", TLExpr::pred("Person", vec![Term::var("x")]));
println!(" ∃x. Person(x) - 'There exists a person'");
let person = TLExpr::pred("Person", vec![Term::var("x")]);
let wise = TLExpr::pred("Wise", vec![Term::var("x")]);
let _exists_wise_person = TLExpr::exists("x", "Person", TLExpr::and(person, wise));
println!(" ∃x. (Person(x) ∧ Wise(x)) - 'There exists a wise person'");
println!("\n2. Universal Quantifier (∀):");
let person = TLExpr::pred("Person", vec![Term::var("x")]);
let mortal = TLExpr::pred("Mortal", vec![Term::var("x")]);
let _all_persons_mortal =
TLExpr::forall("x", "Person", TLExpr::imply(person.clone(), mortal.clone()));
println!(" ∀x. Person(x) → Mortal(x) - 'All persons are mortal'");
let student = TLExpr::pred("Student", vec![Term::var("x")]);
let studies = TLExpr::pred("StudiesHard", vec![Term::var("x")]);
let _all_students_study = TLExpr::forall("x", "Person", TLExpr::imply(student, studies));
println!(" ∀x. Student(x) → StudiesHard(x) - 'All students study hard'");
println!("\n3. Nested Quantifiers:");
let knows_xy = TLExpr::pred("knows", vec![Term::var("x"), Term::var("y")]);
let exists_y_knows = TLExpr::exists("y", "Person", knows_xy.clone());
let _everyone_knows_someone = TLExpr::forall("x", "Person", exists_y_knows);
println!(" ∀x. ∃y. knows(x, y) - 'Everyone knows someone'");
let person_y = TLExpr::pred("Person", vec![Term::var("y")]);
let knows_xy = TLExpr::pred("knows", vec![Term::var("x"), Term::var("y")]);
let knows_all = TLExpr::imply(person_y, knows_xy);
let forall_y_knows = TLExpr::forall("y", "Person", knows_all);
let _someone_knows_all = TLExpr::exists("x", "Person", forall_y_knows);
println!(" ∃x. ∀y. (Person(y) → knows(x, y)) - 'Someone knows everyone'");
println!("\n4. Multiple Variable Quantification:");
let person_x = TLExpr::pred("Person", vec![Term::var("x")]);
let person_y = TLExpr::pred("Person", vec![Term::var("y")]);
let friends = TLExpr::pred("friends", vec![Term::var("x"), Term::var("y")]);
let both_persons_and_friends = TLExpr::and(TLExpr::and(person_x, person_y), friends);
let exists_y_friends = TLExpr::exists("y", "Person", both_persons_and_friends);
let _exists_friends_pair = TLExpr::exists("x", "Person", exists_y_friends);
println!(" ∃x. ∃y. (Person(x) ∧ Person(y) ∧ friends(x, y)) - 'Two people are friends'");
println!("\n5. Free Variables After Quantification:");
let expr = TLExpr::pred("P", vec![Term::var("x"), Term::var("y")]);
println!(" Expression: P(x, y)");
println!(" Free variables: {:?}", expr.free_vars());
let exists_x = TLExpr::exists("x", "Person", expr.clone());
println!(" Expression: ∃x. P(x, y)");
println!(" Free variables: {:?}", exists_x.free_vars());
let exists_xy = TLExpr::exists("y", "Person", exists_x);
println!(" Expression: ∃x. ∃y. P(x, y)");
println!(" Free variables: {:?}", exists_xy.free_vars());
println!("\n6. Domain Validation:");
let valid_expr = TLExpr::exists("x", "Person", TLExpr::pred("Person", vec![Term::var("x")]));
match valid_expr.validate_domains(®istry) {
Ok(_) => println!(" ✓ Domain 'Person' is valid"),
Err(e) => println!(" ✗ Error: {:?}", e),
}
let invalid_expr = TLExpr::exists("x", "Alien", TLExpr::pred("Alien", vec![Term::var("x")]));
match invalid_expr.validate_domains(®istry) {
Ok(_) => println!(" ✓ Valid"),
Err(e) => println!(" ✗ Domain 'Alien' not registered: {:?}", e),
}
println!("\n7. Complex Quantified Expressions:");
let person_x = TLExpr::pred("Person", vec![Term::var("x")]);
let city_y = TLExpr::pred("City", vec![Term::var("y")]);
let lives_in = TLExpr::pred("livesIn", vec![Term::var("x"), Term::var("y")]);
let city_and_lives = TLExpr::and(city_y, lives_in);
let exists_city = TLExpr::exists("y", "City", city_and_lives);
let person_lives_somewhere = TLExpr::imply(person_x, exists_city);
let everyone_lives_somewhere = TLExpr::forall("x", "Person", person_lives_somewhere);
println!(" ∀x. (Person(x) → ∃y. (City(y) ∧ livesIn(x, y)))");
println!(" 'Every person lives in some city'");
println!(
" Free variables: {:?}",
everyone_lives_somewhere.free_vars()
);
match everyone_lives_somewhere.validate_domains(®istry) {
Ok(_) => println!(" ✓ All domains valid"),
Err(e) => println!(" ✗ Error: {:?}", e),
}
println!("\n8. Quantifier Domain Information:");
let expr = TLExpr::exists("x", "Person", TLExpr::pred("Person", vec![Term::var("x")]));
let domains = expr.referenced_domains();
println!(" Expression: ∃x:Person. Person(x)");
println!(" Referenced domains: {:?}", domains);
println!("\n=== Example Complete ===");
Ok(())
}