Weak endings need a full vowel; trailing sibilant is transparent

middle / unavoidable shared only a schwa+L tail — the weak-ending rule
firing on a reduced vowel. Weak endings now require a full final vowel
(infancy/see on IY stays). Surfaced that swimmers' plural -s blocked
its coda from nesting with finisher; a trailing sibilant is inflection,
so it's stripped from the coda tag — Wayne's chain stays whole, garbage
(JH) still stays out.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-08 02:58:03 -04:00
parent b76430caaf
commit 676a596a66
2 changed files with 15 additions and 0 deletions
+6
View File
@@ -344,6 +344,8 @@ def _final_coda_tag(pl: list[str]) -> str:
if p[-1].isdigit():
last = i
coda = "".join(_coda_class(DIGITS.sub("", p)) for p in pl[last + 1:])
if coda.endswith("S"):
coda = coda[:-1] # trailing plural/3rd-person sibilant is transparent
return coda or "."
@@ -398,6 +400,10 @@ def weak_end_key(word: str) -> str | None:
for i in range(len(pl) - 1, -1, -1):
if pl[i][-1].isdigit():
syl = [DIGITS.sub("", p) for p in pl[i:]]
if syl[0] in REDUCED:
return None # a bare schwa tail (-le, -able) rhymes
# everything; weak endings need a full final vowel
# (infancy/see on IY, not middle/unavoidable on AH-L)
out = [syl[0]] + [_coda_class(c) for c in syl[1:]]
return "w:" + " ".join(out)
return None
+9
View File
@@ -714,3 +714,12 @@ def test_garbage_javascript_dont_attach():
bg[t["g"]].add(res["lines"][t["l"]][t["s"]:t["e"]].lower())
dfam = next(s for s in bg.values() if "dollar" in s)
assert "garbage" not in dfam and "javascript" not in dfam
def test_weak_ending_needs_a_full_vowel():
# middle and unavoidable share only a schwa+L tail — too weak to rhyme
text = ("Wednesday has given up and admitted it's the middle\n"
"slightly apologetic and entirely unavoidable")
assert "middle" not in highlighted(text)
# but a full-vowel feminine ending still pairs (infancy/see on IY)
group_with("all I can see\nin my infancy", "see", "infancy")