turk-tokenizer / turk_tokenizer /_allomorph.py
nmstech's picture
Initial release: TurkTokenizer v1.0.0 — TR-MMLU 92%
ca41c16 verified
"""Fix 9: Allomorph canonicalization — map surface forms to morpheme IDs."""
from __future__ import annotations
ALLOMORPH_MAP: dict[str, str] = {
"lar": "PL", "ler": "PL",
"ı": "ACC", "i": "ACC", "u": "ACC", "ü": "ACC",
"yı": "ACC", "yi": "ACC", "yu": "ACC", "yü": "ACC",
"a": "DAT", "e": "DAT", "ya": "DAT", "ye": "DAT",
"da": "LOC", "de": "LOC", "ta": "LOC", "te": "LOC",
"dan": "ABL", "den": "ABL", "tan": "ABL", "ten": "ABL",
"ın": "GEN", "in": "GEN", "un": "GEN", "ün": "GEN",
"nın": "GEN", "nin": "GEN", "nun": "GEN", "nün": "GEN",
"la": "INS", "le": "INS", "yla": "INS", "yle": "INS",
"dı": "PAST", "di": "PAST", "du": "PAST", "dü": "PAST",
"tı": "PAST", "ti": "PAST", "tu": "PAST", "tü": "PAST",
"yor": "PROG",
"ar": "AOR", "er": "AOR",
"ır": "AOR", "ir": "AOR", "ur": "AOR", "ür": "AOR",
"mış": "EVID", "miş": "EVID", "muş": "EVID", "müş": "EVID",
"ma": "NEG", "me": "NEG",
"mak": "INF", "mek": "INF",
"ım": "1SG", "im": "1SG", "um": "1SG", "üm": "1SG",
"ın": "2SG", "in": "2SG", "un": "2SG", "ün": "2SG",
"iz": "1PL", "ız": "1PL", "uz": "1PL", "üz": "1PL",
"mı": "Q", "mi": "Q", "mu": "Q", "mü": "Q",
"lı": "WITH", "li": "WITH", "lu": "WITH", "lü": "WITH",
"sız": "WITHOUT","siz": "WITHOUT","suz": "WITHOUT","süz": "WITHOUT",
"cı": "AGT", "ci": "AGT", "cu": "AGT", "cü": "AGT",
"çı": "AGT", "çi": "AGT", "çu": "AGT", "çü": "AGT",
"lık": "ABSTR","lik": "ABSTR","luk": "ABSTR","lük": "ABSTR",
"sa": "COND", "se": "COND",
"ıl": "PASS", "il": "PASS", "ul": "PASS", "ül": "PASS",
}
def add_canonical_labels(tokens: list[dict]) -> list[dict]:
"""Add ``_canonical`` field to SUFFIX tokens (e.g. 'lar'/'ler' → 'PL')."""
result: list[dict] = []
for tok in tokens:
if tok["type"] != "SUFFIX":
result.append(tok)
continue
canonical = ALLOMORPH_MAP.get(tok["token"].strip().lower())
result.append({**tok, "_canonical": canonical} if canonical else tok)
return result