The universal automaton is failing to accept identical strings like accepts("test", "test"). The transition fails at step 3 because all positions have exhausted the error budget by step 2.
The bit vector positioning and offset semantics are misaligned. Let me trace through the failing case:
Word: "test"
Subword: "$$test" (positions -1, 0, 1, 2, 3, 4 relative to input position 1)
Bit vector: [false, false, true, false, false, true]
Current state: {I+0#0}
From position I+0#0:
Expected behavior: Since we're at word position 1 and input char='t' matches word[1]='t', we should advance WITHOUT error.
Actual behavior: The code checks bit_vector.starts_with_one() which is FALSE because the bit vector starts with [false, false, ...]. The match is at position 2, not position 0!
The problem is that the bit vector index doesn't directly correspond to the offset.
For position I+offset#errors at input position k:
In our case:
The match check needs to account for the offset within the bit vector window:
// Current (WRONG):
if bit_vector.starts_with_one() {
// Match at position 1
if let Ok(succ) = Self::new_i(offset, errors, max_distance) {
successors.push(succ);
}
return successors;
}
Should be:
// Check if there's a match at the current position
// For I+offset#errors at input k, word position i = offset + k
// In bit vector s_n(w,k), this corresponds to index: n + offset
let match_index = (max_distance as i32 + offset) as usize;
if match_index < bit_vector.len() && bit_vector.get(match_index) == Some(true) {
// Match at current position - advance without error
if let Ok(succ) = Self::new_i(offset, errors, max_distance) {
successors.push(succ);
}
return successors;
}
Wait, but that's not quite right either because get() might not exist...
Actually, let me reconsider. The thesis says:
δ^D,ε_e(i#e, b) where b is the bit vector
The position i#e is a concrete position (not universal). The universal position I+t#e gets converted:
But the bit vector b is computed as β(x, s_n(w, k)) where s_n starts at position k-n.
So for I+t#e at input k:
YES! The match index should be offset + n.
Let's verify with our example:
Perfect! The formula is: match_index = offset + n
The starts_with_one() check is fundamentally wrong. We need to check the bit at position offset + n.
Additionally, for the "skip to match" logic, we need to calculate the correct j value relative to the current position, not relative to the start of the bit vector.
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 |