Faithful port of Python difflib.SequenceMatcher(None, a, b).ratio() — the
Ratcliff-Obershelp similarity Hindsight uses for entity name matching
(engine/entity_resolver.py:664).
ratio/2 returns 2.0 * M / T where M is the total number of matched
characters across the recursively-discovered longest matching blocks and
T = length(a) + length(b). Empty-vs-empty returns 1.0 (difflib's T == 0
special case).
Fidelity scope
CPython's SequenceMatcher has two knobs this port deliberately omits, both
provably inert for the entity-name domain it serves:
isjunk— Hindsight always passesNone, so no element is junk. With no junk, the DP below already yields maximal contiguous runs, and difflib's junk-extension loops never fire. Omitting them is exact, not approximate.- autojunk — difflib treats an element as junk when the second sequence
has more than 200 items and the element occupies >1% of them. Entity names
are far shorter than 200 characters, so autojunk never triggers. This port
does not implement it; feeding it a >200-char
bwith a hot character would diverge from difflib, which is out of scope by construction.
Operates on Unicode code points (String.to_charlist/1), matching Python's
per-character iteration over str. Pure and side-effect-free.
Summary
Functions
Ratcliff-Obershelp similarity ratio in [0.0, 1.0], byte-faithful to
difflib.SequenceMatcher(None, a, b).ratio() within the fidelity scope above.