42. The blend needs no grapheme-to-phoneme model, and German needed a fold¶
Context¶
ADR 0041 shipped paronomasia with a bound: it checks a displacement only when
the word that lands is itself in the pronouncing dictionary. The blends that
dominate the punning shopfront — Haarmonie, Hairitage, Föhnix,
Chaarisma, Haarchitektur — put a coined word there, and no pack here can
pronounce a word it has never seen. That ADR named phonemes.g2p as the
capability the family was blocked on, in the manner ADR 0015 prescribes: named
on the row, with no pack behind it.
The question then asked was whether to build it. Three routes were costed: espeak-ng as an out-of-tree GPL-3.0 plugin; a model learned from the 837,689 German Wiktionary entries, 134,000 CMUdict entries and 125,343 Lexique entries already shipped; or nothing.
Measurement first, and it changed the question. A blend is not an arbitrary string. The host word and the word spliced into it are both ordinary dictionary entries, so a blend can be verified as a derived form — the host recoverable behind it, the spliced word really present, and that word sounding like a stretch of the host — without ever pronouncing the coinage. Measured against the named targets, using nothing that is not already installed:
| coinage | host | spliced | distance |
|---|---|---|---|
| Föhnix | Phönix | Föhn | 0.000 |
| Hairitage | heritage | hair | 0.000 |
| Breadwinner | breadwinner | bread | 0.000 |
| Hairways | airways | hair | 0.333 |
| Haarmonie | Harmonie | Haar | 0.667 |
| Chaarisma | Charisma | Haar | 0.667 |
English worked immediately. German did not, and the reason was not g2p at all:
German vocalises a syllable-final /r/, so Haar is transcribed h aː ɐ̯ while
Harmonie opens h a ʁ. The same underlying segment, spelled two ways, and an
unweighted edit distance charges a full substitution for it — the cost ADR 0041
D3 admitted when it chose unweighted Levenshtein over a feature-weighted metric.
Decision¶
D1. No phonemes.g2p, and the name is retired rather than left standing.
The family it was named for is reachable without it. What remains out of reach
is not g2p-shaped: a host the lexicon does not carry (usually a proper noun —
Barbarella is absent from CMUdict) and the cross-lingual blend (Atmosph'air),
which needs phonemes.bilingual and would need it whatever g2p existed.
Recorded as a decision because the alternative was attractive and expensive.
espeak-ng costs a system binary, a GPL-3.0 quarantine and a distribution of its
own, and its output would still need mapping into each pack's notation — which
for English is ARPABET, so the mismatch is real work, not a wrapper. A learned
model costs no licence, but it is a statistical component in a project whose
whole claim is that its verdicts are decidable: at 90% accuracy one verdict in
ten is wrong for a reason nobody can see, which is a far worse failure than
today's MissingCapability, and it would have to be evaluated against the very
dictionaries it was trained on.
D2. portmanteau is its own row. paronomasia displaces a whole word;
a blend splices inside one. Different operations, different violations, and ADR
0007 is one module per procedure. Folding both into one row would have made its
catalogue definition describe two things, which is the drift ADR 0015 exists to
prevent.
D3. A per-language equivalence table, and it folds one thing.
core.phonetics.EQUIVALENT records symbols that are one segment in a language's
own notation. German gets {ʁ, ɐ̯, ɐ, r}. Vowel length is deliberately not
folded: aː and a are contrastive — Staat and Stadt — so collapsing
them would buy Haarmonie a distance of 0.000 by discarding a distinction the
language makes. It sits at 0.333 instead. English and French get no entries:
ARPABET has no vocalised-r symbol and Lexique's SAMPA maps to a single ʁ, so a
table for them would be a guess dressed as data.
D4. The window is searched, not aligned, and that is the row's weakest joint. Deciding which phonemes of the host the spliced letters cover would need grapheme-to-phoneme alignment, which this project does not have. The check asks instead whether the spliced word sounds like some window of the host of about the right length. That would accept a blend whose word matches a stretch somewhere other than where it was spliced. It is the strongest reading available without an aligner, and it is stated in the module docstring rather than left for a reader to discover.
D5. apply is not shipped, though kind says both. The figure is plainly
constructive, so misdescribing it as restrictive to match the implementation
would be the wrong direction. Generating a blend means choosing where to splice —
Deri and Knight's multitape-FST problem — and is its own piece of work.
describe_procedure will still report both; the docstring heads that off, as
larding and lipogrammatic_translation already do.
Consequences¶
Folding was verified additive before it shipped. All nine German pairs the
existing fixtures and domain phrases turn on — Kamm/Komm, Welle/Welt,
Zopf/Kopf, Glanz/Ganz and the rest — score identically with and without
it, and a test pins that. So this is not a re-reading of work already checked.
The prefilter had to learn the same fold, and briefly did not. shares_an_edge
compares first and last phonemes to decide what is worth measuring; unfolded, it
rejected Haar against Harmonie before the metric ever saw the pair. A
prefilter stricter than the measure behind it hides candidates the band would
have accepted, silently. It now folds too.
ADR 0041's phonemes.g2p note is now wrong and stays wrong on purpose. The
row's notes and module docstring named it as the blocker in good faith and the
measurement overturned it; paronomasia's notes now point here instead. The
older ADR is a record of what was decided when, not a document to keep tidy.
A coinage that is its own host is not a blend, and the data found that before a
reader would have. Crustacean contains crust; Breadwinner contains bread;
both satisfied an early draft at a spelling distance of 0.000, because nothing had
been spliced. That is the found pun, which paronomasia already excludes on the
grounds that it states no relation between two texts. The guard is
identical_to_host, and it exists because three trades' worth of authored blends
were run through the checker rather than admired.
Two things are still unreachable, and neither is g2p's fault. A proper-noun
host, which is most of the film and celebrity blends; and the cross-lingual
blend, which is a large share of the German salon window in practice — British
Hairways over a Berlin shop is English inside German, and phonemes.bilingual
is what that needs.
Coverage moves. 123 implemented rows become 124 and the catalogue 157 becomes 158; eight constructed cases take the corpus from 572 to 580. No case claims external provenance, for ADR 0041 D7's reason, which has not changed.