1
0
forked from GitHub/gf-core
Files
gf-core/lib/src/mongolian/MorphoMon.gf

619 lines
26 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
--# -path=.:../prelude:../common
-- A Simple Mongolian Resource Morphology
-- based on D.Tserenpil, R.Kullmann: Mongolian Grammar, 4th revised edition, 2008
-- and Damdinsuren: Modern Mongolian Grammar (in Mongolian) 1983
-- This resource morphology contains definitions of the lexical entries
-- needed in the resource syntax.
-- We use the parameter types and word classes defined for morphology. We only
-- treat inflection, not derivation.
resource MorphoMon = ResMon ** open Prelude, Formal in {
flags optimize=all ; coding=utf8 ;
-- Vowel Harmony
-- The 7 vowels (and double vowels, diphthongs, auxiliary vowels) are separated in 3 types:
-- masculine (=hard) vowels а, аа, аЙ, я (a), о, оо, оЙ, ё (o), у, уу, юу, уЙ, ю, юу (u),
-- feminine (=soft) vowels э, ээ, эЙ, е, иЙ (e), ө, өө (ö), ү, үү, юү, үЙ, юЙ, ю, юү (ü),
-- and neuter и (i). Vowel harmony means that word forms must not mix masculine and
-- feminine vowels.
-- Remark: The gender names have nothing to do with genders for nouns;
-- in fact, Mongolian nouns have no gender.
-- Kullmann, p.7, p.20
-- Basic vowel := short or neuter vowel
-- Strong (= Masc or back) short vowels: a | o | u
-- Weak (= Fem or front) short vowels: e| oe | ue
-- Neuter vowel: i
-- Strong resp. weak words (suffixes) are those whose vowels are strong|neuter resp. weak.
oper
mascBasicVowel : pattern Str = #( "а" | "о" | "у" ) ;
femBasicVowel : pattern Str = #( "э" | "ө" | "ү" ) ;
neuterVowel : pattern Str = #( "и" ) ;
yVowel : pattern Str = #("я"|"е"|"ё"|"ю") ;
doubleVowel : pattern Str = #("аа"|"оо"|"уу"| -- mascDoubleVowel (not Kullmann)
"ээ"|"өө"|"үү"| -- femDoubleVowel
"яа"|"ёо"|"еэ"|"еө"|"юу"|"юү"| -- yDoubleVowel
"иа"|"ио"|"иу") ; -- neuterDoubleVowel
diphtVowel : pattern Str =#("й") ;
shortVowel : pattern Str = #("а"|"у"|"о"|"ү"|"э"|"ө") ; -- (masc|fem BasicVowel) ;
basicVowel : pattern Str = #("а"|"у"|"о"|"ү"|"э"|"ө"|"и") ; -- (shortVowel | "и") ;
longVowel : pattern Str = #("аа"|"оо"|"уу"|
"ээ"|"өө"|"үү"|
"яа"|"ёо"|"еэ"|"еө"|"юу"|"юү"|
"иа"|"ио"|"иу"|
"ай"|"ой"|"уй"|"эй"|"үй"|"ий") ;
-- avoid #vowel where it makes too many distinctions!
-- to match double vowels and diphthongs, these must come first?
-- 2.2.2 (Kullmann) Consonants
-- WeakCons = C7 (vocalized: must be preceded or followed by a vowel)
-- StrongCons = C9 (non-vocalized)
oper
c7 : pattern Str = #("м"|"н"|"г"|"л"|"б"|"в"|"р") ;
c9 : pattern Str = #("д"|"ж"|"з"|"с"|"т"|"ц"|"ч"|"ш"|"х") ;
consonant : pattern Str = #("м"|"н"|"г"|"л"|"б"|"в"|"р"|
"д"|"ж"|"з"|"с"|"т"|"ц"|"ч"|"ш"|"х") ;
neuterCons : pattern Str = #("ь") ;
-- Suffixation: dropping the unstressed vowel in the stem: (Kullmann p.24)
-- Adding a suffix beginning with a vowel causes the final unstressed vowel
-- between consonants to drop (unless it has a grammatical function).
-- The vowel is only dropped if it is unstressed, i.e. not the first vowel in the stem.
-- Apply dropVowel in case the suffix begins with a vowel:
-- ("ын"|"ийн"|"ы"|"ий"|"ыг"|"ийг"|"аас"|"ээс"|"өөс"|"оос"
-- |"аар"|"ээр"|"оор"|"өөр"|"ууд"|"үүд"|"иуд"|"иүд"),
-- so we need only check if suffix = ("ы"|"и"|"а"|"э"|"ө"|"о"|"у"|"ү") + rest.
dropUnstressedVowel : Str -> Str = \stem -> case stem of {
_ + #doubleVowel + #consonant => stem ;
x@(_+(#femBasicVowel|"и")+"г") + #femBasicVowel + y@(#c7|#c9) => (x+y) ;
x@(_+#basicVowel+("н"|"г")) + #shortVowel + y@("н"|"г") => stem ;
x@(_+(#basicVowel|"й")+#c7) + #shortVowel + y@#c7 => (x+y) ;
(_+#basicVowel+"ш") + "и" + "н" => stem ; -- "шашин" ; "машин"
x@(_+?+("ж"|"ч"|"ш")) + ("и") + y@#c7 => (x+y) ;
x@(_+#basicVowel+#c7+("хт"|"сч"|"хч"|"ст")) + #shortVowel + y@#c7 => (x+y) ; -- Damdinsuren 18
x@(_+(#diphtVowel|#basicVowel|"ь"+#c9)) + #shortVowel + y@(#c7|#c9) => (x+y) ;
x@(_+(#basicVowel|"ь")+#c9) + #shortVowel + y@(#c7|#c9) => (x+y) ; -- Damdinsuren 18
x@(_+#c7+ #c9) + #shortVowel + y@#c7 => (x+y) ;
_ => stem
} ;
-- examples: cc dropUnstressedVowel "орон"
-- "дусал"
-- "суртал"
-- "төрөлхтөн"
-- We use dropUnstressedVowel in noun declination classes and regN explicitly,
-- and in regV implicitly via addSuf below.
addSuf : Str -> Suffix -> Str = addSuffix ; -- provide a stem and a suffix with voweltype variants,
-- derive the voweltype from the stem and
-- use the appropriate suffix
-- The following addSufVt is used in ParadigmsMon to combine suffix strings,
-- and in the addSuffix-function below.
-- Extend a stem with a suffix string, by inserting a4 (in the given voweltype)
-- or a softness marker (in the given voweltype) between stem and suffix, if needed:
addSufVt : VowelType -> Str -> Str -> Str = \vt, stm, suffix ->
let
insertVowel = table Str { _+("ж"|"ш"|"ч") => "и" ; _ => a4 ! vt } ;
a4 = insertVowel ! stm
in
case stm of {
_ + #yVowel => case suffix of {
#doubleVowel + _ => stm + Predef.drop 1 suffix ;
_ => stm + suffix } ;
_ + #longVowel => case suffix of {
#doubleVowel + _ => stm + "г" + suffix ;
_ => stm + suffix } ;
_ + y@(#c7|#c9) + "и" => case suffix of {
"" => Predef.tk 1 stm + "ь" ;
#doubleVowel + _ => stm + Predef.drop 1 suffix ;
#yVowel => Predef.tk 1 stm + "ь" + suffix ;
"х" + _ => stm + suffix ;
#c9 + _ => case y of {
#c7 => Predef.tk 1 stm + "ь" + suffix ;
_ => stm + suffix } ;
_ => stm + suffix} ;
x + y@("лг"|(#c7+"л")) + #shortVowel => case suffix of {
#doubleVowel + _ => x + y + suffix ;
_ => stm + suffix } ;
_ + #consonant + #consonant => case suffix of {
("на"|"нэ"|"нө"|"но"|("х" + _)|"я"|"ё"|"е") => stm + a4 + suffix ;
(#consonant + (""|(#consonant + _))) => stm + a4 + suffix ;
_ => stm + suffix } ;
_ + #basicVowel + c@(#c7|#c9) => case suffix of {
("я"|"ё") => stm + "ъ" + suffix ;
"е" => stm + "ь" + suffix ;
(("х" + _)|("в"|"г")) => stm + a4 + suffix ;
"ж" => case c of {
#c9 => stm + a4 + suffix ;
_ => stm + suffix } ;
y@#consonant + #consonant + _ => case c of {
#c7 => case y of {
#c9 => stm + suffix ;
_ => stm + a4 + suffix } ;
_ => stm + a4 + suffix } ;
_ => stm + suffix
} ;
_ => stm + suffix
} ;
-- Given a string (a stem perhaps extended by suffixes) and a suffix varying with
-- the vowel type, choose the proper suffix variant, and concatenate (with addSufVt)
-- both, with insertion of a vowel/softness sign
addSuffix : Str -> Suffix -> Str = \stem,suffix ->
let
vt = vowelType stem ;
suf = suffix ! vt
in addSufVt vt stem suf ;
stemVerb : Str -> Str = \inf -> case inf of {
stem@(_ + ("ч"|"ш"|"ж")) + "их" => stem ;
stem@(_ + ("и"|#longVowel|#yVowel)) + "х" => stem ;
stem@(_ + "н" + #shortVowel) + "х" => stem ;
stem@(_ + #c7 + "л" + #shortVowel) + "х" => stem ;
stem@(_ + #c9) + "л" + v@(#shortVowel) + "х" => case stem of {
_ + ("ж"|"ш"|"ч") => stem + "и" + "л" ;
_ => stem + v + "л" } ;
stem@((#consonant)* + ?) + "х" => stem ;
_ => Predef.tk 2 inf
} ;
-- Personal pronouns with possessive as additional PronForm:
oper
pronEnding : VowelType => RCase => Str = table {
MascA => table RCase ["";"ын";"ад";"ыг";"аас";"аар";"тай";"руу"] ;
_ => table RCase ["";"ийн";"эд";"ийг";"ээс";"ээр";"тэй"; "рүү"]
} ;
mkPron : (_,_,_,_,_,_,_,_ : Str) -> Number -> Person -> Pron =
\bi,minii,nadad,namaig,nadaas,nadaar,nadtai,nadruu,n,p ->
let
vt = vowelType minii
in {
s = table {
PronCase rc => table RCase [bi;minii;nadad;namaig;nadaas;nadaar;nadtai;nadruu] ! rc ;
PronPoss rc => minii + "х" + pronEnding ! vt ! rc
} ;
n = n ;
p = p
} ;
-- Nouns
-- Mongolian noun declension
-- There are 5 different plural suffixes, 4 genitive, 2 dative, 2 accusative, 2 directive.
-- an ablative, comitative and instrumental suffix which depends on the vowel harmony.
oper
plSuffix : Str -> Str = \stem ->
let
vt = vowelType stem ;
stemDr = dropUnstressedVowel stem -- doesn't drop the vowel in loan words, cf. mkDecl
in
table VowelType { vts => case stem of {
_ + #basicVowel + ("гч"|"лч"|"ч") => stem + "ид" ; -- зохиолчид
y@(_ + #doubleVowel + #consonant) + "ь" => y + iud2 ! vts ; -- сургуулиуд
y + ("ь") => y + "и" + nuud2 ! vts ; -- хонинууд
_ + ("сан"|"нан"|"нин"|"шин") => stem + guud2 ! vts ; -- шашингууд
_ + #consonant + #consonant + "и" => stem + nuud2 ! vts ; -- тамхинууд
_ + "р" => stemDr + uud2 ! vts ; -- чихрүүд
_ + ("га"|"гэ"|"го"|"гө") => stem + nuud2 ! vts ; -- хурганууд
_ + "ран" => stem + uud2 ! vts ;
y + "н" => y + "д" ; --охид
y@(_ + #consonant) + #shortVowel => y + uud2 ! vts ;
_ => stem + nuud2 ! vts -- туулайнууд
}
} ! vt ;
-- mkDecl is used for declension of nouns and proper names, depending on the
-- parameter drop:Bool. The parameter drop is used to distinguish between
-- declination for ordinary nouns and declination for proper names
-- and foreign nouns. If the suffix added begins with a vowel, the
-- unstressed vowel in the stem has to be dropped in noun declension, but not in
-- proper name declension. The dropping function is dropUnstressedVowel for
-- nouns, but the identity for proper names. For nouns, drop=True,
-- and a function dropUnstressedVowel is applied to the stem;
-- for proper names, drop=False suppresses the vowel dropping.
-- Note: It is much more efficient to use a flag drop:Bool instead of a parameter
-- drop:(Str -> Str) which is later instantiated to \x->x or dropUnstressedVowel only.
-- A previous version with a function parameter drop:(Str->Str) was much slower.
SemiDcl : Type = Str -> Str -> VowelType => NCase => Str ;
sgDcl : SemiDcl = \stem,stemDr -> \\vts =>
table { NNom => stem ;
NGen => stemDr + iin2 ! vts ;
NDat => stem + "д" ;
NAcc d => case d of {
Definite => stem ;
Indefinite => stemDr + iig2 ! vts } ;
NAbl => stemDr + aas4 ! vts ;
NInst => stemDr + aar4 ! vts ;
NCom => stem + tai3 ! vts ;
NDir => stem ++ ruu2 ! vts
} ;
plDcl : SemiDcl = \stem,stemDr -> \\vts =>
table { NNom => stem ;
NGen => stemDr + iin2 ! vts ;
NDat => case stem of { _ + "нар" => stem + "т" ;
_ => stemDr + ad4 ! vts } ;
NAcc d => case d of {
Definite => stem ;
Indefinite => stemDr + iig2 ! vts } ;
NAbl => stemDr + aas4 ! vts ;
NInst => stemDr + aar4 ! vts ;
NCom => stem + tai3 ! vts ;
NDir => stem ++ (case stem of { _ + "нар" => "луу" ;
_ => ruu2 ! vts })
} ;
Dcl : Type = Str -> Str -> Str -> Str -> VowelType => VowelType => SubstForm => Str ;
nounDcl : Dcl = \stem,stemDr,stemPl,stemPlDr -> \\vts => \\vtp =>
table { SF Sg NNom => stem ;
SF Sg NGen => stemDr + iin2 ! vts ;
SF Sg NDat => stem + "д" ;
SF Sg (NAcc d) => case d of {
Definite => stemDr + iig2 ! vts ;
Indefinite => stem} ;
SF Sg NAbl => stemDr + aas4 ! vts ;
SF Sg NInst => stemDr + aar4 ! vts ;
SF Sg NCom => stem + tai3 ! vts ;
SF Sg NDir => stem ++ ruu2 ! vts ;
SF Pl NNom => stemPl ;
SF Pl NGen => stemPlDr + iin2 ! vtp ;
SF Pl NDat => stemPlDr + a4 ! vtp + "д" ;
SF Pl (NAcc d) => case d of {
Definite => stemPlDr + iig2 ! vts ;
Indefinite => stemPl} ;
SF Pl NAbl => stemPlDr + aas4 ! vtp ;
SF Pl NInst => stemPlDr + aar4 ! vtp ;
SF Pl NCom => stemPl + tai3 ! vtp ;
SF Pl NDir => stemPl ++ ruu2 ! vtp
} ;
gaDcl : Dcl = \stem,stemDr,stemPl,stemPlDr -> \\vts,vtp =>
let
n = nounDcl stem stemDr stemPl stemPlDr ! vts ! vtp ;
gaStem = Predef.tk 1 stem
in
table { SF Sg NGen => stem + nii2 ! vts ;
SF Sg NDat => stem + "нд" ;
SF Sg (NAcc d) => case d of {
Definite => gaStem + iig2 ! vts ;
Indefinite => stem } ;
SF Sg NAbl => stem + naas4 ! vts ;
SF Sg NInst => gaStem + aar4 ! vts ;
sf => n ! sf } ;
longDcl : Dcl = \stem,stemDr,stemPl,stemPlDr -> \\vts,vtp =>
let
ga = gaDcl stem stemDr stemPl stemPlDr ! vts ! vtp
in
table { SF Sg (NAcc d) => case d of {
Definite => stem + "г" ;
Indefinite => stem } ;
SF Sg NInst => stem + gaar4 ! vts ;
sf => ga ! sf } ;
iDcl : Dcl = \stem,stemDr,stemPl,stemPlDr -> \\vts,vtp =>
let
ga = gaDcl stem stemDr stemPl stemPlDr ! vts ! vtp ;
iStem = Predef.tk 1 stem
in
table { SF Sg (NAcc d) => case d of {
Definite => iStem + "ийг" ;
Indefinite => stem } ;
SF Sg NInst => iStem + iar3 ! vts ;
sf => ga ! sf } ;
nDcl : Dcl = \stem,stemDr,stemPl,stemPlDr -> \\vts,vtp =>
let
n = nounDcl stem stemDr stemPl stemPlDr ! vts ! vtp
in
table { SF Sg NGen => stemDr + i2 ! vts ;
sf => n ! sf } ;
shDcl : Dcl = \stem,stemDr,stemPl,stemPlDr -> \\vts,vtp =>
let
ga = gaDcl stem stemDr stemPl stemPlDr ! vts ! vtp
in
table { SF Sg NDat => stemDr + and4 ! vts ;
SF Sg (NAcc d) => case d of {
Definite => stemDr + iig2 ! vts ;
Indefinite => stem } ;
SF Sg NInst => stemDr + aar4 ! vts ;
sf => ga ! sf } ;
gDcl : Dcl = \stem,stemDr,stemPl,stemPlDr -> \\vts,vtp =>
let
k = c92kDcl stem stemDr stemPl stemPlDr ! vts ! vtp
in
table { SF Sg NGen => stemDr + "ийн" ;
SF Sg NDat => stem + "т" ;
sf => k ! sf } ;
vDcl : Dcl = \stem,stemDr,stemPl,stemPlDr -> \\vts,vtp =>
let
n = nounDcl stem stemDr stemPl stemPlDr ! vts ! vtp
in
table { SF Sg NDat => stem + "т";
sf => n ! sf } ;
shortDcl : Dcl = \stem,stemDr,stemPl,stemPlDr -> \\vts,vtp =>
let
ga = gaDcl stem stemDr stemPl stemPlDr ! vts ! vtp ;
shortStem = Predef.tk 1 stem ;
in
table { SF Sg NGen => shortStem + iin2 ! vts ;
SF Sg NDat => stem + "д" ;
SF Sg NAbl => shortStem + aas4 ! vts ;
sf => ga ! sf } ;
c91Dcl : Dcl = \stem,stemDr,stemPl,stemPlDr -> \\vts,vtp =>
let
sh = shDcl stem stemDr stemPl stemPlDr ! vts ! vtp
in
table { SF Sg NGen => case stem of {
_ + #doubleVowel + "лт" => stem + iin2 ! vts ;
_ => stem + nii2 ! vts } ;
sf => sh ! sf } ;
c92kDcl : Dcl = \stem,stemDr,stemPl,stemPlDr -> \\vts,vtp =>
let
ga = gaDcl stem stemDr stemPl stemPlDr ! vts ! vtp
in
table { SF Sg NDat => stemDr + "инд" ;
SF Sg (NAcc d) => case d of {
Definite => stemDr + "ийг" ;
Indefinite => stem } ;
SF Sg NInst => stemDr + aar4 ! vts ;
sf => ga ! sf } ;
yeyaDcl : Dcl = \stem,stemDr,stemPl,stemPlDr -> \\vts,vtp =>
let
n = nounDcl stem stemDr stemPl stemPlDr ! vts ! vtp
in
table { SF Sg NAbl => stemDr + as4 ! vts ;
SF Sg NInst => stemDr + ar4 ! vts ;
sf => n ! sf } ;
rDcl : Dcl = \stem,stemDr,stemPl,stemPlDr -> \\vts,vtp =>
let
n = nounDcl stem stemDr stemPl stemPlDr ! vts ! vtp
in
table { SF Sg NDat => stem + "т";
SF Sg NAbl => stem + naas4 ! vts ;
SF Pl NDir => stem ++ luu2 ! vts ;
sf => n ! sf } ;
neuterConsDcl : Dcl = \stem,stemDr,stemPl,stemPlDr -> \\vts,vtp =>
let
ga = gaDcl stem stemDr stemPl stemPlDr ! vts ! vtp ;
neuterConsStem = Predef.tk 1 stem ;
nCstem = neuterConsStem + "и"
in
table { SF Sg NGen => nCstem + nii2 ! vts ;
SF Sg NDat => nCstem + "нд" ;
SF Sg NAbl => neuterConsStem + ias3 ! vts ;
SF Sg (NAcc d) => case d of {
Definite => neuterConsStem + "ийг" ;
Indefinite => stem } ;
SF Sg NInst => neuterConsStem + iar3 ! vts ;
sf => ga ! sf } ;
lneuterConsDcl : Dcl = \stem,stemDr,stemPl,stemPlDr -> \\vts,vtp =>
let
nC = neuterConsDcl stem stemDr stemPl stemPlDr ! vts ! vtp ;
neuterConsStem = Predef.tk 1 stem ;
in
table { SF Sg NGen => neuterConsStem + "ийн" ;
SF Sg NDat => stem + "д" ;
sf => nC ! sf } ;
modDcl01a : Dcl -> Dcl = \dcl -> \stem,stemDr,stemPl,stemPlDr -> \\vts,vtp =>
let
d = dcl stem stemDr stemPl stemPlDr ! vts ! vtp
in
table { SF Sg NGen => case stem of {
_ + "й" => stem + "н" ;
_ => stem + nii2 ! vts } ;
SF Sg NDat => case stem of {
_ + "й" => stem + "д" ;
_ => stemDr + and4 ! vts } ;
SF Sg NAbl => case stem of {
_ + "й" => stem + gaas4 ! vts ;
_ => stem + naas4 ! vts } ;
sf => d ! sf } ;
modDcl01b : Dcl -> Dcl = \dcl -> \stem,stemDr,stemPl,stemPlDr -> \\vts,vtp =>
let
d = dcl stem stemDr stemPl stemPlDr ! vts ! vtp
in
table { SF Sg NDat => stemDr + and4 ! vts ;
sf => d ! sf } ;
modDcl01c : Dcl -> Dcl = \dcl -> \stem,stemDr,stemPl,stemPlDr -> \\vts,vtp =>
let
d = dcl stem stemDr stemPl stemPlDr ! vts ! vtp
in
table { SF Sg NAbl => stemDr + aas4 ! vts ;
sf => d ! sf } ;
modDcl01d : Dcl -> Dcl = \dcl -> \stem,stemDr,stemPl,stemPlDr -> \\vts,vtp =>
let
nSg = dcl stem stemDr stemPl stemPlDr ! vts ! vtp ;
stemSg = stem + "г" ;
stemPl = stemSg + uud2 ! vtp ; -- overwrite stemPl,stemPlDr
nPl = plDcl stemPl stemPl ! vtp
in
table { SF Sg NGen => stemSg + "ийн" ;
SF Sg (NAcc d) => case d of {
Definite => stemSg ;
Indefinite => stem } ;
SF Sg NAbl => stemSg + aas4 ! vts ;
SF Sg NInst => stemSg + aar4 ! vts ;
SF Sg c => nSg ! SF Sg c ;
SF Pl NGen => stemPl + iin2 ! vtp ;
SF Pl NDat => stemPl + a4 ! vtp + "д" ;
SF Pl NAbl => stemPl + aas4 ! vtp ;
SF Pl c => nPl ! c } ;
modDcl01e : Dcl -> Dcl = \dcl -> \stem,stemDr,stemPl,stemPlDr -> \\vts,vtp =>
let
nSg = dcl stem stemDr stemPl stemPlDr ! vts ! vtp ;
stemPl = stemDr + uud2 ! vts ; -- overwrite stemPl,stemPlDr
nPl = plDcl stemPl stemPl ! vts
in
table { SF Sg NAbl => stemDr + aas4 ! vts ;
SF Sg nc => nSg ! (SF Sg nc) ;
SF Pl NGen => stemPl + iin2 ! vtp ;
SF Pl NDat => stemPl + a4 ! vtp + "д" ;
SF Pl NAbl => stemPl + aas4 ! vtp ;
SF Pl nc => nPl ! nc } ;
modDcl01f : Dcl -> Dcl = \dcl -> \stem,stemDr,stemPl,stemPlDr -> \\vts,vtp =>
let
e = (modDcl01e dcl) stem stemDr stemPl stemPlDr ! vts !vtp
in
table { SF Sg NGen => stemDr + iin2 ! vts ;
SF Sg NDat => stemDr + ad4 ! vts ;
sf => e ! sf } ;
modDcl01g : Dcl -> Dcl = \dcl -> \stem,stemDr,stemPl,stemPlDr -> \\vts,vtp =>
let
nSg = dcl stem stemDr stemPl stemPlDr ! vts ! vtp
in
table { SF n nc => case n of { Sg => nSg ! SF Sg nc ;
Pl => [] } } ;
modDcl01h : Dcl -> Dcl = \dcl -> \stem,stemDr,stemPl,stemPlDr -> \\vts,vtp =>
let
nSg = dcl stem stemDr stemPl stemPlDr ! vts ! vtp ; -- stemPl,stemPlDr irrelevant
stemPl = stem + nuud2 ! vts ;
nPl = plDcl stemPl stemPl ! vts
in
table { SF Sg NGen => stem + nii2 ! vts ;
SF Sg NDat => stemDr + and4 ! vts ;
SF Sg nc => nSg ! (SF Sg nc) ;
SF Pl NGen => stemPl + iin2 ! vtp ;
SF Pl NDat => stemPl + ad4 ! vtp ;
SF Pl nc => nPl ! nc } ;
modDcl2N : Dcl -> Dcl = \dcl -> \stem,stemDr,stemPl,stemPlDr -> \\vts,vtp =>
let
nSg = dcl stem stemDr stemPl stemPlDr ! vts ! vtp ;
nPl = plDcl stemPl stemPlDr ! vtp
in
table { SF Sg nc => nSg ! (SF Sg nc) ;
SF Pl nc => nPl ! nc } ;
modDcl02a : Dcl -> Dcl = \dcl -> \stem,stemDr,stemPl,stemPlDr -> \\vts,vtp =>
let
nSgPl = (modDcl2N dcl) stem stemDr stemPl stemPlDr ! vts ! vtp -- reg2N stem nompl ;
in
table { SF Sg NGen => case stem of {
_ + #longVowel => stem + "г" + "ийн" ;
_ + ("ж"|"ч"|"ш") => stemDr + "ийн" ;
_ => stemDr + iin2 ! vts } ;
SF Sg NDat => case stem of {
_ + #longVowel => stem + "д" ;
_ + ("ж"|"ч"|"ш") => stem + "ид" ;
_ => stemDr + ad4 ! vts } ;
SF Sg NAbl => case stem of {
_ + #longVowel => stem + "г" + aas4 ! vts ;
_ => stemDr + aas4 ! vts } ;
sf => nSgPl ! sf } ;
modDcl02b : Dcl -> Dcl = \dcl -> \stem,stemDr,stemPl,stemPlDr -> \\vts,vtp =>
let
nSgPl = (modDcl2N dcl) stem stemDr stemPl stemPlDr ! vts ! vtp
in
table { SF Pl NGen => stemPlDr + iin2 ! vtp ;
SF Pl NDat => stemPlDr + ad4 ! vtp ;
SF Pl NAbl => stemPlDr + aas4 ! vtp ;
sf => nSgPl ! sf } ;
modDcl02c : Dcl -> Str -> Dcl = \dcl,ablsg -> \stem,stemDr,stemPl,stemPlDr -> \\vts,vtp =>
let
nSgPl = dcl stem stemDr stemPl stemPlDr ! vts ! vtp
in
table { SF Sg NDat => stemDr + and4!vts ;
SF Sg NAbl => ablsg ;
sf => nSgPl ! sf } ;
modDcl02d : Dcl -> Dcl = \dcl -> \stem,stemDr,stemPl,stemPlDr -> \\vts,vtp =>
let
nSgPl = (modDcl2N dcl) stem stemDr stemPl stemPlDr ! vts ! vtp
in
table { SF Sg NDat => stem + "д" ;
SF Sg NAbl => stem + aas4 ! vts ;
SF Pl NGen => stemPl + iin2 ! vtp ;
SF Pl NAbl => stemPl + aas4 ! vtp ;
sf => nSgPl ! sf } ;
modDcl02e : Dcl -> Dcl = \dcl -> \stem,stemDr,stemPl,stemPlDr -> \\vts,vtp =>
let
nSgPl = (modDcl02b dcl) stem stemDr stemPl stemPlDr ! vts ! vtp
in
table { SF Pl NDat => stemPl + "т" ;
sf => nSgPl ! sf } ;
-- Slower with optimize=noexpand:
mkDecl : Bool => Dcl -> Str -> Noun = \\drop => \dcl -> \stem ->
let
stemDr = case drop of { False => stem ; _ => dropUnstressedVowel stem } ;
stemPl = plSuffix stem ;
stemPlDr = case drop of { False => stemPl ; _ => dropUnstressedVowel stemPl } ;
vts = vowelType stem ;
vtp = case stemPl of {"" => MascA ;
_ + ("үүд"|"ууд") => vowelType (uud2!vts) ;
_ => vowelType stemPl }
in
{ s = (dcl stem stemDr stemPl stemPlDr) ! vts ! vtp } ;
mkDeclDrop : Dcl -> Str -> Noun = (mkDecl ! True) ;
mkDeclNoDrop : Dcl -> Str -> Noun = (mkDecl ! False) ;
mkDecl2 : Bool => Dcl -> Str -> Str -> Noun = \\drop => \dcl,stem,stemPl ->
let
vts = vowelType stem ;
vtp = vowelType stemPl ;
stemDr = case drop of { False => stem ; _ => dropUnstressedVowel stem } ;
stemPlDr = case drop of { False => stemPl ; _ => dropUnstressedVowel stemPl }
in
{ s = (dcl stem stemDr stemPl stemPlDr) ! vts ! vtp } ;
mkDecl2Drop : Dcl -> Str -> Str -> Noun = (mkDecl2!True) ;
mkDecl2NoDrop : Dcl -> Str -> Str -> Noun = (mkDecl2!False) ;
};