c2cd5e01e1
El SDK CI - dev / build-and-test (pull_request) Successful in 3m34s
elb.el: - Auto-detect Homebrew OpenSSL (-L$(brew --prefix openssl)/lib) so -lssl resolves on macOS without manual flags; no-op on Linux - Add -include elp-c-decls.h when present in out_dir: resolves undeclared cross-module calls in packages like ELP that lack explicit imports ELP source: - Add import "morphology.el" to all 29 language morphology modules - Add language module imports to morphology.el (all langs it dispatches to) These were missing since ELP was originally built as a monolithic unit
508 lines
21 KiB
EmacsLisp
508 lines
21 KiB
EmacsLisp
// morphology-gez.el - Ge'ez morphology for the NLG engine.
|
||
// ግዕዝ — Classical Ethiopic, the liturgical language of the
|
||
// Ethiopian Orthodox Church and ancestor of Amharic/Tigrinya.
|
||
//
|
||
// Implements Ge'ez verb conjugation (perfect and imperfect, basic G-stem),
|
||
// noun declension (nominative, accusative, construct; singular and plural),
|
||
// and noun-phrase construction.
|
||
//
|
||
// Ge'ez (also: Classical Ethiopic, gǝʿǝz) is the ancient Semitic language
|
||
// of the Kingdom of Axum (ca. 300–900 CE active liturgy; ca. 1st century BCE
|
||
// epigraphic attestation). It remains the liturgical language of the
|
||
// Ethiopian and Eritrean Orthodox Churches. Modern Ethiopian Semitic languages
|
||
// (Amharic, Tigrinya, Tigre) descend from Ge'ez or a closely related ancestor.
|
||
//
|
||
// Script: Ge'ez Fidel (ፊደል) — an Ethiopic abugida (Unicode U+1200–U+137F).
|
||
// Each Fidel character encodes a consonant + vowel combination (7 orders per
|
||
// consonant). String literals in this file use actual Unicode characters.
|
||
//
|
||
// NOTE on El runtime: the El VM currently outputs non-ASCII as numeric hashes
|
||
// (runtime limitation for non-Latin scripts). str_eq and string comparisons
|
||
// work correctly internally. When the VM adds full UTF-8 output, all Ge'ez
|
||
// strings will display correctly automatically.
|
||
//
|
||
// Language profile:
|
||
// code=gez, name=Ge'ez, morph_type=semitic, word_order=SOV,
|
||
// script=ethiopic-fidel, family=semitic/south-ethiopic-semitic
|
||
//
|
||
// Key grammatical facts:
|
||
// - SOV word order — unusual for Semitic (Arabic, Hebrew, Akkadian are VSO);
|
||
// Ge'ez shares SOV with modern Ethiopian Semitic descendants
|
||
// - Semitic trilateral root system (root + vowel pattern = word)
|
||
// - Gender: masculine (default) / feminine (often marked with -t suffix)
|
||
// - Number: singular / plural; dual vestigial
|
||
// - Cases: nominative (unmarked), accusative -a (animate masc nouns),
|
||
// construct/genitive (various; simplified to base form here)
|
||
// - Plural: no single rule; common patterns: -āt (fem/animate), -ān (masc),
|
||
// broken (internal vowel change, unpredictable without lexicon)
|
||
// - Verb system:
|
||
// Perfect (suffix conjugation): completed action
|
||
// Imperfect (prefix conjugation): ongoing / future / habitual
|
||
// Four derived stems: basic (G), causative (ʾa-), intensive (doubling),
|
||
// passive (te-); this file implements basic G-stem throughout
|
||
// - No definite article (unlike Amharic which has suffixed -u/-wa/-itu etc.)
|
||
// - Copula: root kwn (ሆነ honä) — "to be / become"
|
||
//
|
||
// Verb conjugation conventions:
|
||
// person: "first" | "second" | "third"
|
||
// gender: "m" | "f"
|
||
// number: "singular" | "plural"
|
||
// tense: "perfect" | "imperfect"
|
||
//
|
||
// Noun declension conventions:
|
||
// gram_case: "nom" | "acc" | "construct"
|
||
// number: "singular" | "plural"
|
||
//
|
||
// Verbs covered (root / Fidel form / transliteration):
|
||
// "kwn" / ሆነ (honä) — to be / become (copula)
|
||
// "hlw" / ሀሎ (hallo) — to exist / there is
|
||
// "hbl" / ሰጠ (säṭṭä) — to give
|
||
// "rʾy" / አየ (ʾayyä) — to see
|
||
// "qwl" / ተናገረ (tänagärä) — to speak
|
||
//
|
||
// Depends on: morphology.el (str_eq, str_len, str_slice, str_ends_with)
|
||
|
||
// ── String helpers ─────────────────────────────────────────────────────────────
|
||
|
||
import "morphology.el"
|
||
fn gez_str_ends(s: String, suf: String) -> Bool {
|
||
return str_ends_with(s, suf)
|
||
}
|
||
|
||
fn gez_str_len(s: String) -> Int {
|
||
return str_len(s)
|
||
}
|
||
|
||
fn gez_str_drop_last(s: String, n: Int) -> String {
|
||
let len: Int = str_len(s)
|
||
if n >= len {
|
||
return ""
|
||
}
|
||
return str_slice(s, 0, len - n)
|
||
}
|
||
|
||
// ── Slot index ─────────────────────────────────────────────────────────────────
|
||
//
|
||
// Maps person × number to a 0-based slot for table lookups.
|
||
// Gender is handled separately for third-person disambiguation.
|
||
//
|
||
// Slot layout (6 primary cells):
|
||
// 0 = 1sg (I)
|
||
// 1 = 2sg (you sg — gender note: Ge'ez distinguishes 2sg m/f in perfect)
|
||
// 2 = 3sg m (he)
|
||
// 3 = 3sg f (she)
|
||
// 4 = 1pl (we)
|
||
// 5 = 3pl (they — default masc)
|
||
|
||
fn gez_slot(person: String, number: String) -> Int {
|
||
if str_eq(person, "first") {
|
||
if str_eq(number, "plural") { return 4 }
|
||
return 0
|
||
}
|
||
if str_eq(person, "second") {
|
||
return 1
|
||
}
|
||
// third
|
||
if str_eq(number, "plural") { return 5 }
|
||
return 2
|
||
}
|
||
|
||
// gez_slot_g: gender-sensitive slot for third-person singular.
|
||
fn gez_slot_g(person: String, gender: String, number: String) -> Int {
|
||
let base: Int = gez_slot(person, number)
|
||
if str_eq(person, "third") {
|
||
if str_eq(number, "singular") {
|
||
if str_eq(gender, "f") { return 3 }
|
||
}
|
||
}
|
||
return base
|
||
}
|
||
|
||
// ── Copula: kwn / ሆነ — to be / become ────────────────────────────────────────
|
||
//
|
||
// Perfect paradigm (suffix forms):
|
||
// 3sg m: ሆነ honä (base form)
|
||
// 3sg f: ሆነት honät (-t suffix)
|
||
// 2sg m: ሆንከ honkä (-kä suffix)
|
||
// 2sg f: ሆንኪ honki (-ki suffix)
|
||
// 1sg: ሆንኩ honku (-ku suffix)
|
||
// 3pl m: ሆኑ honu (-u suffix)
|
||
// 3pl f: ሆና honā (-ā suffix)
|
||
// 2pl: ሆንክሙ honkǝmu (-kǝmu suffix)
|
||
// 1pl: ሆንነ honna (-na suffix)
|
||
//
|
||
// Imperfect paradigm (prefix forms):
|
||
// 3sg m: ይሆን yǝhon (yǝ- prefix)
|
||
// 3sg f: ትሆን tǝhon (tǝ- prefix)
|
||
// 2sg: ትሆን tǝhon (tǝ- prefix)
|
||
// 1sg: እሆን ʾǝhon (ʾǝ- prefix)
|
||
// 3pl m: ይሆኑ yǝhonu (yǝ- + -u suffix)
|
||
// 1pl: ንሆን nǝhon (nǝ- prefix)
|
||
|
||
fn gez_kwn_perfect(slot: Int) -> String {
|
||
if slot == 0 { return "ሆንኩ" } // 1sg honku
|
||
if slot == 1 { return "ሆንከ" } // 2sg m honkä (default; fem: ሆንኪ)
|
||
if slot == 2 { return "ሆነ" } // 3sg m honä
|
||
if slot == 3 { return "ሆነት" } // 3sg f honät
|
||
if slot == 4 { return "ሆንነ" } // 1pl honna
|
||
return "ሆኑ" // 3pl honu
|
||
}
|
||
|
||
fn gez_kwn_imperfect(slot: Int) -> String {
|
||
if slot == 0 { return "እሆን" } // 1sg ʾǝhon
|
||
if slot == 1 { return "ትሆን" } // 2sg tǝhon
|
||
if slot == 2 { return "ይሆን" } // 3sg m yǝhon
|
||
if slot == 3 { return "ትሆን" } // 3sg f tǝhon (same prefix as 2sg)
|
||
if slot == 4 { return "ንሆን" } // 1pl nǝhon
|
||
return "ይሆኑ" // 3pl yǝhonu
|
||
}
|
||
|
||
fn gez_is_copula(verb: String) -> Bool {
|
||
if str_eq(verb, "kwn") { return true }
|
||
if str_eq(verb, "ሆነ") { return true }
|
||
if str_eq(verb, "hona") { return true }
|
||
if str_eq(verb, "be") { return true }
|
||
return false
|
||
}
|
||
|
||
fn gez_conjugate_copula(tense: String, slot: Int) -> String {
|
||
if str_eq(tense, "imperfect") { return gez_kwn_imperfect(slot) }
|
||
return gez_kwn_perfect(slot)
|
||
}
|
||
|
||
// ── hlw / ሀሎ — to exist / there is ───────────────────────────────────────────
|
||
//
|
||
// hallo is an existential copula used for "there is/are".
|
||
// In Ge'ez it is largely invariant in its classical usage (presentational).
|
||
// We provide a minimal paradigm; for existential use, hallo is returned for
|
||
// all slots in the "perfect" (existential present).
|
||
|
||
fn gez_hlw_perfect(slot: Int) -> String {
|
||
// Invariant existential for most purposes
|
||
if slot == 0 { return "ሀሎኩ" } // 1sg halloku
|
||
if slot == 1 { return "ሀሎከ" } // 2sg hallokä
|
||
if slot == 2 { return "ሀሎ" } // 3sg m hallo
|
||
if slot == 3 { return "ሀለወት" } // 3sg f halläwät
|
||
if slot == 4 { return "ሀሎነ" } // 1pl hallonä
|
||
return "ሀሉ" // 3pl hallu
|
||
}
|
||
|
||
fn gez_hlw_imperfect(slot: Int) -> String {
|
||
if slot == 0 { return "እሀሉ" } // 1sg
|
||
if slot == 1 { return "ትሀሉ" } // 2sg
|
||
if slot == 2 { return "ይሀሉ" } // 3sg m
|
||
if slot == 3 { return "ትሀሉ" } // 3sg f
|
||
if slot == 4 { return "ንሀሉ" } // 1pl
|
||
return "ይሀልዉ" // 3pl
|
||
}
|
||
|
||
// ── hbl / ሰጠ — to give ────────────────────────────────────────────────────────
|
||
//
|
||
// Perfect: säṭṭä (3sg m base); standard G-stem suffix paradigm.
|
||
// Imperfect: yǝsäṭ (3sg m).
|
||
|
||
fn gez_hbl_perfect(slot: Int) -> String {
|
||
if slot == 0 { return "ሰጠኩ" } // 1sg säṭṭäku
|
||
if slot == 1 { return "ሰጠከ" } // 2sg säṭṭäkä
|
||
if slot == 2 { return "ሰጠ" } // 3sg m säṭṭä
|
||
if slot == 3 { return "ሰጠት" } // 3sg f säṭṭät
|
||
if slot == 4 { return "ሰጠነ" } // 1pl säṭṭänä
|
||
return "ሰጡ" // 3pl säṭṭu
|
||
}
|
||
|
||
fn gez_hbl_imperfect(slot: Int) -> String {
|
||
if slot == 0 { return "እሰጥ" } // 1sg ʾǝsäṭ
|
||
if slot == 1 { return "ትሰጥ" } // 2sg tǝsäṭ
|
||
if slot == 2 { return "ይሰጥ" } // 3sg m yǝsäṭ
|
||
if slot == 3 { return "ትሰጥ" } // 3sg f tǝsäṭ
|
||
if slot == 4 { return "ንሰጥ" } // 1pl nǝsäṭ
|
||
return "ይሰጡ" // 3pl yǝsäṭu
|
||
}
|
||
|
||
// ── rʾy / አየ — to see ─────────────────────────────────────────────────────────
|
||
//
|
||
// Third-weak verb (final ʾ). Perfect: ʾayyä (3sg m); imperfect: yāy (3sg m).
|
||
|
||
fn gez_ray_perfect(slot: Int) -> String {
|
||
if slot == 0 { return "አየኩ" } // 1sg ʾayyäku
|
||
if slot == 1 { return "አየከ" } // 2sg ʾayyäkä
|
||
if slot == 2 { return "አየ" } // 3sg m ʾayyä
|
||
if slot == 3 { return "አየት" } // 3sg f ʾayyät
|
||
if slot == 4 { return "አየነ" } // 1pl ʾayyänä
|
||
return "አዩ" // 3pl ʾayyu
|
||
}
|
||
|
||
fn gez_ray_imperfect(slot: Int) -> String {
|
||
if slot == 0 { return "እያይ" } // 1sg ʾǝyāy
|
||
if slot == 1 { return "ትያይ" } // 2sg tǝyāy
|
||
if slot == 2 { return "ያይ" } // 3sg m yāy
|
||
if slot == 3 { return "ትያይ" } // 3sg f tǝyāy
|
||
if slot == 4 { return "ንያይ" } // 1pl nǝyāy
|
||
return "ያዩ" // 3pl yāyu
|
||
}
|
||
|
||
// ── qwl / ተናገረ — to speak ────────────────────────────────────────────────────
|
||
//
|
||
// tänagärä is actually a derived (reciprocal / D-stem) form of the root ngrǝ,
|
||
// used as the ordinary word for "to speak" in Classical Ge'ez.
|
||
// Perfect: tänagärä (3sg m); imperfect: yǝnagär (3sg m).
|
||
|
||
fn gez_qwl_perfect(slot: Int) -> String {
|
||
if slot == 0 { return "ተናገርኩ" } // 1sg tänagärku
|
||
if slot == 1 { return "ተናገርከ" } // 2sg tänagärkä
|
||
if slot == 2 { return "ተናገረ" } // 3sg m tänagärä
|
||
if slot == 3 { return "ተናገረት" } // 3sg f tänagärät
|
||
if slot == 4 { return "ተናገርነ" } // 1pl tänagärnä
|
||
return "ተናገሩ" // 3pl tänagäru
|
||
}
|
||
|
||
fn gez_qwl_imperfect(slot: Int) -> String {
|
||
if slot == 0 { return "እናገር" } // 1sg ʾǝnagär
|
||
if slot == 1 { return "ትናገር" } // 2sg tǝnagär
|
||
if slot == 2 { return "ይናገር" } // 3sg m yǝnagär
|
||
if slot == 3 { return "ትናገር" } // 3sg f tǝnagär
|
||
if slot == 4 { return "ንናገር" } // 1pl nǝnagär
|
||
return "ይናገሩ" // 3pl yǝnagäru
|
||
}
|
||
|
||
// ── Generic G-stem paradigm ────────────────────────────────────────────────────
|
||
//
|
||
// For regular strong verbs not in the lookup table.
|
||
// Ge'ez perfect suffixes: 1sg -ku, 2sg -kä, 3sg m ∅, 3sg f -at, 1pl -nä, 3pl -u
|
||
// Ge'ez imperfect prefixes: 1sg ʾǝ-, 2sg tǝ-, 3sg m yǝ-, 3sg f tǝ-, 1pl nǝ-
|
||
|
||
fn gez_generic_perfect(base3sg: String, slot: Int) -> String {
|
||
if slot == 0 { return base3sg + "ኩ" } // -ku
|
||
if slot == 1 { return base3sg + "ከ" } // -kä
|
||
if slot == 2 { return base3sg } // ∅
|
||
if slot == 3 { return base3sg + "ት" } // -at (simplified: -t Fidel)
|
||
if slot == 4 { return base3sg + "ነ" } // -nä
|
||
return base3sg + "ኡ" // -u (3pl)
|
||
}
|
||
|
||
fn gez_generic_imperfect(base3sg: String, slot: Int) -> String {
|
||
// base3sg is the 3sg m imperfect form (with yǝ- prefix)
|
||
// We heuristically return the stem with different prefixes.
|
||
if slot == 0 { return "እ" + base3sg } // ʾǝ-
|
||
if slot == 1 { return "ት" + base3sg } // tǝ-
|
||
if slot == 2 { return "ይ" + base3sg } // yǝ-
|
||
if slot == 3 { return "ት" + base3sg } // tǝ-
|
||
if slot == 4 { return "ን" + base3sg } // nǝ-
|
||
return "ይ" + base3sg + "ኡ" // yǝ- + -u (3pl)
|
||
}
|
||
|
||
// ── Known-verb dispatcher ─────────────────────────────────────────────────────
|
||
|
||
fn gez_known_verb(verb: String, tense: String, slot: Int) -> String {
|
||
// kwn / ሆነ — to be
|
||
if str_eq(verb, "kwn") {
|
||
return gez_conjugate_copula(tense, slot)
|
||
}
|
||
if str_eq(verb, "ሆነ") {
|
||
return gez_conjugate_copula(tense, slot)
|
||
}
|
||
if str_eq(verb, "hona") {
|
||
return gez_conjugate_copula(tense, slot)
|
||
}
|
||
|
||
// hlw / ሀሎ — to exist
|
||
if str_eq(verb, "hlw") {
|
||
if str_eq(tense, "imperfect") { return gez_hlw_imperfect(slot) }
|
||
return gez_hlw_perfect(slot)
|
||
}
|
||
if str_eq(verb, "ሀሎ") {
|
||
if str_eq(tense, "imperfect") { return gez_hlw_imperfect(slot) }
|
||
return gez_hlw_perfect(slot)
|
||
}
|
||
if str_eq(verb, "hallo") {
|
||
if str_eq(tense, "imperfect") { return gez_hlw_imperfect(slot) }
|
||
return gez_hlw_perfect(slot)
|
||
}
|
||
|
||
// hbl / ሰጠ — to give
|
||
if str_eq(verb, "hbl") {
|
||
if str_eq(tense, "imperfect") { return gez_hbl_imperfect(slot) }
|
||
return gez_hbl_perfect(slot)
|
||
}
|
||
if str_eq(verb, "ሰጠ") {
|
||
if str_eq(tense, "imperfect") { return gez_hbl_imperfect(slot) }
|
||
return gez_hbl_perfect(slot)
|
||
}
|
||
if str_eq(verb, "sätta") {
|
||
if str_eq(tense, "imperfect") { return gez_hbl_imperfect(slot) }
|
||
return gez_hbl_perfect(slot)
|
||
}
|
||
|
||
// rʾy / አየ — to see
|
||
if str_eq(verb, "rʾy") {
|
||
if str_eq(tense, "imperfect") { return gez_ray_imperfect(slot) }
|
||
return gez_ray_perfect(slot)
|
||
}
|
||
if str_eq(verb, "አየ") {
|
||
if str_eq(tense, "imperfect") { return gez_ray_imperfect(slot) }
|
||
return gez_ray_perfect(slot)
|
||
}
|
||
if str_eq(verb, "ʾayya") {
|
||
if str_eq(tense, "imperfect") { return gez_ray_imperfect(slot) }
|
||
return gez_ray_perfect(slot)
|
||
}
|
||
|
||
// qwl / ተናገረ — to speak
|
||
if str_eq(verb, "qwl") {
|
||
if str_eq(tense, "imperfect") { return gez_qwl_imperfect(slot) }
|
||
return gez_qwl_perfect(slot)
|
||
}
|
||
if str_eq(verb, "ተናገረ") {
|
||
if str_eq(tense, "imperfect") { return gez_qwl_imperfect(slot) }
|
||
return gez_qwl_perfect(slot)
|
||
}
|
||
if str_eq(verb, "tänagärä") {
|
||
if str_eq(tense, "imperfect") { return gez_qwl_imperfect(slot) }
|
||
return gez_qwl_perfect(slot)
|
||
}
|
||
|
||
return ""
|
||
}
|
||
|
||
// ── Main conjugation entry point ──────────────────────────────────────────────
|
||
//
|
||
// gez_conjugate: conjugate a Ge'ez verb (G-stem / basic stem).
|
||
//
|
||
// verb: root (e.g. "kwn", "rʾy"), Fidel citation form (e.g. "ሆነ"),
|
||
// or transliterated 3sg perfect (e.g. "hona", "ʾayya")
|
||
// tense: "perfect" | "imperfect"
|
||
// person: "first" | "second" | "third"
|
||
// number: "singular" | "plural"
|
||
//
|
||
// Returns:
|
||
// - Fidel string (Unicode) for known verbs
|
||
// - verb unchanged as safe fallback for unknown verbs
|
||
|
||
fn gez_conjugate(verb: String, tense: String, person: String, number: String) -> String {
|
||
let slot: Int = gez_slot(person, number)
|
||
|
||
if gez_is_copula(verb) {
|
||
return gez_conjugate_copula(tense, slot)
|
||
}
|
||
|
||
let known: String = gez_known_verb(verb, tense, slot)
|
||
if !str_eq(known, "") {
|
||
return known
|
||
}
|
||
|
||
return verb
|
||
}
|
||
|
||
// ── Noun declension ────────────────────────────────────────────────────────────
|
||
//
|
||
// gez_decline: decline a Ge'ez noun for gram_case and number.
|
||
//
|
||
// Case system (simplified for this engine):
|
||
// Nominative: base form (unmarked — the Fidel form as given)
|
||
// Accusative: base + -a (for animate masculine nouns; inanimate often same)
|
||
// Construct: base form (genitive/construct; detailed vowel alternations
|
||
// are lexically irregular — simplified to base here)
|
||
//
|
||
// Plural patterns (highly irregular in Ge'ez, like Arabic broken plurals):
|
||
// Common productive suffixes:
|
||
// Feminine/animate: -āt (ሀዋርያት hawāryāt — apostles)
|
||
// Masculine: -ān (ነቢያን nabiyān — prophets)
|
||
// Broken plurals: unpredictable — must come from vocabulary layer.
|
||
// Fallback: base + "āt" (ア default)
|
||
//
|
||
// noun: base singular form (Fidel or transliterated)
|
||
// gram_case: "nom" | "acc" | "construct"
|
||
// number: "singular" | "plural"
|
||
|
||
fn gez_is_fidel(noun: String) -> Bool {
|
||
// Ethiopic Unicode block starts at U+1200 (ሀ).
|
||
// We detect by checking a set of common Fidel first characters.
|
||
let n: Int = gez_str_len(noun)
|
||
if n == 0 { return false }
|
||
let first: String = str_slice(noun, 0, 1)
|
||
if str_eq(first, "ሀ") { return true }
|
||
if str_eq(first, "ሁ") { return true }
|
||
if str_eq(first, "ሂ") { return true }
|
||
if str_eq(first, "ሃ") { return true }
|
||
if str_eq(first, "ሄ") { return true }
|
||
if str_eq(first, "ህ") { return true }
|
||
if str_eq(first, "ሆ") { return true }
|
||
if str_eq(first, "ለ") { return true }
|
||
if str_eq(first, "መ") { return true }
|
||
if str_eq(first, "ሰ") { return true }
|
||
if str_eq(first, "ሸ") { return true }
|
||
if str_eq(first, "ቀ") { return true }
|
||
if str_eq(first, "በ") { return true }
|
||
if str_eq(first, "ተ") { return true }
|
||
if str_eq(first, "ነ") { return true }
|
||
if str_eq(first, "አ") { return true }
|
||
if str_eq(first, "እ") { return true }
|
||
if str_eq(first, "ከ") { return true }
|
||
if str_eq(first, "ወ") { return true }
|
||
if str_eq(first, "ዘ") { return true }
|
||
if str_eq(first, "የ") { return true }
|
||
if str_eq(first, "ደ") { return true }
|
||
if str_eq(first, "ገ") { return true }
|
||
if str_eq(first, "ጠ") { return true }
|
||
if str_eq(first, "ፀ") { return true }
|
||
if str_eq(first, "ፈ") { return true }
|
||
if str_eq(first, "ፐ") { return true }
|
||
return false
|
||
}
|
||
|
||
fn gez_decline(noun: String, gram_case: String, number: String) -> String {
|
||
if str_eq(number, "plural") {
|
||
// Plural: default suffix -āt (Fidel: append transliterated marker for
|
||
// non-Fidel input; for Fidel input append ት as the -āt marker)
|
||
if gez_is_fidel(noun) {
|
||
return noun + "ዎች" // simplified -woc plural marker (Ge'ez -āt ≈ ዎ)
|
||
}
|
||
return noun + "āt"
|
||
}
|
||
|
||
// Singular
|
||
if str_eq(gram_case, "acc") {
|
||
// Accusative: add -a suffix
|
||
if gez_is_fidel(noun) {
|
||
return noun + "ን" // accusative object marker (simplified)
|
||
}
|
||
return noun + "a"
|
||
}
|
||
|
||
// Nominative and construct: return base form
|
||
return noun
|
||
}
|
||
|
||
// ── Noun phrase ────────────────────────────────────────────────────────────────
|
||
//
|
||
// gez_noun_phrase: produce the surface noun phrase.
|
||
//
|
||
// Ge'ez has no definite article (unlike Amharic's suffix -u/-wa/-itu).
|
||
// Definiteness is expressed through word order and context.
|
||
// The definite parameter is accepted for interface uniformity but has no
|
||
// surface effect.
|
||
//
|
||
// noun: base noun (Fidel string or transliteration)
|
||
// gram_case: "nom" | "acc" | "construct"
|
||
// number: "singular" | "plural"
|
||
// definite: "true" | "false" (no surface effect in Ge'ez)
|
||
|
||
fn gez_noun_phrase(noun: String, gram_case: String, number: String, definite: String) -> String {
|
||
return gez_decline(noun, gram_case, number)
|
||
}
|
||
|
||
// ── Canonical verb mapping ─────────────────────────────────────────────────────
|
||
//
|
||
// gez_map_canonical: map cross-lingual English canonical verb labels to
|
||
// Ge'ez roots or citation forms.
|
||
|
||
fn gez_map_canonical(verb: String) -> String {
|
||
if str_eq(verb, "be") { return "kwn" }
|
||
if str_eq(verb, "exist") { return "hlw" }
|
||
if str_eq(verb, "give") { return "hbl" }
|
||
if str_eq(verb, "see") { return "rʾy" }
|
||
if str_eq(verb, "speak") { return "qwl" }
|
||
if str_eq(verb, "say") { return "qwl" }
|
||
return verb
|
||
}
|