Date: 2025-11-13 Status: Phase 1 COMPLETE, Phase 2 IN PROGRESS
Implement transposition and merge/split operations for UniversalAutomaton to unblock GeneralizedAutomaton Phase 2d.
Changes to PositionVariant trait (position.rs:87-103):
pub trait PositionVariant: Clone + fmt::Debug + PartialEq + Eq + std::hash::Hash {
/// State type for this variant
type State: Clone + fmt::Debug + PartialEq + Eq + std::hash::Hash + Default;
fn variant_name() -> &'static str;
}
Key Achievement: Added State associated type to allow variants to track additional state.
TranspositionState (position.rs:119-133):
#[derive(Clone, Debug, PartialEq, Eq, Hash, Default)]
pub enum TranspositionState {
#[default]
Usual, // Regular position i#e
Transposing, // Transposition state i#e_t
}
MergeSplitState (position.rs:151-165):
#[derive(Clone, Debug, PartialEq, Eq, Hash, Default)]
pub enum MergeSplitState {
#[default]
Usual, // Regular position i#e
Splitting, // Split state i#e_s
}
Variant Implementations:
Standard: type State = () (zero-sized, no overhead)Transposition: type State = TranspositionStateMergeAndSplit: type State = MergeSplitStateUpdated enum (position.rs:197-233):
pub enum UniversalPosition<V: PositionVariant> {
INonFinal {
offset: i32,
errors: u8,
variant_state: V::State, // Was: variant: PhantomData<V>
},
MFinal {
offset: i32,
errors: u8,
variant_state: V::State,
},
}
API Changes:
PhantomData<V>variant_state: V::State fieldV::State::default()With custom variant state (position.rs:350-431):
pub fn new_i_with_state(
offset: i32,
errors: u8,
max_distance: u8,
variant_state: V::State,
) -> Result<Self, PositionError>
pub fn new_m_with_state(
offset: i32,
errors: u8,
max_distance: u8,
variant_state: V::State,
) -> Result<Self, PositionError>
Accessor method:
pub fn variant_state(&self) -> &V::State
All 156 Universal automaton tests pass:
$ cargo test --lib universal
test result: ok. 156 passed; 0 failed; 0 ignored; 0 measured
Backward Compatibility: Fully maintained for Standard variant (zero-size state).
Goal: Add transposition-specific successor generation
Approach: Specialize successors() method for Transposition variant
From Mitankin's Thesis (Definition 7, Page 16):
For regular positions i#e (Usual state):
δ^D,t_e(i#e, b) = δ^D,ε_e(i#e, b) ∪ {
{(i+1)#(e+1)_t} if b[1] = 0 ∧ e < n (enter transposition state)
}
For transposition state i#e_t (Transposing):
δ^D,t_e(i#e_t, b) = {
{(i+2)#e} if b[1] = 1 (complete transposition - chars swapped)
∅ otherwise (transposition failed)
}
Implementation Strategy:
impl UniversalPosition<Transposition> {
pub fn successors(
&self,
bit_vector: &CharacteristicVector,
max_distance: u8,
) -> Vec<Self> {
match self {
Self::INonFinal { offset, errors, variant_state } => {
match variant_state {
TranspositionState::Usual => {
// 1. Get standard successors
let mut successors = Self::successors_i_type_standard(...);
// 2. Add transposition initiation if no match
let match_index = (max_distance as i32 + offset) as usize;
if match_index < bit_vector.len()
&& !bit_vector.is_match(match_index)
&& errors < max_distance
{
// Enter transposition state: (i+1)#(e+1)_t
if let Ok(trans) = Self::new_i_with_state(
offset + 1,
errors + 1,
max_distance,
TranspositionState::Transposing
) {
successors.push(trans);
}
}
successors
}
TranspositionState::Transposing => {
// In transposition state: check if next char matches previous
let match_index = (max_distance as i32 + offset) as usize;
if match_index < bit_vector.len()
&& bit_vector.is_match(match_index)
{
// Complete transposition: (i+2)#e
vec![Self::new_i_with_state(
offset + 1, // I^ε: (i+2)#e → I+(i+1)#e
errors,
max_distance,
TranspositionState::Usual
).ok().into_iter().collect()]
} else {
// Transposition failed
vec![]
}
}
}
}
Self::MFinal { ... } => {
// Similar logic for M-type
...
}
}
}
}
Challenge: Need to handle conversion from standard successors (which have () state) to transposition successors (which need TranspositionState).
Solution: Use generic helpers or match on variant type when creating successors.
Similar to transposition, but for merge and split operations.
Transposition Tests:
#[test]
fn test_transposition_adjacent_swap() {
let automaton = UniversalAutomaton::<Transposition>::new(2);
assert!(automaton.accepts("test", "etst")); // swap 't' and 'e'
assert!(automaton.accepts("test", "tset")); // swap 'e' and 's'
}
#[test]
fn test_transposition_state_transition() {
// Test entering and exiting transposition state
let pos = UniversalPosition::<Transposition>::new_i(0, 0, 2).unwrap();
// ... verify state transitions
}
Problem: Current successors() is generic over V: PositionVariant but needs variant-specific logic.
Options:
PositionVariant to compute successorssuccessors() for each variant via impl UniversalPosition<Transposition>variant_state inside generic methodRecommendation: Option B - clearest separation of concerns.
Problem: Transposition needs to include standard successors plus transposition-specific ones.
Solution: Make successors_i_type_standard() and successors_m_type_standard() create positions with generic state, then convert.
Question: How to display transposition state?
Answer: Extend Display to show state: I + 0#1_t for transposition state.
State associated type to PositionVariantStandard implementationTranspositionState and Transposition implementationMergeSplitState and MergeAndSplit implementationUniversalPosition enum structurenew_i() constructornew_m() constructornew_i_with_state() and new_m_with_state() constructorsvariant_state() accessorTo complete transposition implementation:
Implement successors() for Transposition variant (~2-3 hours)
impl UniversalPosition<Transposition> blockAdd transposition tests (~1 hour)
Implement merge/split (~2-3 hours)
Update GeneralizedAutomaton (~2 hours)
Total Remaining Time: ~7-9 hours
What Changed:
UniversalPosition now has variant_state: V::State instead of variant: PhantomData<V>new_i_with_state() and new_m_with_state()variant_state() accessorImpact:
() is zero-sized)Mitigation:
Standard variant works unchangednew_i, new_m) still work the same wayPhase 1 (Complete):
State associated type to PositionVariantTranspositionState and MergeSplitState enumsUniversalPosition to store variant statePhase 2 (Next):
Phase 3 (Future):
Phase 4 (Future):
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 |