From 344342012d0bfdfa80ff11c98d0aba1e951efd82 Mon Sep 17 00:00:00 2001 From: aarneranta Date: Fri, 10 Jul 2026 16:32:25 +0200 Subject: [PATCH] czech: fix noun paradigm selection, add loanword and adjectival types MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit declensionNounForms only tested hardConsonant (d t g h k n r), so the neutral consonants (b f l m p s v), which take the hard endings, matched nothing and fell through to the soft declSTROJ fallback: graf, atom, profil, přístup were all declined as if soft. Same gap in guessNounForms. Add hardishConsonant (hard + neutral + the foreign z, x) and use it in both. The genitive passed to the three-argument mkN was only used to pick a paradigm, then thrown away, so the oblique stem was re-derived from the nominative by dropFleetingE. That guesses wrong in both directions: it fires on člen -> člnu, and fails to fire on uzel -> uzelu, doplněk -> doplněku, výpočet -> výpočetu. Give declHRAD, declHRADA and declMUZ stem-taking variants and let declensionNounForms pass the stem it was given. The one-argument guessNounForms keeps the old dropFleetingE behaviour. New paradigms, all previously falling back to declSTROJ: declLATINUS algoritmus - algoritmu, kosmos - kosmu (also -os) declLATINUSA the same, masculine animate declLATINUM kontinuum - kontinua declGREEKMA schéma - schématu declHRADA les - lesa, zákon - zákona declADJF proměnná - proměnné declADJM nultý - nultého declINVAR indeclinable loans: bombé, tamari, software Also match feminine consonant stems by genitive (-i -> kost, -e/-ě -> píseň), masculine -e/-ě genitives (kužel - kužele, král - krále), and neuter -ě (těžiště), none of which were reachable before. Measured on the 1177 nouns of informath's WikidataWordsCze: 225 hit the fallback before, 1 after (the acronym ADE). Co-Authored-By: Claude Opus 4.8 (1M context) --- src/czech/ResCze.gf | 141 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 122 insertions(+), 19 deletions(-) diff --git a/src/czech/ResCze.gf b/src/czech/ResCze.gf index 4e009982..620d0739 100644 --- a/src/czech/ResCze.gf +++ b/src/czech/ResCze.gf @@ -28,6 +28,11 @@ oper softConsonant : pattern Str = #("ť"|"ď"|"j"|"ň"|"ř"|"š"|"c"|"č"|"ž") ; neutralConsonant : pattern Str = #("b"|"f"|"l"|"m"|"p"|"s"|"v") ; +-- neutral consonants take the hard endings by default (hrad, pán), and so do +-- the foreign "z" and "x"; this is the class to test when choosing a paradigm + hardishConsonant : pattern Str = + #("d"|"t"|"g"|"h"|"k"|"n"|"r" | "b"|"f"|"l"|"m"|"p"|"s"|"v" | "z"|"x") ; + consonant : pattern Str = #( "d" | "t" | "g" | "h" | "k" | "n" | "r" | @@ -139,22 +144,33 @@ oper declensionNounForms : (nom,gen : Str) -> Gender -> NounForms = \nom,gen,g -> - let decl : DeclensionType = case of { - => declPAN ; - => declPREDSEDA ; - => declHRAD ; - => declZENA ; - => declMESTO ; - => declMUZ ; - => declMUZ ; +-- the oblique stem, for the paradigms that cannot derive it from the nominative + let stem : Str = Predef.tk 1 gen ; + decl : DeclensionType = case of { + => declMUZstem stem ; => declSOUDCE ; - => declSTROJ ; + => declLATINUSA ; + => declPREDSEDA ; + => declMUZstem stem ; + => declPAN ; + => declLATINUS ; + => declADJM ; + => declSTROJ ; + => declHRADstem stem ; + => declHRADAstem stem ; + => declZENA ; + => declADJF ; => declRUZE ; - => declPISEN ; - => declKOST ; --- also many other "st" 3.6.3 + => declKOST ; --- also many other "st" 3.6.3 + => declPISEN ; + => declLATINUM ; + => declGREEKMA ; + => declMESTO ; => declKURE ; - => declMORE ; => declSTAVENI ; + => declMORE ; + => declINVAR (Masc Inanim) ; + => declINVAR Neutr ; _ => (\s -> declSTROJ ("" + s)) -- Predef.error ("cannot infer declension type for" ++ nom ++ gen) } in decl nom ; @@ -165,12 +181,14 @@ oper = \s -> case s of { _ + "ost" => declKOST s ; _ + "tel" => declMUZ s ; - _ + #hardConsonant => declHRAD s ; + _ + "us" => declLATINUS s ; + _ + "um" => declLATINUM s ; + _ + #hardishConsonant => declHRAD s ; _ + #softConsonant => declSTROJ s ; _ + "a" => declZENA s ; _ + "o" => declMESTO s ; _ + "ce" => declSOUDCE s ; - _ + "e" => declMORE s ; + _ + ("e"|"ě") => declMORE s ; _ + "í" => declSTAVENI s ; _ => declSTROJ ("" + s) -- Predef.error ("cannot guess declension type for" ++ s) } ; @@ -216,9 +234,9 @@ oper g = Masc Anim } ; - declHRAD : DeclensionType = \hrad -> --- 3.5.2: sloc u/ě/e extra arg, sport-u, hrad-ě ; sgen u/a - let hrd = dropFleetingE hrad - in +-- the oblique stem is a separate argument, because it cannot always be +-- derived from the nominative: uzel-uzlu but člen-členu + declHRADstem : Str -> DeclensionType = \hrd,hrad -> { snom,sacc = hrad ; sgen,sdat = hrd + "u" ; --- Berlín-a @@ -233,6 +251,9 @@ oper g = Masc Inanim } ; + declHRAD : DeclensionType = \hrad -> --- 3.5.2: sloc u/ě/e extra arg, sport-u, hrad-ě ; sgen u/a + declHRADstem (dropFleetingE hrad) hrad ; + declZENA : DeclensionType = \zena -> --- 3.6.1 sge y/i ; pgen sometimes shortening let zen = init zena in @@ -270,9 +291,91 @@ oper g = Neutr } ; +-- Latin masculines in -us: the ending is dropped outside the nominative +-- (algoritmus - algoritmu), otherwise they follow hrad + declLATINUS : DeclensionType = \algoritmus -> + let algoritm = Predef.tk 2 algoritmus + in declHRAD algoritm ** { + snom, sacc = algoritmus ; + svoc = algoritm + "e" + } ; + + declLATINUSA : DeclensionType = \genius -> + declLATINUS genius ** {g = Masc Anim} ; + +-- Latin neuters in -um: the ending is dropped outside the nominative +-- (kontinuum - kontinua), otherwise they follow město + declLATINUM : DeclensionType = \kompaktum -> + let kompakt = Predef.tk 2 kompaktum + in declMESTO (kompakt + "o") ** { + snom, sacc, svoc = kompaktum + } ; + +-- Greek neuters in -ma, with the stem extended by -t- (schéma - schématu) + declGREEKMA : DeclensionType = \schema -> + let schemat = schema + "t" + in { + snom,sacc,svoc = schema ; + sgen,sdat,sloc = schemat + "u" ; + sins = schemat + "em" ; + + pnom,pacc = schemat + "a" ; + pgen = schemat ; + pdat = schemat + "ům" ; + ploc = schemat + "ech" ; + pins = schemat + "y" ; + g = Neutr + } ; + +-- the hrad type with genitive -a instead of -u (les - lesa, zákon - zákona) + declHRADAstem : Str -> DeclensionType = \les_,les -> + declHRADstem les_ les ** {sgen = les_ + "a"} ; + + declHRADA : DeclensionType = \les -> + declHRADAstem (dropFleetingE les) les ; + +-- nouns that are adjectives in form: proměnná - proměnné, nultý - nultého + declADJF : DeclensionType = \promenna -> + let a = mladyAdjForms (init promenna + "ý") + in { + snom,svoc = a.fsnom ; + sgen = a.fsgen ; + sdat,sloc = a.fsdat ; + sacc = a.fsacc ; + sins = a.fsins ; + pnom,pacc = a.fpnom ; + pgen,ploc = a.pgen ; + pdat = a.msins ; + pins = a.pins ; + g = Fem + } ; + + declADJM : DeclensionType = \nulty -> + let a = mladyAdjForms nulty + in { + snom,sacc,svoc = a.msnom ; + sgen = a.msgen ; + sdat = a.msdat ; + sloc = a.msloc ; + sins = a.msins ; + pnom,pacc = a.fpnom ; + pgen,ploc = a.pgen ; + pdat = a.msins ; + pins = a.pins ; + g = Masc Inanim + } ; + +-- indeclinable loans: bombé, tamari, software + declINVAR : Gender -> DeclensionType = \g,s -> { + snom,sgen,sdat,sacc,svoc,sloc,sins = s ; + pnom,pgen,pdat,pacc,ploc,pins = s ; + g = g + } ; + declMUZ : DeclensionType = \muz_ -> --- 3.5.3 : sdat,sloc ; pnom - let muz = dropFleetingE muz_ - in + declMUZstem (dropFleetingE muz_) muz_ ; + + declMUZstem : Str -> DeclensionType = \muz,muz_ -> { snom = muz_ ; sgen,sacc = muz + "e" ; --- pacc