Project Status: 🚧 Phase 1 & 9 Complete - Foundation + Contextual Completion Proof Assistant: Rocq (formerly Coq) Started: 2025-11-17 Team: Formal Verification Team
This directory contains formal proofs of correctness for the Levenshtein automata implementation in liblevenshtein-rust. We use the Rocq proof assistant to mechanically verify that the algorithms correctly implement the theory described in docs/research/weighted-levenshtein-automata/README.md.
We follow a specification-first methodology:
Theory → Formalization → Proof → Specification → Implementation Fix
Three tests related to generalized automata are currently failing:
test_phonetic_split_multipletest_phonetic_split_with_standard_opstest_new_i_splitting_invalidTraditional debugging has been expensive and inconclusive. These failures likely stem from subtle interactions between:
Formal verification provides:
/var/tmp/debug/f1r3node/rocq/liblevenshtein/ # Rocq proof files
├── Core.v # Foundational definitions ✓
├── Invariants.v # Position invariant proofs ✓
├── Operations.v # Standard operations ✓
├── Transitions.v # State transitions ✓
├── PhoneticOperations.v # Phonetic split operations ✓
├── SubwordOperations.v # Subword operation model ✓
└── _CoqProject # Build configuration
docs/formal-verification/ # Human-readable documentation
├── README.md # This file
├── STATUS.md # Current proof status
├── VALIDATION_MATRIX.md # Rust/proof validation matrix
├── FINDINGS.md # Formal audit findings
├── 03_standard_operations.md # Standard operation proof notes
├── 04_phonetic_operations.md # Phonetic operation proof notes
└── proofs/ # Detailed proof documentation
├── 01_subsumption_properties.md # Phase 1 ✓
├── 02_position_invariants.md # Phase 2 ✓
└── 06_contextual_completion/ # Phase 9 ✓
├── README.md # Category overview
├── 01_context_visibility.md # Context tree visibility
├── 02_draft_consistency.md # UTF-8 draft buffer operations
├── 03_checkpoint_stack.md # Undo/redo correctness
├── 04_query_fusion.md # Completion result correctness
├── 05_distance_correctness.md # Levenshtein distance algorithm
├── 06_hierarchical_visibility.md # Scope isolation
└── 07_finalization.md # Atomicity of draft→dictionary
Completed: 2025-11-17
rocq/liblevenshtein/)Core.v - Foundational definitions (585 lines)
~ (p \sqsubseteq p)$p_{1} \sqsubseteq p_{2} \to p_{2} \sqsubseteq p_{3} \to p_{1} \sqsubseteq p_{3}$\text{variant}(p_{1}) \ne \text{variant}(p_{2}) \to ~ (p_{1} \sqsubseteq p_{2})$01_subsumption_properties.md, 600+ lines)$ cd rocq/liblevenshtein
$ coqc -R . LevensteinAutomata Core.v
# Success! Generated Core.vo (53,419 bytes)
All proofs compile and verify successfully under Rocq 9.x.
| Theorem | Statement | Significance | Status |
|---|---|---|---|
| Irreflexivity | $\forall p, \lnot (p \sqsubseteq p)$ | No position subsumes itself | ✅ Proven |
| Transitivity | $p_{1}\sqsubseteq p_{2} \land p_{2}\sqsubseteq p_{3} \to p_{1}\sqsubseteq p_{3}$ | Subsumption chains compose | ✅ Proven |
| Variant Restriction | $\text{variant}(p_{1})\ne \text{variant}(p_{2}) \to \lnot (p_{1}\sqsubseteq p_{2})$ | Different types don't subsume | ✅ Proven |
| Anti-Symmetry | $p_{1}\sqsubseteq p_{2} \land p_{2}\sqsubseteq p_{1} \to \text{False}$ | No cycles in subsumption | ✅ Proven (derived) |
Install Rocq (Coq):
# Arch Linux
sudo pacman -S coq
# Ubuntu/Debian
sudo apt-get install coq
# Via opam (OCaml package manager)
opam install coq
# Verify installation
coqc --version # Should show 8.17+ or 9.x (Rocq)
Recommended tools:
cd /home/dylon/Workspace/f1r3fly.io/liblevenshtein-rust/rocq/liblevenshtein
# Compile all proofs
coqc -R . LevensteinAutomata Core.v
# Or use make (when Makefile generated)
coq_makefile -f _CoqProject -o Makefile
make
Start with the documentation:
docs/formal-verification/README.md (this file)docs/formal-verification/proofs/01_subsumption_properties.mdrocq/liblevenshtein/Core.v in ProofGeneral/VSCoqTip: Proofs have extensive inline comments explaining each step.
Using ProofGeneral (Emacs):
emacs rocq/liblevenshtein/Core.v
# Use C-c C-n to step forward through proof
# Use C-c C-u to step backward
# Use C-c C-RET to process to cursor
Using VSCoq (VS Code):
code rocq/liblevenshtein/Core.v
# Use Alt+Down to step forward
# Use Alt+Up to step backward
# Hover over terms to see types
Document first: Create markdown file in docs/formal-verification/proofs/
Formalize: Add definitions and theorem statements to appropriate .v file
Prove: Develop proof incrementally
lia, auto, destruct, inductionVerify: Compile and check
coqc -R . LevensteinAutomata YourFile.v
Document: Update markdown with final proof
Comments:
Structure:
subsumes_requires_error_gap)Tactics:
lia for arithmetic (auto-solves linear inequalities)destruct for case analysisinduction for recursive structuresExample:
(**
THEOREM: Subsumption is Irreflexive
INTUITION: No position can subsume itself because subsumption
requires errors(p₂) > errors(p₁), but for p⊑p we'd
need errors(p) > errors(p), which is impossible.
PROOF STRATEGY: Direct from definition + lia solver
REFERENCE: Part II, Section 3.1 of weighted-levenshtein-automata doc
*)
Theorem subsumes_irreflexive : forall p, ~ (p ⊑ p).
Proof.
intros p [_ [Hcontr _]]. (* Extract errors(p) > errors(p) *)
lia. (* Contradiction *)
Qed.
After proving properties, add property-based tests to Rust:
#[cfg(test)]
mod formal_verification_tests {
use super::*;
use proptest::prelude::*;
// Property: Irreflexivity (from Core.v)
proptest! {
#[test]
fn subsumption_irreflexive(
offset in any::<i32>(),
errors in 0u8..10,
variant in any::<PositionVariant>()
) {
let pos = create_position(variant, offset, errors);
assert!(!subsumes(&pos, &pos, errors));
}
}
// Property: Transitivity (from Core.v)
proptest! {
#[test]
fn subsumption_transitive(/* ... */) {
// If p1 ⊑ p2 and p2 ⊑ p3, then p1 ⊑ p3
// ...
}
}
}
Goal: Prove position constructors maintain invariants
Deliverables:
Invariants.v: Formalize invariant checkingnew_i correctnessnew_m correctness02_position_invariants.mdKey theorems:
new_i_valid: Valid inputs → valid I-type positionnew_m_valid: Valid inputs → valid M-type positioninvariant_decidable: Invariant checking is computableGoal: Prove standard edit operations correct
Deliverables:
Operations.v: Operation type definitionsTransitions.v: Successor computation03_standard_operations.mdKey theorems:
successor_match_valid: Match produces valid successorssuccessor_substitute_valid: Substitute preserves invariantsoperation_cost_correct: Cost accounting is accurateGoal: Extend to transposition and merge
Deliverables:
Transitions.v with transposition04_multi_step_operations.mdDefer: Split operations (phonetic) to Phase 8+
Key theorems:
transposition_entry_sound: Entry → completion existstransposition_complete_valid: Completion produces valid positionmerge_correct: Direct 2→1 merge is soundGoal: Prove state minimization algorithm correct
Deliverables:
State.v: State representation and anti-chainadd_position algorithm05_state_management.mdKey theorems:
add_position_preserves_anti_chain: Main correctness theoremanti_chain_decidable: Anti-chain checking is computablestate_size_bound: $\mathcal{O}(n^{2})$ state sizeGoal: Extract formal spec from proofs
Deliverables:
SPECIFICATION.md: Formal specification documentGoal: Fix Rust code to match proven spec
Deliverables:
DISCREPANCIES.md: Documented differencesFIX_REPORT.md: Changes made with justificationIMPLEMENTATION_GUIDE.md: Maintenance guideExpected outcome: Standard operation tests pass
Phonetic operations (fractional weights):
Full automaton acceptance:
accepts(word, query, n) ⟺ $\text{distance}(\text{word}, \text{query}) \le n$Extraction to verified implementation:
Completed: 2025-01-21
Goal: Establish formal foundation for contextual completion engine used by rholang-language-server
Deliverables:
proofs/06_contextual_completion/)visible_contexts() returns all ancestors in orderchar type guaranteescomplete() returns union of draft + finalized\mathcal{O}(n\cdot m)$ implementation matches Wagner-FischerKey Insights:
Verification Status:
Files Created:
proofs/06_contextual_completion/README.mdproofs/06_contextual_completion/01_context_visibility.mdproofs/06_contextual_completion/02_draft_consistency.mdproofs/06_contextual_completion/03_checkpoint_stack.mdproofs/06_contextual_completion/04_query_fusion.mdproofs/06_contextual_completion/05_distance_correctness.mdproofs/06_contextual_completion/06_hierarchical_visibility.mdproofs/06_contextual_completion/07_finalization.mdPrimary reference:
docs/research/weighted-levenshtein-automata/README.md (765 lines)
Supporting documents:
docs/generalized/phase2d_completion_report.md - Implementation statusdocs/generalized/phase3b_requirements.md - Phonetic operations (400+ lines)docs/algorithms/README.md - Algorithm layer documentation (504 lines)Core files:
src/transducer/generalized/position.rs (757 lines) - Position typessrc/transducer/generalized/state.rs (1600+ lines) - State managementsrc/transducer/generalized/automaton.rs (1700+ lines) - Main automatonsrc/transducer/generalized/subsumption.rs (334 lines) - Subsumption checksTest files:
src/transducer/generalized/automaton.rs:1200-1700 - Unit teststests/integration_tests.rs - Integration teststests/proptest_*.rs - Property-based testsRocq/Coq:
Similar Projects:
/var/tmp/debug/f1r3node/docs/formal-verification/coq/ - Rholang proofs (13 files)Papers:
Follow the style established in Core.v:
Scope issues (Z vs nat):
(* Wrong: *)
errors p <= max_distance p (* Interpreted as Z.le with Z_scope open *)
(* Right: *)
(errors p <= max_distance p)%nat (* Explicitly use nat scope *)
Type mismatches:
(* Wrong: *)
assert (errors p2 > errors p1) by lia. (* nat in scope that expects Z *)
(* Right: *)
assert (Hgap: (errors p2 > errors p1)%nat). { lia. }
Triangle inequality:
(* Wrong: *)
apply Z.abs_triangle. (* Goal doesn't match lemma form *)
(* Right: *)
replace (x - y) with ((x - z) + (z - y)) by lia.
apply Z.abs_triangle.
ProofGeneral not responding:
M-x customize-variable proof-prog-nameVSCoq errors:
_CoqProject is in workspace rootcoqAdded:
Verified:
Status: ✅ All proofs compile, Phase 1 objectives met
This formal verification work is part of the liblevenshtein-rust project and follows the same license (MIT/Apache-2.0).
/var/tmp/debug/f1r3node/ Rholang proofsLast Updated: 2025-11-17 Next Review: After Phase 2 completion
Can you improve this documentation?Edit on GitHub
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |