diff --git a/src/estonian/AdjectiveEst.gf b/src/estonian/AdjectiveEst.gf index 5cf65d4e..cb43fe1b 100644 --- a/src/estonian/AdjectiveEst.gf +++ b/src/estonian/AdjectiveEst.gf @@ -11,14 +11,14 @@ concrete AdjectiveEst of Adjective = CatEst ** open ResEst, Prelude in { } ; ComparA a np = { s = \\isMod,af => case isMod of { - True => np.s ! NPCase Elat ++ a.s ! Compar ! AN af ; -- minust suurem - _ => a.s ! Compar ! AN af ++ "kui" ++ np.s ! NPCase Nom -- suurem kui mina + True => linNP (NPCase Elat) np ++ a.s ! Compar ! AN af ; -- minust suurem + _ => a.s ! Compar ! AN af ++ "kui" ++ linNP (NPCase Nom) np -- suurem kui mina } ; infl = Regular ; --a.infl } ; CAdvAP ad ap np = { - s = \\m,af => ad.s ++ ap.s ! m ! af ++ ad.p ++ np.s ! NPCase Nom ; + s = \\m,af => ad.s ++ ap.s ! m ! af ++ ad.p ++ linNP (NPCase Nom) np ; infl = ap.infl } ; UseComparA a = { diff --git a/src/estonian/AdverbEst.gf b/src/estonian/AdverbEst.gf index 566f3475..8b750f62 100644 --- a/src/estonian/AdverbEst.gf +++ b/src/estonian/AdverbEst.gf @@ -5,7 +5,7 @@ concrete AdverbEst of Adverb = CatEst ** open ResEst, Prelude in { lin PositAdvAdj a = {s = a.s ! Posit ! AAdv} ; ComparAdvAdj cadv a np = { - s = cadv.s ++ a.s ! Posit ! AAdv ++ cadv.p ++ np.s ! NPCase Nom + s = cadv.s ++ a.s ! Posit ! AAdv ++ cadv.p ++ linNP (NPCase Nom) np } ; ComparAdvAdjS cadv a s = { s = cadv.s ++ a.s ! Posit ! AAdv ++ cadv.p ++ s.s diff --git a/src/estonian/CatEst.gf b/src/estonian/CatEst.gf index 0b8b5cc6..945f55d1 100644 --- a/src/estonian/CatEst.gf +++ b/src/estonian/CatEst.gf @@ -20,7 +20,7 @@ concrete CatEst of Cat = CommonX ** open HjkEst, ResEst, Prelude in { -- Question QCl = {s : ResEst.Tense => Anteriority => Polarity => Str} ; - IP = {s : NPForm => Str ; n : Number} ; + IP = ResEst.IPhrase ; IComp = {s : Agr => Str} ; IDet = {s : Case => Str ; n : Number ; isNum : Bool} ; IQuant = {s : Number => Case => Str} ; @@ -28,7 +28,7 @@ concrete CatEst of Cat = CommonX ** open HjkEst, ResEst, Prelude in { -- Relative RCl = {s : ResEst.Tense => Anteriority => Polarity => Agr => Str ; c : NPForm} ; - RP = {s : Number => NPForm => Str ; a : RAgr} ; + RP = ResEst.RelPron ; -- Verb @@ -43,20 +43,14 @@ concrete CatEst of Cat = CommonX ** open HjkEst, ResEst, Prelude in { -- The $Infl$ in infl tells whether the adjective inflects as a -- modifier: e.g. "väsinud mehele" vs. "mees muutus väsinuks". - AP = {s : Bool => NForm => Str ; infl : Infl} ; + AP = ResEst.APhrase ; -- Noun - CN = {s : NForm => Str} ; + CN = ResEst.CNoun ; Pron = {s : NPForm => Str ; a : Agr} ; - NP = {s : NPForm => Str ; a : Agr ; isPron : Bool} ; - DAP, Det = { - s : Case => Str ; -- minun kolme - sp : Case => Str ; -- se (substantival form) - n : Number ; -- Pl (agreement feature for verb) - isNum : Bool ; -- True (a numeral is present) - isDef : Bool -- True (verb agrees in Pl, Nom is not Part) --I: actually, can we get rid of this? - } ; + NP = ResEst.NPhrase ; + DAP, Det = ResEst.Determiner ; ---- QuantSg, QuantPl = {s : Case => Str ; isDef : Bool} ; Ord = {s : NForm => Str} ; @@ -75,26 +69,34 @@ concrete CatEst of Cat = CommonX ** open HjkEst, ResEst, Prelude in { Conj = {s1,s2 : Str ; n : Number} ; ----b DConj = {s1,s2 : Str ; n : Number} ; Subj = {s : Str} ; - Prep = Compl ; + Prep = ResEst.Compl ; -- Open lexical classes, e.g. Lexicon - V, VS, VQ = Verb1 ; -- = {s : VForm => Str ; sc : Case} ; - V2, VA, V2Q, V2S = Verb2 ; - V2A, V3 = Verb3 ; - VV = Verb1 ** {vi : InfForms} ; - V2V = Verb2 ** {vi : InfForms} ; + V, VS, VQ = ResEst.Verb1 ; -- = {s : VForm => Str ; sc : Case} ; + V2, VA, V2Q, V2S = ResEst.Verb2 ; + V2A, V3 = ResEst.Verb3 ; + VV = ResEst.Verb1 ** {vi : InfForms} ; + V2V = ResEst.Verb2 ** {vi : InfForms} ; - A = Adjective ** {infl : Infl} ; - A2 = A ** {c2 : Compl} ; + A = ResEst.Adjective ** {infl : Infl} ; + A2 = ResEst.Adjective ** {infl : Infl ; c2 : Compl} ; - N = Noun ; - N2 = Noun ** {c2 : Compl ; isPre : Bool} ; - N3 = Noun ** {c2,c3 : Compl ; isPre,isPre2 : Bool} ; + N = ResEst.Noun ; + N2 = ResEst.Noun ** { + postmod : Str ; -- postmod, because N2 can come from N3+complement via ComplN3 + c2 : Compl ; + isPre : Bool} ; + N3 = ResEst.Noun ** { -- no postmod, because N3 can only come from lexical funs + c2,c3 : Compl ; + isPre,isPre2 : Bool + } ; PN = {s : Case => Str} ; linref VP = \vp -> linV vp.v ; + NP = linNP (NPCase Nom) ; + CN = linCN (NCase Sg Nom) ; V,VS,VQ = linV ; V2,VA,V2S,V2Q = linV2 ; diff --git a/src/estonian/ConjunctionEst.gf b/src/estonian/ConjunctionEst.gf index d7517733..51169db4 100644 --- a/src/estonian/ConjunctionEst.gf +++ b/src/estonian/ConjunctionEst.gf @@ -9,11 +9,12 @@ concrete ConjunctionEst of Conjunction = ConjAdv = conjunctDistrSS ; - ConjCN = conjunctDistrTable NForm ; + ConjCN conj ss = conjunctDistrTable NForm conj ss ** ss ; ConjNP conj ss = conjunctDistrTable NPForm conj ss ** { a = conjAgr (Ag conj.n P3) ss.a ; -- P3 is the maximum - isPron = False + isPron = False ; + postmod = ss.postmod } ; ConjAP conj ss = conjunctDistrTableAdj conj ss ; @@ -28,20 +29,20 @@ concrete ConjunctionEst of Conjunction = ConsS = consrSS comma ; BaseAdv = twoSS ; ConsAdv = consrSS comma ; - BaseCN = twoTable NForm ; - ConsCN = consrTable NForm comma ; - BaseNP x y = twoTable NPForm x y ** {a = conjAgr x.a y.a} ; - ConsNP xs x = consrTable NPForm comma xs x ** {a = conjAgr xs.a x.a} ; + BaseCN x y = twoTable NForm (mergeCN x) y ** {postmod = y.postmod} ; + ConsCN x xs = consrTable NForm comma (mergeCN x) xs ** xs ; + BaseNP x y = twoTable NPForm (mergeNP x) y ** {a = conjAgr x.a y.a ; postmod = y.postmod} ; + ConsNP x xs = consrTable NPForm comma (mergeNP x) xs ** {a = conjAgr xs.a x.a ; postmod = xs.postmod} ; BaseAP x y = twoTableAdj x y ; - ConsAP xs x = consrTableAdj comma x xs ; + ConsAP x xs = consrTableAdj comma x xs ; BaseRS x y = twoTable Agr x y ** {c = y.c} ; - ConsRS xs x = consrTable Agr comma xs x ** {c = xs.c} ; + ConsRS x xs = consrTable Agr comma x xs ** {c = xs.c} ; lincat [S] = {s1,s2 : Str} ; [Adv] = {s1,s2 : Str} ; - [CN] = {s1,s2 : NForm => Str} ; - [NP] = {s1,s2 : NPForm => Str ; a : Agr} ; + [CN] = {s1,s2 : NForm => Str ; postmod : Str} ; + [NP] = {s1,s2 : NPForm => Str ; a : Agr ; postmod : Str} ; [AP] = {s1,s2 : {s : Bool => NForm => Str ; infl : Infl }} ; [RS] = {s1,s2 : Agr => Str ; c : NPForm} ; @@ -53,7 +54,7 @@ concrete ConjunctionEst of Conjunction = s2 = y } ; - consrTableAdj : Str -> [AP] -> {s : Bool => NForm => Str ; infl : Infl} -> [AP] = \c,xs,x -> + consrTableAdj : Str -> APhrase -> [AP] -> [AP] = \c,x,xs -> let ap1 = xs.s1 ; ap2 = xs.s2 @@ -101,4 +102,7 @@ concrete ConjunctionEst of Conjunction = infl = Regular } ; + -- for CN and NP with discontinuous fields, put all stuff in s field + mergeNP : NPhrase -> NPhrase = \np -> np ** {s = \\c => linNP c np} ; + mergeCN : CNoun -> CNoun = \cn -> cn ** {s = \\nf => linCN nf cn} ; } diff --git a/src/estonian/ExtendEst.gf b/src/estonian/ExtendEst.gf index c953be65..b8b2ebd4 100644 --- a/src/estonian/ExtendEst.gf +++ b/src/estonian/ExtendEst.gf @@ -90,7 +90,7 @@ concrete ExtendEst of Extend = RNPList = {s1,s2 : Agr => NPForm => Str} ; oper - rnp2np : Agr -> RNP -> NP = \agr,rnp -> lin NP { + rnp2np : Agr -> RNP -> NPhrase = \agr,rnp -> emptyNP ** { a = agr ; s = rnp.s ! agr ; isPron = False ; -- ?? @@ -159,7 +159,7 @@ concrete ExtendEst of Extend = AdAdV ad adv = AdAdv ad adv ; -- : AP -> CN ; -- a green one ; en grön (Swe) - AdjAsCN ap = {s = ap.s ! True} ; -- True = attributive ; False = predicative + AdjAsCN ap = emptyCN ** {s = ap.s ! True} ; -- True = attributive ; False = predicative -- : AP -> NP AdjAsNP ap = MassNP (AdjAsCN ap) ; @@ -270,14 +270,14 @@ concrete ExtendEst of Extend = lin -- : NP -> Quant ; -- this man's GenNP np = { - s,sp = \\_,_ => np.s ! NPCase Gen ; + s,sp = \\_,_ => linNP (NPCase Gen) np ; isNum = False ; isDef = True ; isNeg = False } ; -- : IP -> IQuant ; -- whose - GenIP ip = {s = \\_,_ => ip.s ! NPCase Gen} ; + GenIP ip = {s = \\_,_ => linIP (NPCase Gen) ip} ; -- : Num -> CN -> RP ; -- whose car GenRP num cn = { @@ -298,7 +298,7 @@ concrete ExtendEst of Extend = GerundAdv vp = {s = infVPdefault vp InfDes} ; -- : VP -> CN -- publishing of the document (can get a determiner) - GerundCN vp = {s = \\nf => infVPdefault vp InfMine} ; + GerundCN vp = emptyCN ** {s = \\nf => infVPdefault vp InfMine} ; -- : VP -> NP -- publishing the document (by nature definite) GerundNP vp = MassNP (GerundCN vp) ; @@ -331,7 +331,7 @@ concrete ExtendEst of Extend = -- : VPSlash -> NP -> VP ; -- be begged by her to go PassAgentVPSlash vps np = let vp : VP = PassVPSlash vps in vp ** { - adv = vp.adv ++ np.s ! NPCase Gen ++ "poolt" ; + adv = vp.adv ++ appCompl True Pos by8agent_Prep np ; } ; @@ -357,7 +357,7 @@ concrete ExtendEst of Extend = -- : VPSlash -> NP -> AP -- hobisukeldujate poolt leitud (süvaveepomm) PastPartAgentAP vp np = { - s = \\_,_ => np.s ! NPCase Gen ++ "poolt" ++ vp2adv vp True (VIPass Past) ; + s = \\_,_ => appCompl True Pos by8agent_Prep np ++ vp2adv vp True (VIPass Past) ; infl = Invariable } ; @@ -407,11 +407,11 @@ concrete ExtendEst of Extend = UseDAPFem, UseDAPMasc = DetNP ; - UttAccIP ip = {s = ip.s ! NPAcc} ; - UttAccNP np = {s = np.s ! NPAcc} ; + UttAccIP ip = {s = linIP NPAcc ip} ; + UttAccNP np = {s = linNP NPAcc np} ; UttAdV adv = adv ; - UttDatIP ip = {s = ip.s ! NPCase Part} ; -- is partitive a reasonable translation? - UttDatNP np = {s = np.s ! NPCase Part} ; + UttDatIP ip = {s = linIP (NPCase Part) ip} ; -- is partitive a reasonable translation? + UttDatNP np = {s = linNP (NPCase Part) np} ; -- : VP -> Utt ; -- There's no "short form", so just using InfDa instead of InfMa UttVPShort vp = {s = infVPdefault vp InfDa} ; diff --git a/src/estonian/ExtraEst.gf b/src/estonian/ExtraEst.gf index 644d8e9e..4fc96a0b 100644 --- a/src/estonian/ExtraEst.gf +++ b/src/estonian/ExtraEst.gf @@ -3,7 +3,7 @@ concrete ExtraEst of ExtraEstAbs = CatEst ** flags coding=utf8; lin GenNP np = { - s,sp = \\_,_ => np.s ! NPCase Gen ; + s,sp = \\_,_ => linNP (NPCase Gen) np ; isNum = False ; isDef = True ; --- "Jussin kolme autoa ovat" ; thus "...on" is missing isNeg = False @@ -15,7 +15,7 @@ concrete ExtraEst of ExtraEstAbs = CatEst ** AbessCN = caseCN Abessive ; -- autota pere TerminCN = caseCN Terminative ; -- maani kleit - GenIP ip = {s = \\_,_ => ip.s ! NPCase Gen} ; + GenIP ip = {s = \\_,_ => linIP (NPCase Gen) ip} ; GenRP num cn = { s = \\n,c => let k = npform2case num.n c in relPron ! NCase n Gen ++ cn.s ! NCase num.n k ; @@ -87,7 +87,7 @@ concrete ExtraEst of ExtraEstAbs = CatEst ** PassAgentVPSlash vp np = vp ; {- s = {s = vp.s.s ; h = vp.s.h ; p = vp.s.p ; sc = npform2subjcase vp.c2.c} ; - s2 = \\b,p,a => np.s ! NPCase Nom ++ vp.s2 ! b ! p ! a ; + s2 = \\b,p,a => linNP (NPCase Nom) np ++ vp.s2 ! b ! p ! a ; adv = vp.adv ; ext = vp.ext ; vptyp = vp.vptyp ; @@ -95,7 +95,7 @@ concrete ExtraEst of ExtraEstAbs = CatEst ** AdvExistNP adv np = mkClause (\_ -> adv.s) np.a (insertObj - (\\_,b,_ => np.s ! NPCase Nom) (predV (verbOlema ** {sc = NPCase Nom}))) ; + (\\_,b,_ => linNP (NPCase Nom) np) (predV (verbOlema ** {sc = NPCase Nom}))) ; RelExistNP prep rp np = { s = \\t,ant,bo,ag => @@ -105,7 +105,7 @@ concrete ExtraEst of ExtraEstAbs = CatEst ** (\_ -> appCompl True Pos prep (rp2np n rp)) np.a (insertObj - (\\_,b,_ => np.s ! NPCase Nom) + (\\_,b,_ => linNP (NPCase Nom) np) (predV (verbOlema ** {sc = NPCase Nom}))) ; in cl.s ! t ! ant ! bo ! SDecl ; @@ -114,26 +114,26 @@ concrete ExtraEst of ExtraEstAbs = CatEst ** AdvPredNP adv v np = mkClause (\_ -> adv.s) np.a (insertObj - (\\_,b,_ => np.s ! NPCase Nom) (predV v)) ; + (\\_,b,_ => linNP (NPCase Nom) np) (predV v)) ; ICompExistNP adv np = let cl = mkClause (\_ -> adv.s ! np.a) np.a (insertObj - (\\_,b,_ => np.s ! NPCase Nom) (predV (verbOlema ** {sc = NPCase Nom}))) ; + (\\_,b,_ => linNP (NPCase Nom) np) (predV (verbOlema ** {sc = NPCase Nom}))) ; in { s = \\t,a,p => cl.s ! t ! a ! p ! SDecl } ; IAdvPredNP iadv v np = let cl = mkClause (\_ -> iadv.s) np.a (insertObj - (\\_,b,_ => np.s ! v.sc) (predV v)) ; + (\\_,b,_ => linNP v.sc np) (predV v)) ; in { s = \\t,a,p => cl.s ! t ! a ! p ! SDecl } ; -- i_implicPron = mkPronoun [] "minun" "minua" "minuna" "minuun" Sg P1 ; - whatPart_IP = { + whatPart_IP = emptyIP ** { s = table { - NPCase Nom | NPAcc => "mitä" ; + NPCase Nom | NPAcc => "mida" ; c => whatSg_IP.s ! c } ; n = Sg @@ -142,12 +142,11 @@ concrete ExtraEst of ExtraEstAbs = CatEst ** PartCN cn = let acn = DetCN (DetQuant IndefArt NumSg) cn - in { + in acn ** { s = table { NPCase Nom | NPAcc => acn.s ! NPCase ResEst.Part ; c => acn.s ! c } ; - a = acn.a ; isPron = False ; isNeg = False } ; diff --git a/src/estonian/IdiomEst.gf b/src/estonian/IdiomEst.gf index 59c1b9ef..8ae3c7ca 100644 --- a/src/estonian/IdiomEst.gf +++ b/src/estonian/IdiomEst.gf @@ -10,7 +10,7 @@ concrete IdiomEst of Idiom = CatEst ** Pos => NPCase Nom ; -- on olemas lammas Neg => NPCase Part -- ei ole olemas lammast } ; - vp = insertObj (\\_,b,_ => "olemas" ++ np.s ! cas b) (predV olla) + vp = insertObj (\\_,b,_ => "olemas" ++ linNP (cas b) np) (predV olla) in existClause noSubj (agrP3 Sg) vp ; @@ -28,7 +28,7 @@ concrete IdiomEst of Idiom = CatEst ** CleftNP np rs = mkClause (\_ -> "see") (agrP3 Sg) (insertExtrapos (rs.s ! np.a) - (insertObj (\\_,_,_ => np.s ! NPCase Nom) (predV olla))) ; + (insertObj (\\_,_,_ => linNP (NPCase Nom) np) (predV olla))) ; -- This gives the almost forbidden "se on Porissa kun Matti asuu". -- Est: "see on Toris, kus Mati elab" (?) diff --git a/src/estonian/NounEst.gf b/src/estonian/NounEst.gf index f87ae33f..f353b1e6 100644 --- a/src/estonian/NounEst.gf +++ b/src/estonian/NounEst.gf @@ -22,7 +22,7 @@ concrete NounEst of Noun = CatEst ** open ResEst, HjkEst, MorphoEst, Prelude in <_, _, True,_> => ; -- kolmeks kassiks (all other cases) _ => -- kass, kassi, ... (det is not a number) } - in { + in cn ** { s = \\c => let k = ncase c ; in @@ -41,7 +41,7 @@ concrete NounEst of Noun = CatEst ** open ResEst, HjkEst, MorphoEst, Prelude in True => Sg ; _ => det.n } ; - in { + in emptyNP ** { s = \\c => let k = npform2case n c in det.sp ! k ; a = agrP3 (case det.isDef of { @@ -51,37 +51,24 @@ concrete NounEst of Noun = CatEst ** open ResEst, HjkEst, MorphoEst, Prelude in isPron = False } ; - UsePN pn = { + UsePN pn = emptyNP ** { s = \\c => pn.s ! npform2case Sg c ; a = agrP3 Sg ; isPron = False } ; - UsePron p = p ** {isPron = True} ; + UsePron p = p ** {isPron = True ; postmod = []} ; - PredetNP pred np = { + PredetNP pred np = np ** { s = \\c => pred.s ! complNumAgr np.a ! c ++ np.s ! c ; - a = np.a ; - isPron = np.isPron -- kaikki minun - ni } ; PPartNP np v2 = let num : Number = complNumAgr np.a ; part : Str = v2.s ! (PastPart Pass) ; - adj : NForms = hjk_type_IVb_maakas part ; - partGen : Str = adj ! 1 ; - partEss : Str = partGen + "na" - in { - s = \\c => np.s ! c ++ part ; --partEss ; - a = np.a ; - isPron = np.isPron -- minun täällä - ni - } ; + in np ** {postmod = np.postmod ++ part} ; - AdvNP np adv = { - s = \\c => np.s ! c ++ adv.s ; - a = np.a ; - isPron = np.isPron -- minun täällä - ni - } ; + AdvNP np adv = np ** {postmod = np.postmod ++ adv.s} ; DetQuantOrd quant num ord = { s = \\c => quant.s ! num.n ! c ++ num.s ! Sg ! c ++ ord.s ! NCase num.n c ; @@ -120,7 +107,7 @@ concrete NounEst of Noun = CatEst ** open ResEst, HjkEst, MorphoEst, Prelude in isDef = True --- "minun kolme autoani ovat" ; thus "...on" is missing } ; - PossNP cn np = {s = \\nf => np.s ! NPCase Gen ++ cn.s ! nf }; + PossNP cn np = np ** {s = \\nf => linNP (NPCase Gen) np ++ cn.s ! nf} ; NumSg = {s = \\_,_ => [] ; isNum = False ; n = Sg} ; NumPl = {s = \\_,_ => [] ; isNum = False ; n = Pl} ; @@ -167,36 +154,44 @@ concrete NounEst of Noun = CatEst ** open ResEst, HjkEst, MorphoEst, Prelude in let n : Number = Sg ; ncase : Case -> NForm = \c -> NCase n c ; - in { + in cn ** { s = \\c => let k = npform2case n c in cn.s ! ncase k ; a = agrP3 Sg ; isPron = False } ; - UseN n = n ; + UseN n = emptyCN ** { + s = n.s + } ; UseN2 n = n ; - Use2N3 f = f ; + Use2N3 f = f ** { + postmod = [] + } ; Use3N3 f = f ** { c2 = f.c3 ; - isPre = f.isPre2 + isPre = f.isPre2 ; + postmod = [] } ; - ComplN2 f x = { - s = \\nf => preOrPost f.isPre (f.s ! nf) (appCompl True Pos f.c2 x) + ComplN2 f x = let compl : Str = appCompl True Pos f.c2 x in { + s = \\nf => case f.isPre of { + True => f.s ! nf ; -- N2 is pre, so compl goes into postmod + False => compl ++ f.s ! nf -- N2 isn't pre, compl goes in s before the N2 + } ; + postmod = f.postmod ++ if_then_Str f.isPre compl [] } ; - - ComplN3 f x = lin N2 { - s = \\nf => preOrPost f.isPre (f.s ! nf) (appCompl True Pos f.c2 x) ; + -- N2 is subtype of CN, so we can reuse result of ComplN2 as a base for our CN. + -- The decision of noun-complement order is only done once, in ComplN2. + ComplN3 f x = let cn : CN = ComplN2 (Use2N3 f) x in cn ** { c2 = f.c3 ; isPre = f.isPre2 } ; - - AdjCN ap cn = { + AdjCN ap cn = cn ** { s = \\nf => case ap.infl of { Invariable|Participle => ap.s ! True ! NCase Sg Nom ++ cn.s ! nf ; --valmis kassile; väsinud kassile @@ -204,19 +199,20 @@ concrete NounEst of Noun = CatEst ** open ResEst, HjkEst, MorphoEst, Prelude in } } ; - RelCN cn rs = {s = \\nf => cn.s ! nf ++ rs.s ! agrP3 (numN nf)} ; + RelCN cn rs = cn ** { -- exception to postmod rule, because RS depends on Agr + s = \\nf => cn.s ! nf ++ rs.s ! agrP3 (numN nf) + } ; - RelNP np rs = { - s = \\c => np.s ! c ++ "," ++ rs.s ! np.a ; - a = np.a ; + RelNP np rs = np ** { + postmod = np.postmod ++ "," ++ rs.s ! np.a ; isPron = np.isPron ---- correct ? } ; - AdvCN cn ad = {s = \\nf => cn.s ! nf ++ ad.s} ; + AdvCN cn ad = cn ** {postmod = cn.postmod ++ ad.s} ; - SentCN cn sc = {s = \\nf=> cn.s ! nf ++ sc.s} ; + SentCN cn sc = cn ** {postmod = cn.postmod ++ sc.s} ; - ApposCN cn np = {s = \\nf=> cn.s ! nf ++ np.s ! NPCase Nom} ; --- luvun x + ApposCN cn np = cn ** {postmod = cn.postmod ++ linNP (NPCase Nom) np} ; --- luvun x oper numN : NForm -> Number = \nf -> case nf of { diff --git a/src/estonian/ParadigmsEst.gf b/src/estonian/ParadigmsEst.gf index 55f5cc69..45bffe7d 100644 --- a/src/estonian/ParadigmsEst.gf +++ b/src/estonian/ParadigmsEst.gf @@ -574,7 +574,12 @@ oper mkN2 : N -> Prep -> N2 = mmkN2 } ; - mmkN2 : N -> Prep -> N2 = \n,c -> lin N (n ** {c2 = c ; isPre = mkIsPre c}) ; + mmkN2 : N -> Prep -> N2 = \n,c -> lin N2 (n ** { + c2 = c ; + isPre = mkIsPre c ; + postmod = [] + }) ; + mkN3 = \n,c,e -> lin N3 (n ** { c2 = c ; c3 = e ; isPre = mkIsPre c ; -- matka Londonist Pariisi diff --git a/src/estonian/PhraseEst.gf b/src/estonian/PhraseEst.gf index 0557107b..a50c61db 100644 --- a/src/estonian/PhraseEst.gf +++ b/src/estonian/PhraseEst.gf @@ -9,12 +9,12 @@ concrete PhraseEst of Phrase = CatEst ** open ResEst, (P = Prelude) in { UttImpPl pol imp = {s = pol.s ++ imp.s ! pol.p ! Ag Pl P2} ; UttImpPol pol imp = {s = pol.s ++ imp.s ! pol.p ! AgPol} ; - UttIP ip = {s = ip.s ! NPCase Nom} ; + UttIP ip = {s = linIP (NPCase Nom) ip} ; UttIAdv iadv = iadv ; - UttNP np = {s = np.s ! NPCase Nom} ; + UttNP np = {s = linNP (NPCase Nom) np} ; UttVP vp = {s = infVP (NPCase Nom) Pos (agrP3 Sg) vp InfMa} ; UttAdv adv = adv ; - UttCN np = {s = np.s ! NCase Sg Nom} ; + UttCN cn = {s = linCN (NCase Sg Nom) cn} ; UttAP np = {s = np.s ! P.False ! NCase Sg Nom} ; UttCard n = {s = n.s ! Sg ! Nom} ; UttInterj i = i ; @@ -23,6 +23,6 @@ concrete PhraseEst of Phrase = CatEst ** open ResEst, (P = Prelude) in { PConjConj conj = {s = conj.s2} ; NoVoc = {s = []} ; - VocNP np = {s = "," ++ np.s ! NPCase Nom} ; + VocNP np = {s = "," ++ linNP (NPCase Nom) np} ; } diff --git a/src/estonian/QuestionEst.gf b/src/estonian/QuestionEst.gf index 58a69f6b..0df94f21 100644 --- a/src/estonian/QuestionEst.gf +++ b/src/estonian/QuestionEst.gf @@ -40,16 +40,15 @@ concrete QuestionEst of Question = CatEst ** open ResEst, Prelude in { PrepIP p ip = {s = appCompl True Pos p (ip ** {a = agrP3 ip.n ; isPron = False})} ; - AdvIP ip adv = { - s = \\c => ip.s ! c ++ adv.s ; - n = ip.n + AdvIP ip adv = ip ** { + postmod = ip.postmod ++ adv.s ; } ; -- The computation of $ncase$ is a special case of that in $NounEst.DetCN$, -- since we don't have possessive suffixes or definiteness. --- It could still be nice to have a common oper... - IdetCN idet cn = let n = idet.n in { + IdetCN idet cn = let n = idet.n in emptyIP ** { s = \\c => let k : Case = npform2case n c ; @@ -67,7 +66,7 @@ concrete QuestionEst of Question = CatEst ** open ResEst, Prelude in { n = n } ; - IdetIP idet = let n = idet.n in { + IdetIP idet = let n = idet.n in emptyIP ** { s = \\c => let k = npform2case n c ; @@ -97,6 +96,6 @@ concrete QuestionEst of Question = CatEst ** open ResEst, Prelude in { AdvIAdv i a = {s = i.s ++ a.s} ; CompIAdv a = {s = \\_ => a.s} ; - CompIP ip = {s = \\_ => ip.s ! NPCase Nom} ; + CompIP ip = {s = \\_ => linIP (NPCase Nom) ip} ; } diff --git a/src/estonian/RelativeEst.gf b/src/estonian/RelativeEst.gf index 4be5f96a..7cf10c34 100644 --- a/src/estonian/RelativeEst.gf +++ b/src/estonian/RelativeEst.gf @@ -18,8 +18,10 @@ concrete RelativeEst of Relative = CatEst ** open Prelude, ResEst, MorphoEst in RAg a => a } ; cl = mkClause - (subjForm {s = rp.s ! (complNumAgr agr) ; - a = agr ; isPron = False} vp.sc) agr vp + (subjForm + (emptyNP ** {s = rp.s ! complNumAgr agr ; a = agr}) + vp.sc) + agr vp in cl.s ! t ! ant ! b ! SDecl ; c = NPCase Nom @@ -36,7 +38,7 @@ concrete RelativeEst of Relative = CatEst ** open Prelude, ResEst, MorphoEst in } ; FunRP p np rp = { - s = \\n,c => appCompl True Pos p (rp2np n rp) ++ np.s ! c ; --- is c OK? + s = \\n,c => appCompl True Pos p (rp2np n rp) ++ linNP c np ; --- is c OK? a = RAg np.a } ; diff --git a/src/estonian/ResEst.gf b/src/estonian/ResEst.gf index d5e3e1bc..5e7f45c6 100644 --- a/src/estonian/ResEst.gf +++ b/src/estonian/ResEst.gf @@ -57,8 +57,34 @@ resource ResEst = ParamX ** open Prelude in { } ; oper - NP = {s : NPForm => Str ; a : Agr ; isPron : Bool} ; + IPhrase : Type = { + s : NPForm => Str ; -- the noun phrase + premodifiers + postmod : Str ; -- adverb, RS, etc. other postmods + n : Number + } ; + NPhrase : Type = { + s : NPForm => Str ; -- the noun phrase + premodifiers + postmod : Str ; -- adverb, RS, etc. other postmods + a : Agr ; + isPron : Bool + } ; + + emptyNP : NPhrase = { + s = \\_ => [] ; + postmod = [] ; + a = agrP3 Sg ; + isPron = False + } ; + + emptyIP : IPhrase = { + s = \\_ => [] ; + postmod = [] ; + n = Sg ; + } ; + + linNP : NPForm -> NPhrase -> Str = \npf,np -> np.s ! npf ++ np.postmod ; + linIP : NPForm -> IPhrase -> Str = \npf,ip -> ip.s ! npf ++ ip.postmod ; -- --2 Adjectives -- @@ -73,6 +99,8 @@ param oper Adjective : Type = {s : Degree => AForm => Str} ; + APhrase : Type = {s : Bool => NForm => Str ; infl : Infl} ; + --2 Noun phrases -- -- Two forms of *virtual accusative* are needed for nouns in singular, @@ -179,7 +207,9 @@ param Compl : Type = {s : Str ; c : NPFormPlus ; isPre : Bool} ; - appCompl : Bool -> Polarity -> Compl -> NP -> Str = \isFin,b,co,np -> + npfplus2compl : NPFormPlus -> Compl = \npf -> {s = [] ; c = npf ; isPre = False} ; + + appCompl : Bool -> Polarity -> Compl -> NPhrase -> Str = \isFin,b,co,np -> let c = case co.c.npf of { NPAcc => case b of { @@ -196,7 +226,7 @@ param } ; nps = np.s ! c ++ co.c.suf ; -- complement's NPFormPlus may include suffix for the cases based on Gen stem, e.g. comitative "ga" in - preOrPost co.isPre co.s nps ; + preOrPost co.isPre co.s nps ++ np.postmod ; -- Used for passive; c2 of V2/VPSlash becomes sc of VP compl2subjcase : Compl -> NPForm = \compl -> @@ -436,7 +466,7 @@ oper -- This is used for subjects of passives: therefore isFin in False. - subjForm : NP -> NPForm -> Polarity -> Str = \np,sc,b -> + subjForm : NPhrase -> NPForm -> Polarity -> Str = \np,sc,b -> appCompl False b {s = [] ; c = case2npformp sc ; isPre = True} np ; infVP : NPForm -> Polarity -> Agr -> VP -> InfForms -> Str = infVPAnt Simul ; @@ -644,6 +674,15 @@ oper Noun : Type = {s : NForm => Str} ; + CNoun : Type = Noun ** {postmod : Str} ; + + emptyCN : CNoun = { + s = \\nf => [] ; + postmod = [] + } ; + + linCN : NForm -> CNoun -> Str = \nf,cn -> cn.s ! nf ++ cn.postmod ; + -- To form an adjective, it is usually enough to give a noun declension: the -- adverbial form is regular. @@ -666,13 +705,13 @@ oper -- Reflexive pronoun. --- Possessive could be shared with the more general $NounFin.DetCN$. - reflPron : Agr -> NP = \agr -> + reflPron : Agr -> NPhrase = \agr -> let ise = nForms2N (nForms6 "ise" "enda" "ennast" "endasse" "endi" "endid") ; n = case agr of { AgPol => Sg ; Ag n _ => n } ; - in { + in emptyNP ** { s = table { NPAcc => "ennast" ; NPCase c => fixPlNom "endid" ise.s ! NCase n c @@ -747,7 +786,11 @@ oper } ; oper - rp2np : Number -> {s : Number => NPForm => Str ; a : RAgr} -> NP = \n,rp -> { + -- Technically, we could also add a postmod field for RP, + -- because multiple applications of FunRP add multiple complements. + -- But I will only add it if I see a real-world sentence that uses multiple applications of FunRP. + RelPron : Type = {s : Number => NPForm => Str ; a : RAgr} ; + rp2np : Number -> RelPron -> NPhrase = \n,rp -> emptyNP ** { s = rp.s ! n ; a = agrP3 Sg ; -- does not matter (--- at least in Slash) isPron = False -- has no special accusative @@ -755,7 +798,17 @@ oper etta_Conj : Str = "et" ; - heavyDet : PDet -> PDet ** {sp : Case => Str} = \d -> d ** {sp = d.s} ; + Determiner : Type = { + s : Case => Str ; -- minun kolme + sp : Case => Str ; -- se (substantival form) + n : Number ; -- Pl (agreement feature for verb) + isNum : Bool ; -- True (a numeral is present) + isDef : Bool -- True (verb agrees in Pl, Nom is not Part) --I: actually, can we get rid of this? + } ; + + IDeterminer : Type = {s : Case => Str ; n : Number ; isNum : Bool} ; + + heavyDet : PDet -> Determiner = \d -> d ** {sp = d.s} ; PDet : Type = { s : Case => Str ; n : Number ; diff --git a/src/estonian/StructuralEst.gf b/src/estonian/StructuralEst.gf index f74b092b..b5e2857a 100644 --- a/src/estonian/StructuralEst.gf +++ b/src/estonian/StructuralEst.gf @@ -78,10 +78,8 @@ concrete StructuralEst of Structural = CatEst ** quite_Adv = ss "üsna" ; she_Pron = mkPronoun "tema" "tema" "teda" Sg P3 ; so_AdA = ss "nii" ; - somebody_NP = { + somebody_NP = emptyNP ** { s = \\c => jokuPron ! Sg ! npform2case Sg c ; - a = agrP3 Sg ; - isPron = False } ; someSg_Det = heavyDet { s = jokuPron ! Sg ; @@ -92,10 +90,8 @@ concrete StructuralEst of Structural = CatEst ** isNum = False ; isDef = True ; n = Pl } ; - something_NP = { + something_NP = emptyNP ** { s = \\c => mikaInt ! Sg ! npform2case Sg c ; - a = agrP3 Sg ; - isPron = False } ; somewhere_Adv = ss "kuskil" ; that_Quant = heavyQuant { @@ -133,11 +129,11 @@ concrete StructuralEst of Structural = CatEst ** very_AdA = ss "väga" ; want_VV = mkVV (mkV "tahtma") ; we_Pron = mkPronoun "meie" "meie" "meid" Pl P1 ; - whatPl_IP = { + whatPl_IP = emptyIP ** { s = table {NPAcc => "mida" ; c => mikaInt ! Pl ! npform2case Pl c} ; n = Pl } ; - whatSg_IP = { + whatSg_IP = emptyIP ** { s = \\c => mikaInt ! Sg ! npform2case Sg c ; n = Sg } ; @@ -145,11 +141,11 @@ concrete StructuralEst of Structural = CatEst ** when_Subj = ss "kui" ; where_IAdv = ss "kus" ; which_IQuant = { s = mikaInt } ; - whoSg_IP = { + whoSg_IP = emptyIP ** { s = table {NPAcc => "keda" ; c => kukaInt ! Sg ! npform2case Sg c} ; n = Sg } ; - whoPl_IP = { + whoPl_IP = emptyIP ** { s = table {NPAcc => "keda" ; c => kukaInt ! Pl ! npform2case Pl c} ; n = Pl } ; @@ -250,11 +246,10 @@ oper oper - makeNP : N -> MorphoEst.Number -> CatEst.NP ; - makeNP noun num = lin NP { + makeNP : N -> MorphoEst.Number -> NPhrase ; + makeNP noun num = emptyNP ** { s = \\c => noun.s ! NCase num (npform2case num c) ; a = agrP3 num ; - isPron = False ; } ; lin @@ -266,16 +261,14 @@ lin } ; if_then_Conj = {s1 = "kui" ; s2 = "siis" ; n = Sg} ; - nobody_NP = { + nobody_NP = emptyNP ** { s = \\c => "mitte" ++ kukaanPron ! Sg ! npform2case Sg c ; a = agrP3 Sg ; - isPron = False } ; - nothing_NP = { + nothing_NP = emptyNP ** { s = \\c => "mitte" ++ mikaanPron ! Sg ! npform2case Sg c ; a = agrP3 Sg ; - isPron = False } ; at_least_AdN = ss "vähemalt" ; diff --git a/src/estonian/SymbolEst.gf b/src/estonian/SymbolEst.gf index 0d1000a6..df6827d5 100644 --- a/src/estonian/SymbolEst.gf +++ b/src/estonian/SymbolEst.gf @@ -8,20 +8,14 @@ lin FloatPN i = {s = \\c => i.s} ; --- c NumPN i = {s = \\c => i.s!Sg!Nom } ; --- c - CNIntNP cn i = { - s = \\c => cn.s ! NCase Sg (npform2case Sg c) ++ i.s ; - a = agrP3 Sg ; - isPron = False + CNIntNP cn i = let np : NP = NounEst.MassNP cn in np ** { + postmod = np.postmod ++ i.s ; } ; - CNSymbNP det cn xs = let detcn = NounEst.DetCN det cn in { - s = \\c => detcn.s ! c ++ xs.s ; - a = detcn.a ; - isPron = False + CNSymbNP det cn xs = let np : NP = NounEst.DetCN det cn in np ** { + postmod = np.postmod ++ xs.s ; } ; - CNNumNP cn i = { - s = \\c => cn.s ! NCase Sg (npform2case Sg c) ++ i.s ! Sg ! Nom ; - a = agrP3 Sg ; - isPron = False + CNNumNP cn i = let np : NP = NounEst.MassNP cn in np ** { + postmod = np.postmod ++ i.s ! Sg ! Nom ; } ; SymbS sy = sy ; diff --git a/src/estonian/VerbEst.gf b/src/estonian/VerbEst.gf index c07c24b1..2fa22f13 100644 --- a/src/estonian/VerbEst.gf +++ b/src/estonian/VerbEst.gf @@ -87,7 +87,7 @@ concrete VerbEst of Verb = CatEst ** open Prelude, ResEst in { CompAP = compAP ; CompCN = compCN ; - CompNP np = {s = \\_ => np.s ! NPCase Nom} ; + CompNP np = {s = \\_ => linNP (NPCase Nom) np} ; CompAdv a = {s = \\_ => a.s} ; }