git » alan.git » master » tree

[master] / grammar_check.py

"""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