"""Grammar check via reconstruction from features."""
from __future__ import annotations
from typing import Dict
from language_spec import (
SentenceFeatures,
NPFeature,
realize_sentence,
generate_language_instance,
FEMININE_NOUNS,
AGENT,
RECIPIENT,
THEME,
)
def is_grammatical(option: Dict, spec=None) -> bool:
if spec is None:
spec = generate_language_instance()
feat = option.get("features")
if not feat:
return False
subj = NPFeature(**feat["subject"])
obj1 = NPFeature(**feat["obj1"])
obj2 = NPFeature(**feat["obj2"]) if feat.get("obj2") else None
# role sanity
if subj.role != AGENT:
return False
if obj1.role not in {RECIPIENT, THEME}:
return False
if feat["verb_id"] == "give":
if obj2 is None or obj2.role != THEME:
return False
else:
if obj2 is not None:
return False
# feminine only for feminine nouns
for np in [subj, obj1] + ([obj2] if obj2 else []):
if np.feminine and np.noun_id not in FEMININE_NOUNS:
return False
# give should have obj2
sf = SentenceFeatures(
subject=subj,
obj1=obj1,
obj2=obj2,
verb_id=feat["verb_id"],
tense=feat["tense"],
use_irregular_verb=feat.get("use_irregular_verb", True),
)
surface = realize_sentence(spec, sf)
return option["text"] == surface