You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Repeated parses of the same sentence could yield different trees
whenever the parse forest contained subtrees with exactly equal
reduction scores. The root cause was State::getHash() in eparser.cpp
XOR-ing raw heap pointers (m_pProd, m_pw) into the hash: the Column
hash-bin enumeration order then varied with malloc addresses, changing
the order of addFamily() calls when building the SPPF, and thereby
which equal-score family the reducer's index-based tie-breaker picked.
- eparser.h/eparser.cpp: make State::getHash() content-based, using
Production::getId() and a new Label::getHash()/Node::getHash()
(nonterminal index, dot, production id, token span) instead of
pointer values. State equality is unchanged.
- grammar.py: hash Terminal and Nonterminal by their creation-order
sequence number instead of id(), so that set/dict iteration order
over grammar items is stable across processes and PYTHONHASHSEED
values. The cached _hash snapshot is kept separate from _index,
which is renumbered after the grammar is read.
- test_parse.py: add test_deterministic_reduction with sentences
that previously flipped between equal-score parses (verified to
fail against the old parser core).
- test_native_matching.py: update a comment that documented the old
nondeterministic tie-breaking.
Parse results are now stable across repeated parses, processes and
hash seeds. Note that this can change which of two equally-scored
parses is returned, compared to earlier versions.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
0 commit comments