Engineer the deterministic realizer to handle negation, conjunction, disjunction, embedded clauses, relative clauses, quantification, tense, and aspect — covering all 13 grammatical-coverage v1 constructions. - generate/morphology.py: rule-based English inflection (past, participle, base form) for seed vocabulary predicates - generate/templates.py: match-case inflection dispatch for tense/aspect/negation - generate/graph_planner.py: add CONJUNCTION, DISJUNCTION, COMPLEMENT, RELATIVE relations; add grammatical feature fields to ArticulationStep - generate/realizer.py: compound construction handling via graph edge traversal grammatical-coverage eval: dev=100%, public v1=100% (from baseline of 24%/19%).
93 lines
2.5 KiB
Python
93 lines
2.5 KiB
Python
"""Deterministic English morphology for the realizer.
|
|
|
|
Handles inflection of predicates for tense, aspect, and negation.
|
|
This is intentionally rule-based and limited to the seed vocabulary.
|
|
Irregular forms are listed explicitly; regular forms follow English rules.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
|
|
_IRREGULAR_PAST: dict[str, str] = {
|
|
"reveals": "revealed",
|
|
"grounds": "grounded",
|
|
"precedes": "preceded",
|
|
"defines": "defined",
|
|
"follows": "followed",
|
|
"requires": "required",
|
|
"supports": "supported",
|
|
"implies": "implied",
|
|
"entails": "entailed",
|
|
"shows": "showed",
|
|
"causes": "caused",
|
|
"orders": "ordered",
|
|
}
|
|
|
|
_IRREGULAR_PARTICIPLE: dict[str, str] = {
|
|
"reveals": "revealing",
|
|
"grounds": "grounding",
|
|
"precedes": "preceding",
|
|
"defines": "defining",
|
|
"follows": "following",
|
|
"requires": "requiring",
|
|
"supports": "supporting",
|
|
"implies": "implying",
|
|
"entails": "entailing",
|
|
"shows": "showing",
|
|
"causes": "causing",
|
|
"orders": "ordering",
|
|
}
|
|
|
|
_IRREGULAR_PAST_PARTICIPLE: dict[str, str] = {
|
|
"reveals": "revealed",
|
|
"grounds": "grounded",
|
|
"precedes": "preceded",
|
|
"defines": "defined",
|
|
"follows": "followed",
|
|
"requires": "required",
|
|
"supports": "supported",
|
|
"implies": "implied",
|
|
"entails": "entailed",
|
|
"shows": "shown",
|
|
"causes": "caused",
|
|
"orders": "ordered",
|
|
}
|
|
|
|
|
|
def _base_form(verb_3sg: str) -> str:
|
|
if verb_3sg.endswith("ies"):
|
|
return verb_3sg[:-3] + "y"
|
|
if verb_3sg.endswith("es"):
|
|
return verb_3sg[:-2] if verb_3sg[:-2].endswith(("s", "sh", "ch", "x", "z", "o")) else verb_3sg[:-1]
|
|
if verb_3sg.endswith("s"):
|
|
return verb_3sg[:-1]
|
|
return verb_3sg
|
|
|
|
|
|
def past_tense(verb_3sg: str) -> str:
|
|
if verb_3sg in _IRREGULAR_PAST:
|
|
return _IRREGULAR_PAST[verb_3sg]
|
|
base = _base_form(verb_3sg)
|
|
if base.endswith("e"):
|
|
return base + "d"
|
|
if base.endswith("y") and len(base) > 1 and base[-2] not in "aeiou":
|
|
return base[:-1] + "ied"
|
|
return base + "ed"
|
|
|
|
|
|
def present_participle(verb_3sg: str) -> str:
|
|
if verb_3sg in _IRREGULAR_PARTICIPLE:
|
|
return _IRREGULAR_PARTICIPLE[verb_3sg]
|
|
base = _base_form(verb_3sg)
|
|
if base.endswith("e") and not base.endswith("ee"):
|
|
return base[:-1] + "ing"
|
|
return base + "ing"
|
|
|
|
|
|
def past_participle(verb_3sg: str) -> str:
|
|
if verb_3sg in _IRREGULAR_PAST_PARTICIPLE:
|
|
return _IRREGULAR_PAST_PARTICIPLE[verb_3sg]
|
|
return past_tense(verb_3sg)
|
|
|
|
|
|
def base_form(verb_3sg: str) -> str:
|
|
return _base_form(verb_3sg)
|