Portfolio · Mechanism
A Deterministic English Fluency Layer
A ~50 KB cabinet of rule-based specialists that turn a typed semantic trace into fluent English. No neural network, no training, no GPU. Inflection, lemmatisation with etymological layering, article selection, verb conjugation. 104/104 tests pass. A reference implementation for the separation of semantic navigation and surface rendering.
A deterministic English fluency layer
Rendering semantic intent to surface form without a transformer
Summary
vine_mouth is a small Python package that converts a typed semantic trace into fluent English. It replaces the portion of a language model's work that is responsible for how to say things that have already been decided, leaving what to say upstream. The implementation is deterministic, rule-based, around 50 KB of data, and passes 104 end-to-end tests. It covers inflection, lemmatisation with etymological layering, article selection, verb conjugation, modal auxiliaries, negation with do-support, pre-nominal adjective modifiers, and clause-level capitalisation and punctuation.
The package does not do semantic reasoning or content selection. It is a narrow engineering artifact with a well-defined interface. Its usefulness is in two places: as a fluency back-end for systems that produce structured semantic output, and as a morphology corrector for language-model output that has degraded under quantisation, distillation, or distribution shift.
1. Background
Modern neural language models handle the full stack of language production — semantics, lexicon, syntax, morphology, orthography — inside a single inference pass. This coupling is usually regarded as a feature. In practice it also couples the failure modes: a model that produces runned instead of ran is failing at morphology, but the failure is not separable from whatever else the model is doing, and the fix (retraining, distillation, improved sampling) is expensive relative to the size of the problem.
Most of the stack above morphology — content selection, role assignment, topicality — genuinely does benefit from large models, because the space of possible meanings is unbounded and statistically structured. The stack below, from morphology downward, does not. English morphology, article selection, and verb conjugation are rule-governed systems with finite inventories of exceptions. Every native English speaker knows them with complete determinism by mid-childhood, and the knowledge is a matter of a few hundred irregular forms and a small set of phonological constraints. A language model encodes this knowledge distributively across billions of parameters, paying for the privilege with model size, inference cost, and unpredictable failure under pressure.
This package separates the two layers and implements the lower one as a cabinet of deterministic specialists with a typed interface between them.
2. Architecture
The system consists of a conductor interface (a trace format) and five specialists, composed by a small dispatch pipeline.
2.1 Trace format
The upstream system produces an ordered list of events. Each event is one of:
| Event | Purpose |
|---|---|
NOMINAL |
A noun phrase |
VERB |
A verbal event (tense, aspect, agreement) |
MODAL |
A modal auxiliary (can, could, will...) |
ADJ |
A bare adjective (typically predicative) |
WORD |
A literal pass-through token |
CLAUSE_START / CLAUSE_END |
Clause boundaries |
COMMA / PUNCT |
Inline punctuation |
A NOMINAL event carries the head noun as a lemma together with structural attributes: definiteness (definite | indefinite | generic | unique_the | unique_zero), countability (count | mass), number (singular | plural), optional pre-modifiers, and an optional generic_style for generic expressions. A VERB event carries the verb as a lemma together with tense, aspect (simple | progressive | perfect), subject agreement features, optional negation, and optional form override. Full schema in docs/trace_format.md.
The format is designed to be the minimum sufficient commitment for surface rendering. The upstream system decides what the content is; it does not need to know how any word is spelled.
2.2 Specialists
The five specialists are:
Inflection. Forward morphology. Given a lemma and a target form (past | pp | ing | 3sg | plural | comp | sup), produces the inflected surface form. Regular rules handle the productive cases; an irregulars table of ~150 verbs, ~20 nouns, and a small adjective set covers the exceptions. Polysyllabic final-stress handling (refer → referred but open → opened) uses a syllable-count heuristic with a small override list.
Lemmatisation. Reverse morphology, with etymological layering. Given a surface form, returns (lemma, edge_tag, layer). The layer is germanic | latin | greek | french | base. Layer-appropriate collapse rules decide whether a form is grammatical variation of an existing concept (Germanic layer: stillness → still), a derivational nominalisation of a living verb (productive Latin: decision → decide), or a frozen borrowing that should stand on its own (frozen Latin: mission). Described in more detail in §3 below.
Articles. Selection of the / a / an / ∅ from a small decision tree driven by definiteness, countability, number, and generic style. The a/an alternation is phonological rather than orthographic, with exception lists for silent-h words (an hour, an honest mistake) and /juː/-initial spellings (a university, a European).
Verbs. Tense × aspect × agreement. Builds simple, progressive, and perfect aspect forms using the inflection specialist and internal rules for be and have auxiliaries. Subject agreement features drive -s / -es selection for third-person singular present and plural/singular selection for was / were. Accepts an explicit form override that short-circuits tense logic when upstream events (modals, do-support) fix the verb's form.
Pipeline. Dispatches events to specialists, assembles tokens with correct spacing, attaches punctuation, handles capitalisation at clause boundaries, and implements the stateful behaviour required for modal priming and negation with do-support.
2.3 Determinism and size
Given the same trace, the pipeline always produces the same sentence. There are no learned parameters, no random sampling, and no floating-point intermediate states. Total code is 1,274 lines of Python; total data (irregulars tables, exception lists, phonological sets) is approximately 50 KB. The package runs on any machine with a standard Python interpreter and has no external dependencies.
3. Etymological layering
English is a stacked morphology. Germanic (Old English and Norse) provides the inflectional system and the basic function words. Latin provides institutional and scientific vocabulary with its own derivational morphology (-tion, -ment, -ity, -able). Greek provides compound roots (-logy, -graph, -meter). French (Norman) provides a further layer of borrowings (-age, -ette, -esque). The four layers coexist in modern English but behave differently under lemmatisation.
A naive rule-based lemmatiser that treats all suffixes uniformly produces correct results on Germanic morphology (softly → soft, stillness → still) and unreliable results on Latin morphology. The difficulty is that Latin suffixes are sometimes productive in English — decision genuinely is the nominalisation of the living verb decide — and sometimes frozen — mission was borrowed whole and has no English verb root meaning "to send." A rule that strips -sion and returns the stem will produce decide correctly and miss incorrectly, where miss exists as an English verb but means something entirely different.
The lemmatiser resolves this by tagging each suffix with its etymological layer and applying layer-specific logic:
- Germanic suffixes (-ly, -ness, -ful, -less, -hood, -ship, -dom, -th) always collapse. English productive morphology is sufficiently regular that the collapse is safe even when the underlying root is not in the vocabulary.
- Latin suffixes (-tion, -sion, -ment, -ity, -ance, -ence, -ive, -ous, -al, -able) only collapse if the candidate root is present in the vocabulary. When no root is found, the word is tagged
base_latin_frozenand retained as its own lemma. - Greek compounds (-logy, -graphy, -meter, -scope, -phone...) are not stripped at all. They are tagged with the Greek root name so that downstream systems can treat the word as a standalone concept with etymological-relative edges to its constituent morphemes.
- French suffixes (-age, -ette, -esque) follow the same vocabulary-gated rule as Latin, and most are kept as frozen borrowings in practice.
The lemmatiser therefore returns a three-tuple (lemma, edge_tag, layer). The layer is semantically meaningful: it tells a downstream consumer whether the returned lemma represents the same concept as the input (productive collapse) or merely an etymological relative (frozen borrowing). When consumed by a concept-graph system, Germanic and productive-Latin edges connect variants of the same node, while frozen-Latin and Greek edges connect distinct nodes.
A secondary consequence is that the layer distribution of a text is a measurable stylistic property. Across the test corpus (a 5,290-word prose chapter), Germanic-layer tokens and Latin-layer tokens varied by narrative scene in a way that tracked genre register: bureaucratic passages had Latin-layer token density of 16% against a baseline of 3-4%, without any conscious styling decision on the author's part.
4. Coverage and evaluation
The package includes 104 end-to-end tests covering:
- 36 inflection cases (regular, irregular, polysyllabic stress, comparatives)
- 22 lemmatisation cases (inflectional, derivational, layer disambiguation, possessives)
- 10 a/an phonology cases
- 14 verb conjugation cases across tense × aspect × person × number
- 22 pipeline rendering cases (simple statements, questions, negation, modals, modifiers, serial lists, multi-clause)
All 104 tests pass. The tests are the specification for correct behaviour; extensions are expected to preserve them. A bug-triage methodology document (docs/bug_triage.md) describes the process for classifying a failure (missing rule, missing exception, vocabulary gap, or upstream wrongness) and producing a one-line fix plus regression test.
The system is deliberately not evaluated against a language-model benchmark. The task it performs — rendering a committed semantic trace — is not what a language model is benchmarked on, and the comparison would be category-confused. A language model trained on a dataset of (trace, sentence) pairs could be compared. That comparison has not been run.
5. Use cases
As a fluency back-end for structured generators. Dialogue systems, templating systems, query-answering systems, and knowledge-graph verbalisers all produce structured semantic output that must be rendered to English. A trace is a natural target for such systems, and deterministic rendering removes a class of unpredictable behaviour that would otherwise need to be tested empirically. Size and latency are negligible relative to typical retrieval or reasoning costs.
As a morphology corrector for degraded language-model output. A 7B-parameter model quantised to 4-bit may begin to emit runned or childs at low temperatures or on out-of-distribution prompts. A post-hoc pass through the inflection specialist can identify and correct these forms without retraining. The package's inflect() function is the relevant entry point; a simple surface-form corrector can wrap it.
As an oracle for testing alternative implementations. Because the package is deterministic and its behaviour is specified by the test suite, it functions as a ground-truth reference for any alternative implementation of the same task. An alternative system's agreement with the reference on the 104 tests is a calibrated measure of its morphological correctness.
6. Limitations
What the package does not currently handle:
- Relative clauses (the horse that ran)
- Embedded clauses beyond one level of nesting
- Quoted direct speech
- Adverbs as verb or adjective modifiers (adverbs are currently passed through as literal tokens)
- Dialect variation (the phonological tables default to a mix of US and UK conventions; configurable)
Each of these is a bounded extension of the existing specialists rather than a new capability. None are expected to require more than tens to low hundreds of additional lines of rules.
What it does not aspire to do:
- Content selection, topic tracking, or discourse planning
- Translation or paraphrase
- Recognition of ungrammatical input
- Any form of learning from data
7. Availability
The package is pure Python with no runtime dependencies beyond the standard library. It is organised as:
vine_mouth/
├── specialists/
│ ├── inflection.py
│ ├── lemmatiser.py
│ ├── articles.py
│ └── verbs.py
├── pipeline/
│ └── render.py
├── tests/
│ └── run_tests.py
└── docs/
├── trace_format.md
├── design.md
└── bug_triage.md
Tests are run with python3 -m vine_mouth.tests.run_tests. The public API is exposed at package top level:
from vine_mouth import render_trace, lemmatise, inflect
Acknowledgements
The three-layer morphology framing — Germanic, Latin, Greek, with French as a fourth — is standard in historical linguistics but is not commonly used as a runtime distinction in lemmatisation. Its application here as a collapse-rule gate was motivated by the observation that treating English as a single morphology produces false derivations on borrowed vocabulary, and that the failure pattern is systematic.
Raychell Langan · NEXICOG Ltd · Hampshire, UK