use ipfrs_tensorlogic::ir::{Constant, Predicate, Rule, Term};
use ipfrs_tensorlogic::proof_storage::{
ProofAssembler, ProofCompressor, ProofFragment, ProofFragmentStore, ProofMetadata,
};
fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("=== Proof Storage and Compression Example ===\n");
let mut store = ProofFragmentStore::new();
println!("--- Creating Proof Fragments ---");
println!("Adding fact fragments...");
let fact1 = ProofFragment::fact(Predicate::new(
"parent".to_string(),
vec![
Term::Const(Constant::String("alice".to_string())),
Term::Const(Constant::String("bob".to_string())),
],
));
let fact2 = ProofFragment::fact(Predicate::new(
"parent".to_string(),
vec![
Term::Const(Constant::String("bob".to_string())),
Term::Const(Constant::String("charlie".to_string())),
],
));
let fact3 = ProofFragment::fact(Predicate::new(
"parent".to_string(),
vec![
Term::Const(Constant::String("alice".to_string())),
Term::Const(Constant::String("david".to_string())),
],
));
let fact4 = ProofFragment::fact(Predicate::new(
"parent".to_string(),
vec![
Term::Const(Constant::String("alice".to_string())),
Term::Const(Constant::String("bob".to_string())),
],
));
let id1 = store.add(fact1);
let id2 = store.add(fact2);
let id3 = store.add(fact3);
let id4 = store.add(fact4);
println!("Added {} fact fragments", store.len());
println!(" Fragment IDs: {}, {}, {}, {}", id1, id2, id3, id4);
println!("\nCreating rule-based proof fragment...");
let grandparent_rule = Rule::new(
Predicate::new(
"grandparent".to_string(),
vec![Term::Var("X".to_string()), Term::Var("Z".to_string())],
),
vec![
Predicate::new(
"parent".to_string(),
vec![Term::Var("X".to_string()), Term::Var("Y".to_string())],
),
Predicate::new(
"parent".to_string(),
vec![Term::Var("Y".to_string()), Term::Var("Z".to_string())],
),
],
);
let mut grandparent_proof = ProofFragment::with_rule(
Predicate::new(
"grandparent".to_string(),
vec![
Term::Const(Constant::String("alice".to_string())),
Term::Const(Constant::String("charlie".to_string())),
],
),
&grandparent_rule,
vec![], vec![
(
"X".to_string(),
Term::Const(Constant::String("alice".to_string())),
),
(
"Y".to_string(),
Term::Const(Constant::String("bob".to_string())),
),
(
"Z".to_string(),
Term::Const(Constant::String("charlie".to_string())),
),
],
);
println!("\n--- Adding Metadata ---");
grandparent_proof.metadata = ProofMetadata::new()
.with_created_at(1234567890)
.with_created_by("example_user".to_string())
.with_complexity(3)
.with_depth(2);
println!("Adding metadata to grandparent fragment:");
println!(" Created at: {:?}", grandparent_proof.metadata.created_at);
println!(" Created by: {:?}", grandparent_proof.metadata.created_by);
println!(" Complexity: {:?}", grandparent_proof.metadata.complexity);
println!(" Depth: {}", grandparent_proof.metadata.depth);
let id5 = store.add(grandparent_proof);
println!("\nAdded rule-based fragment with metadata: {}", id5);
println!("Total fragments in store: {}", store.len());
println!("\n--- Querying Fragments ---");
let parent_fragments = store.find_by_conclusion("parent");
println!(
"Found {} fragments with 'parent' conclusion",
parent_fragments.len()
);
let grandparent_fragments = store.find_by_conclusion("grandparent");
println!(
"Found {} fragments with 'grandparent' conclusion",
grandparent_fragments.len()
);
println!("\n--- Proof Verification ---");
let assembler = ProofAssembler::new(&store);
if let Some(fragment) = store.get(&id1) {
let proof = fragment.to_proof(vec![]);
let is_valid = assembler.verify(&proof);
println!(
"Fact proof verification: {}",
if is_valid { "✓ Valid" } else { "✗ Invalid" }
);
}
println!("\n--- Proof Compression ---");
println!("Before compression:");
println!(" Total fragments: {}", store.len());
let mut compressor = ProofCompressor::new();
let stats = compressor.compress(&mut store);
println!("\nCompression statistics:");
println!(" Original count: {}", stats.original_count);
println!(" Compressed count: {}", stats.compressed_count);
println!(" Shared subproofs: {}", stats.shared_subproofs);
println!(" Size reduction: {} bytes", stats.size_reduction);
println!(
" Compression ratio: {:.2}%",
stats.compression_ratio() * 100.0
);
println!(" Space savings: {:.2}%", stats.space_savings());
println!("\nAfter compression:");
println!(" Total fragments: {}", store.len());
println!("\n--- Delta Encoding ---");
let base_proof = ProofFragment::fact(Predicate::new(
"likes".to_string(),
vec![
Term::Const(Constant::String("alice".to_string())),
Term::Const(Constant::String("pizza".to_string())),
],
));
let new_proof = ProofFragment::fact(Predicate::new(
"likes".to_string(),
vec![
Term::Const(Constant::String("bob".to_string())),
Term::Const(Constant::String("pizza".to_string())),
],
));
let delta = compressor.compute_delta(&base_proof, &new_proof);
println!(
"Delta between base and new proof: {} fragments",
delta.len()
);
let same_delta = compressor.compute_delta(&base_proof, &base_proof);
println!(
"Delta between identical proofs: {} fragments (should be 0)",
same_delta.len()
);
println!("\n--- Storage Statistics ---");
println!("Final store statistics:");
println!(" Total fragments: {}", store.len());
let fact_count =
store.find_by_conclusion("parent").len() + store.find_by_conclusion("likes").len();
let derived_count = store.find_by_conclusion("grandparent").len();
println!(" Fact proofs: ~{}", fact_count);
println!(" Derived proofs: {}", derived_count);
println!("\n--- Fragment Indexing ---");
println!("Fragments by predicate:");
let predicates = vec!["parent", "grandparent", "likes"];
for pred in &predicates {
let count = store.find_by_conclusion(pred).len();
if count > 0 {
println!(" {}: {} fragments", pred, count);
}
}
println!("\n--- Summary ---");
println!("✓ Created {} proof fragments", stats.original_count);
println!("✓ Added metadata to proofs");
println!("✓ Verified proof validity");
println!(
"✓ Compressed proofs with {:.1}% space savings",
stats.space_savings()
);
println!("✓ Implemented delta encoding");
println!("✓ Indexed fragments by conclusion");
println!("\n✓ Example completed successfully!");
Ok(())
}