#![cfg(feature = "verification")]
use elicitation::verification::contracts::{I32Positive, StringNonEmpty, VecNonEmpty};
use elicitation::verification::{Contract, DynContract, VerifierBackend, compose};
fn main() {
println!("=== Multi-Verifier Contract Example ===\n");
println!("1. Runtime Verifier Selection");
let value = 42i32;
let kani_backend =
VerifierBackend::Kani(Box::new(I32Positive) as Box<dyn DynContract<i32, i32>>);
println!(
" Kani backend precondition: {}",
kani_backend.check_precondition(&value)
);
#[cfg(feature = "verify-creusot")]
{
use elicitation::verification::contracts::creusot::CreusotI32Positive;
let creusot_backend = VerifierBackend::Creusot(
Box::new(CreusotI32Positive) as Box<dyn DynContract<i32, i32>>
);
println!(
" Creusot backend precondition: {}",
creusot_backend.check_precondition(&value)
);
}
#[cfg(feature = "verify-prusti")]
{
use elicitation::verification::contracts::prusti::PrustiI32Positive;
let prusti_backend =
VerifierBackend::Prusti(Box::new(PrustiI32Positive) as Box<dyn DynContract<i32, i32>>);
println!(
" Prusti backend precondition: {}",
prusti_backend.check_precondition(&value)
);
}
#[cfg(feature = "verify-verus")]
{
use elicitation::verification::contracts::verus::VerusI32Positive;
let verus_backend =
VerifierBackend::Verus(Box::new(VerusI32Positive) as Box<dyn DynContract<i32, i32>>);
println!(
" Verus backend precondition: {}",
verus_backend.check_precondition(&value)
);
}
println!();
println!("2. Contract Refinement Workflow");
println!(" Step 1: Start with Kani (fast feedback)");
let hello = String::from("hello");
println!(" StringNonEmpty: {}", StringNonEmpty::requires(&hello));
println!(" Step 2: Refine with composition");
let composed = compose::and(StringNonEmpty, StringNonEmpty);
println!(
" Composed contract: {}",
composed.check_requires(&hello)
);
println!(" Step 3: Switch to stronger verifier for production");
#[cfg(feature = "verify-creusot")]
{
use elicitation::verification::contracts::creusot::CreusotStringNonEmpty;
println!(
" Creusot contract: {}",
CreusotStringNonEmpty::requires(&hello)
);
}
println!();
println!("3. Choosing the Right Verifier");
println!();
println!(" ๐น Development Phase:");
println!(" Use Kani - Fast feedback, easy setup");
println!(" Verify basic properties quickly");
println!();
println!(" ๐น Testing Phase:");
println!(" Use Prusti - Memory safety, ownership");
println!(" Catch Rust-specific issues");
println!();
println!(" ๐น Production Phase:");
println!(" Use Creusot or Verus - Formal guarantees");
println!(" Prove correctness of critical code");
println!();
println!("4. Contract Composition Patterns");
let vec = vec![1, 2, 3];
println!(" AND: Both must hold");
let vec_contract1 = VecNonEmpty::<i32>::new();
let vec_contract2 = VecNonEmpty::<i32>::new();
let and_contract = compose::and(vec_contract1, vec_contract2);
println!(" Result: {}", and_contract.check_requires(&vec));
println!(" OR: Either can hold");
let vec_contract3 = VecNonEmpty::<i32>::new();
let vec_contract4 = VecNonEmpty::<i32>::new();
let or_contract = compose::or(vec_contract3, vec_contract4);
println!(" Result: {}", or_contract.check_requires(&vec));
println!(" NOT: Inverts the contract");
let vec_contract5 = VecNonEmpty::<i32>::new();
let not_contract = compose::not(vec_contract5);
println!(" Result: {}", not_contract.check_requires(&vec));
println!();
println!("5. Migration Strategy");
println!();
println!(" Phase 1: Add default contracts (Kani)");
println!(" โ Quick to add");
println!(" โ Immediate value");
println!(" โ No dependencies");
println!();
println!(" Phase 2: Identify critical paths");
println!(" โ Performance-critical code");
println!(" โ Security-sensitive code");
println!(" โ Bug-prone algorithms");
println!();
println!(" Phase 3: Upgrade critical contracts");
println!(" โ Switch to Creusot/Prusti/Verus");
println!(" โ Add stronger properties");
println!(" โ Verify edge cases");
println!();
println!(" Phase 4: Continuous verification");
println!(" โ Run in CI/CD");
println!(" โ Prevent regressions");
println!(" โ Document guarantees");
println!();
println!("=== Verifier Comparison ===\n");
println!("โโโโโโโโโโโโโโฌโโโโโโโโโฌโโโโโโโโโโโฌโโโโโโโโโโโโโฌโโโโโโโโโโโโโโ");
println!("โ Verifier โ Speed โ Setup โ Coverage โ Use Case โ");
println!("โโโโโโโโโโโโโโผโโโโโโโโโผโโโโโโโโโโโผโโโโโโโโโโโโโผโโโโโโโโโโโโโโค");
println!("โ Kani โ โกโกโก โ Easy โ Symbolic โ Development โ");
println!("โ Prusti โ โกโก โ Medium โ Ownership โ Testing โ");
println!("โ Creusot โ โก โ Hard โ Functional โ Critical โ");
println!("โ Verus โ โกโก โ Hard โ SMT-based โ Research โ");
println!("โโโโโโโโโโโโโโดโโโโโโโโโดโโโโโโโโโโโดโโโโโโโโโโโโโดโโโโโโโโโโโโโโ");
println!();
println!("=== Best Practices ===\n");
println!("โ Start simple: Use Kani defaults first");
println!("โ Compose contracts: Build complex from simple");
println!("โ Test contracts: Verify they catch bugs");
println!("โ Document choices: Explain why each verifier");
println!("โ Gradual adoption: Don't try to verify everything");
println!("โ Profile verification: Measure time cost");
println!();
}