Date: 2025-11-19 Purpose: Analyze all 13 production rules to prove pattern overlap preservation Goal: Replace admit at position_skipping_proof.v:2114
The Rust implementation uses 13 production rules (not the full 56 Zompist rules):
Total rule pairs to analyze: 13 × 13 = 169 pairs
[Consonant('c'), Consonant('h')] (length 2)[Digraph('c', 'h')] (length 1)Anywhere[Consonant('s'), Consonant('h')] (length 2)[Digraph('s', 'h')] (length 1)Anywhere[Consonant('p'), Consonant('h')] (length 2)[Consonant('f')] (length 1)Anywhere[Consonant('c')] (length 1)[Consonant('s')] (length 1)BeforeVowel(['e', 'i'])[Consonant('c')] (length 1)[Consonant('k')] (length 1)Anywhere[Consonant('g')] (length 1)[Consonant('j')] (length 1)BeforeVowel(['e', 'i'])[Vowel('e')] (length 1)[Silent] (length 1)Final[Consonant('g'), Consonant('h')] (length 2)[Silent] (length 1)Anywhere[Consonant('t'), Consonant('h')] (length 2)[Consonant('t')] (length 1)Anywhere[Consonant('q'), Consonant('u')] (length 2)[Consonant('k'), Consonant('w')] (length 2)Anywhere[Consonant('k'), Consonant('w')] (length 2)[Consonant('q'), Consonant('u')] (length 2)Anywhere[Consonant('x')] (length 1)[Consonant('y'), Consonant('y')] (length 2)Anywhere[Consonant('y')] (length 1)[Consonant('z')] (length 1)AnywhereContractions (5 rules): Pattern longer than replacement
Substitutions (6 rules): Same length
Expansions (1 rule): Replacement longer than pattern
Position-Independent (12 rules): Safe for overlap preservation
Anywhere (9 rules): 1, 2, 3, 21, 34, 100, 101, 102, 200, 201BeforeVowel (2 rules): 20, 22Position-Dependent (1 rule): Requires special handling
Final (1 rule): 33Single-phone patterns (5 rules):
Two-phone patterns (6 rules):
For Axiom 2, we need to prove that for any two rules r_applied and r:
If
rdoesn't match at positionp < posin strings, andr_appliedis applied atposwherep < pos < p + length(pattern r), thenrstill doesn't match atpin the results'.
For position-independent contexts, the critical case is when:
i_left is at position i_left >= posThis requires: replacement(r_applied) cannot accidentally match pattern(r) in the overlap region.
Case 1.1: Disjoint patterns (no overlapping phones)
Case 1.2: Context disjoint
BeforeVowel(['e','i']) vs Final - mutually exclusiveCase 1.3: Deletion rules as r_applied
r_applied produces Silent, it cannot match non-Silent patternsCase 2.1: Replacement too short to match pattern
length(replacement r_applied) < length(pattern r), cannot matchCase 2.2: No phone overlap in replacement and pattern
For remaining pairs, check computationally:
replacement(r_applied) contain subsequence matching pattern(r)?Will use computational decision procedure in Coq.
Fixpoint check_pair_safe (r1 r2: RewriteRule) : bool :=
(* Check if r1's replacement can match r2's pattern *)
Lemma check_pair_safe_correct:
forall r1 r2,
check_pair_safe r1 r2 = true ->
(* Then replacement r1 cannot match pattern r2 in overlap *)
Definition all_production_rules_safe :=
forallb (fun '(r1, r2) => check_pair_safe r1 r2)
(list_prod production_rules production_rules).
Compute all_production_rules_safe. (* Should reduce to 'true' *)
/home/dylon/Workspace/f1r3fly.io/liblevenshtein-rust/src/phonetic/rules.rs/home/dylon/Workspace/f1r3fly.io/liblevenshtein-rust/docs/verification/phonetic/position_skipping_proof.v:2114/home/dylon/Workspace/f1r3fly.io/liblevenshtein-rust/docs/verification/phonetic/zompist_rules.vStatus: Step 1 complete - all 13 rules documented Next: Build and classify 169-pair interaction matrix
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 |