Chapimenge/amharic-gemination-lexicon
Amharic Gemination Lexicon v3 Which consonants are doubled in each of 86,022 Amharic words, for every reading of the word, and where each doubling comes from. Built by Dataset.ET with the HornMorpho morphological analyzer, corrected with rules that native listening, Armbruster's hand-marked verb tables and recorded speech agree on. Word types 86,022 (856,734 corpus tokens) Analyzed by HornMorpho 56,964 types, 84.0% of tokens Words with a geminate in the top… See the full description on the dataset page: https://huggingface.co/datasets/Chapimenge/amharic-gemination-lexicon.
0
1"""Tests against Armbruster's hand-marked Amharic verb tables.2 3Expected answers are Armbruster forms, written with U+135F ETHIOPIC COMBINING4GEMINATION MARK after each doubled consonant, taken from5github.com/geezorg/data, amharic/verbs/ArmbrusterVerbs-Geminated-20081118.txt.6 7The offline tests need nothing but this directory: each case carries the seg8that HornMorpho 5.3.6 returns for the reading. The live tests run HornMorpho9itself and are skipped when it is not installed.10 11 python test_gemination.py (or: pytest test_gemination.py)12"""13import gemination as G14 15# (word, Armbruster form, seg of the matching reading from hm.anal('a', word, degem=False), sources)16CASES = [17 ("ጨምሮ", "ጨም፟ሮ", "----<ጨ/ምር>ኦ------", ["root"]),18 ("ተከትሎ", "ተከት፟ሎ", "----<ተ-ከ/ትል>ኦ------", ["root"]),19 ("ወሳኝ", "ወሳ፟ኝ", "-<ወ/ሳን-ኢ>------", ["root"]),20 ("መከበር", "መከ፟በር", "-<መ/-ከበር>------", ["t-prefix"]),21 ("ይገኛል", "ይገ፟ኛ፟ል", "----ይ</ገ/ኝ>---ኣ/ል---", ["t-prefix", "root"]),22 ("ይደረጋል", "ይደ፟ረ፟ጋል", "----ይ</ደ/ረግ>---ኣ/ል---", ["t-prefix", "root"]),23 ("ገለባበጠ", "ገለባበ፟ጠ", "----<ገለባ/በጥ>አ------", ["reduplication"]),24 ("ይቀላቀላል", "ይቀ፟ላቀ፟ላል", "----ይ</ቀላ/ቀል>---ኣ/ል---", ["t-prefix", "reduplication"]),25]26# Homographs: the spelling has several readings; Armbruster's form must be one of them.27HOMOGRAPHS = [28 ("መለወጥ", "መለ፟ወጥ", [[1], [2]]), # passive mälläwäṭ, active mäläwwäṭ29 ("ይገባል", "ይገ፟ባ፟ል", [[], [1, 2]]), # active yɨgäbal, passive yɨggäbbal30]31 32 33def positions(marked):34 """Armbruster form -> 0-based indices of geminated characters."""35 out, n = [], 036 for ch in marked:37 if ch == G.GEM_MARK:38 out.append(n - 1)39 else:40 n += 141 return out42 43 44def test_mark_roundtrip():45 for word, arm, _, _ in CASES:46 assert G.mark(word, positions(arm)) == arm47 48 49def test_offline_segs():50 for word, arm, seg, sources in CASES:51 g = G.reading_gemination(word, {"seg": seg})52 assert g["ok"], word53 assert g["pos"] == positions(arm), (word, g["pos"], arm)54 assert g["sources"] == sources, (word, g["sources"])55 56 57def test_suffix_final_geminate_dropped():58 # the -all of ይገኛል is geminate in the seg but inaudible word-finally59 g = G.reading_gemination("ይገኛል", {"seg": "----ይ</ገ/ኝ>---ኣ/ል---"}, final="keep")60 assert g["pos"] == [1, 2, 3]61 62 63def _hm():64 try:65 import hm # noqa: F40166 return True67 except Exception:68 return False69 70 71def test_live_hornmorpho():72 if not _hm():73 print("HornMorpho not installed: live test skipped")74 return75 for word, arm, _, sources in CASES:76 pats = G.analyze(word)77 assert pats and pats[0]["pos"] == positions(arm), (word, [p["pos"] for p in pats], arm)78 assert pats[0]["sources"] == sources, (word, pats[0]["sources"])79 for word, arm, expected in HOMOGRAPHS:80 got = sorted(p["pos"] for p in G.analyze(word))81 assert got == sorted(expected), (word, got)82 assert positions(arm) in got83 84 85# v3 rules: (word, expected form, seg HornMorpho 5.3.6 returns, rule that must fire)86V3_CASES = [87 ("ማሳደግ", "ማሳደ፟ግ", "-<ማስ-ኣደግ>------", "causative_glottal"), # Armbruster ማሳደ፟ግ88 ("አሳይቷል", "አሳይ፟ቷል", "----<ኣስ-ኣይት>ኦ---ኣ/ል---", "causative_glottal"), # Armbruster አሳይ፟ቷል89 ("አስታውሶ", "አስታው፟ሶ", "----<ኣስተ-ኣውስ>ኦ------", "causative_glottal"), # Armbruster አስታው፟ሶ90 ("የሚጠበቅ", "የሚጠ፟በ፟ቅ", "የ--/ም--ይ</ጠ/በቅ>------", "relative_m_light"), # native listener91]92 93 94def test_v3_rules():95 for word, form, seg, rule in V3_CASES:96 g = G.reading_gemination(word, {"seg": seg})97 assert G.mark(word, g["pos"]) == form, (word, G.mark(word, g["pos"]), form)98 assert rule in g["rules"], (word, g["rules"])99 assert G.reading_gemination(word, {"seg": seg}, rules=False)["pos"] != g["pos"], word100 exist = G.word_gemination("ያለው", [{"seg": "የ----<ኣል>አ-ው-----", "freq": 10430, "pos": "V"},101 {"seg": "የ-----<ኣ/ለ>አ-ው-----", "freq": 1849, "pos": "AUX"}])102 assert exist[0]["pos"] == [1] and "relative_exist" in exist[0]["rules"], exist[0]103 104 105if __name__ == "__main__":106 for name, fn in list(globals().items()):107 if name.startswith("test_") and callable(fn):108 fn()109 print("ok", name)110 