use tensorlogic_adapters::{Metadata, Provenance, SchemaBuilder};
fn main() {
println!("=== SchemaBuilder Example ===\n");
println!("=== Example 1: Basic Schema ===");
basic_schema();
println!();
println!("=== Example 2: Schema with Metadata ===");
schema_with_metadata();
println!();
println!("=== Example 3: Knowledge Graph Schema ===");
knowledge_graph_schema();
println!();
println!("=== Example 4: Schema Validation ===");
validated_schema();
}
fn basic_schema() {
let table = SchemaBuilder::new()
.domain("Person", 100)
.domain("Location", 50)
.domain("Event", 200)
.predicate("attends", vec!["Person", "Event"])
.predicate("held_at", vec!["Event", "Location"])
.predicate("knows", vec!["Person", "Person"])
.variable("x", "Person")
.variable("y", "Event")
.build()
.expect("unwrap");
println!("✓ Created schema with:");
println!(" {} domains", table.domains.len());
println!(" {} predicates", table.predicates.len());
println!(" {} variables", table.variables.len());
println!("\nDomains:");
for (name, domain) in &table.domains {
println!(" - {}: cardinality {}", name, domain.cardinality);
}
println!("\nPredicates:");
for (name, pred) in &table.predicates {
println!(" - {}: {:?}", name, pred.arg_domains);
}
}
fn schema_with_metadata() {
let mut person_meta = Metadata::new();
person_meta.add_tag("core");
person_meta.add_tag("entity");
person_meta.set_attribute("namespace", "org.example");
person_meta.provenance =
Some(Provenance::new("Alice", "2025-01-15T10:30:00Z").with_source("schema.yaml", Some(42)));
let table = SchemaBuilder::new()
.domain_with_metadata("Person", 100, person_meta)
.domain_with_desc("Location", 50, "Physical places")
.domain_with_desc("Organization", 75, "Companies and institutions")
.predicate_with_desc(
"works_at",
vec!["Person", "Organization"],
"Employment relationship",
)
.predicate_with_desc(
"located_in",
vec!["Organization", "Location"],
"Organization location",
)
.build()
.expect("unwrap");
println!("✓ Created schema with metadata");
if let Some(person) = table.get_domain("Person") {
println!("\nPerson domain:");
if let Some(meta) = &person.metadata {
println!(" Tags: {:?}", meta.tags);
println!(" Attributes: {:?}", meta.attributes);
if let Some(prov) = &meta.provenance {
println!(" Created by: {}", prov.created_by);
println!(" Created at: {}", prov.created_at);
}
}
}
if let Some(location) = table.get_domain("Location") {
if let Some(desc) = &location.description {
println!("\nLocation: {}", desc);
}
}
}
fn knowledge_graph_schema() {
let table = SchemaBuilder::new()
.domain("Entity", 1000)
.domain("Person", 500)
.domain("Organization", 200)
.domain("Document", 1000)
.domain("Topic", 100)
.domain("String", 10000)
.domain("Date", 365)
.subtype("Person", "Entity")
.subtype("Organization", "Entity")
.subtype("Document", "Entity")
.predicate("works_for", vec!["Person", "Organization"])
.predicate("authored", vec!["Person", "Document"])
.predicate("mentions", vec!["Document", "Entity"])
.predicate("about", vec!["Document", "Topic"])
.predicate("related_to", vec!["Entity", "Entity"])
.predicate("has_name", vec!["Entity", "String"])
.predicate("founded", vec!["Organization", "Date"])
.predicate("born", vec!["Person", "Date"])
.build()
.expect("unwrap");
println!("✓ Created knowledge graph schema");
println!("\nStatistics:");
println!(" Entity domains: {}", table.domains.len());
println!(" Relationships: {}", table.predicates.len());
let mut total_possible: usize = 0;
for pred in table.predicates.values() {
let mut pred_size: usize = 1;
for domain_name in &pred.arg_domains {
if let Some(domain) = table.get_domain(domain_name) {
pred_size *= domain.cardinality;
}
}
total_possible += pred_size;
}
println!(" Possible facts: ~{}", total_possible);
println!("\nSample predicates:");
for (name, pred) in table.predicates.iter().take(5) {
println!(" - {}: {:?}", name, pred.arg_domains);
}
}
fn validated_schema() {
println!("Valid schema:");
let result = SchemaBuilder::new()
.domain("Person", 100)
.domain("Location", 50)
.predicate("at", vec!["Person", "Location"])
.build_and_validate();
match result {
Ok(table) => {
println!(" ✓ Schema validated successfully");
println!(
" {} domains, {} predicates",
table.domains.len(),
table.predicates.len()
);
}
Err(e) => {
println!(" ✗ Validation failed: {}", e);
}
}
println!("\nInvalid schema (missing domain):");
let result = SchemaBuilder::new()
.predicate("at", vec!["Person", "UndefinedDomain"])
.build();
match result {
Ok(_) => println!(" ✗ Should have failed but succeeded"),
Err(e) => println!(" ✓ Caught error as expected: {}", e),
}
println!("\nProblematic schema (unused domain):");
let result = SchemaBuilder::new()
.domain("UsedDomain", 100)
.domain("UnusedDomain", 50)
.predicate("test", vec!["UsedDomain"])
.build_and_validate();
match result {
Ok(table) => {
use tensorlogic_adapters::SchemaAnalyzer;
let recommendations = SchemaAnalyzer::analyze(&table);
if recommendations.issues.is_empty() {
println!(" ✓ No issues found");
} else {
println!(" ⚠ Issues detected:");
for issue in &recommendations.issues {
println!(" - {}", issue.description());
}
}
}
Err(e) => {
println!(" ✗ Unexpected error: {}", e);
}
}
println!("\n=== Example Complete ===");
}