diff --git a/src/finnish/CatFin.gf b/src/finnish/CatFin.gf index 131d671e..aaf9bb65 100644 --- a/src/finnish/CatFin.gf +++ b/src/finnish/CatFin.gf @@ -48,7 +48,7 @@ concrete CatFin of Cat = CommonX ** open ResFin, StemFin, Prelude in { -- The $Bool$ tells if a possessive suffix is attached, which affects the case. - CN = {s : NForm => Str ; h : Harmony} ; + CN = {s : NForm => Str ; h : Harmony ; postmod : Number => Str} ; Pron = {s : NPForm => Str ; a : Agr ; hasPoss : Bool ; poss : Str} ; NP = {s : NPForm => Str ; a : Agr ; isPron : Bool ; isNeg : Bool} ; DAP, Det = { @@ -93,7 +93,7 @@ concrete CatFin of Cat = CommonX ** open ResFin, StemFin, Prelude in { A2 = {s : Degree => SAForm => Str ; h : Harmony ; c2 : Compl} ; N = SNoun ; - N2 = SNoun ** {c2 : Compl ; isPre : Bool} ; + N2 = SNoun ** {c2 : Compl ; isPre : Bool ; postmod : Number => Str} ; N3 = SNoun ** {c2,c3 : Compl ; isPre,isPre2 : Bool} ; PN = SPN ; diff --git a/src/finnish/ConjunctionFin.gf b/src/finnish/ConjunctionFin.gf index ceeb441e..f9b7eb1d 100644 --- a/src/finnish/ConjunctionFin.gf +++ b/src/finnish/ConjunctionFin.gf @@ -1,5 +1,5 @@ -concrete ConjunctionFin of Conjunction = - CatFin ** open ResFin, Coordination, Prelude in { +concrete ConjunctionFin of Conjunction = + CatFin ** open ResFin, Coordination, Prelude, (N=NounFin) in { flags optimize=all_subs ; @@ -24,7 +24,7 @@ concrete ConjunctionFin of Conjunction = ConjCN conj ss = let s = (conjunctDistrTable NForm conj ss).s - in {s = s ; h = Back } ; ---- harmony? + in {s = s ; h = Back ; postmod = \\_ => []} ; ---- harmony? -- These fun's are generated from the list cat's. @@ -40,8 +40,15 @@ concrete ConjunctionFin of Conjunction = ConsAP xs x = consrTable2 Bool NForm comma xs x ; BaseRS x y = twoTable Agr x y ** {c = y.c} ; ConsRS xs x = consrTable Agr comma xs x ** {c = xs.c} ; - BaseCN x y = twoTable NForm x y ; - ConsCN xs x = consrTable NForm comma xs x ; + BaseCN x y = twoTable NForm (mergeCN x) (mergeCN y) ; -- put postmod in s field + ConsCN x xs = consrTable NForm comma (mergeCN x) xs; + oper + LinCN : Type = {s : NForm => Str ; h : Harmony ; postmod : Number => Str} ; + -- RS, SC and Adv are in separate fields, to prevent "lasi viiniänsa" for "lasinsa viiniä". + -- But for coordination, we just give up and attach the postmod. + -- Really, if you want to have "lasinsa viiniä ja kuppinsa teetä", just use ConjNP instead. + mergeCN : LinCN -> LinCN = \cn -> cn ** { + s = \\nf => cn.s ! nf ++ cn.postmod ! N.numN nf } ; lincat [S] = {s1,s2 : Str} ; diff --git a/src/finnish/ExtraFin.gf b/src/finnish/ExtraFin.gf index 8f6bbb10..d525bb0f 100644 --- a/src/finnish/ExtraFin.gf +++ b/src/finnish/ExtraFin.gf @@ -20,8 +20,11 @@ concrete ExtraFin of ExtraFinAbs = CatFin ** GenIP ip = {s = \\_,_ => ip.s ! NPCase Gen} ; - GenCN n1 n2 = {s = \\nf => n1.s ! NPCase Gen ++ n2.s ! nf ; - h = n2.h } ; + GenCN n1 n2 = { + s = \\nf => n1.s ! NPCase Gen ++ n2.s ! nf ; + postmod = \\_ => [] ; + h = n2.h + } ; GenRP num cn = { s = \\n,c => let k = npform2case num.n c in relPron ! n ! Gen ++ cn.s ! NCase num.n k ; @@ -287,9 +290,10 @@ concrete ExtraFin of ExtraFinAbs = CatFin ** AdjAsCN ap = { - s = \\nf => ap.s ! True ! (n2nform nf) ; - h = Back ; ---- TODO should be ap.h, which does not exist - } ; + s = \\nf => ap.s ! True ! (n2nform nf) ; + postmod = \\_ => [] ; + h = Back ; ---- TODO should be ap.h, which does not exist + } ; lincat RNP = {s : Agr => NPForm => Str ; isPron : Bool} ; diff --git a/src/finnish/NounFin.gf b/src/finnish/NounFin.gf index 8a6677d8..fa9857fb 100644 --- a/src/finnish/NounFin.gf +++ b/src/finnish/NounFin.gf @@ -29,11 +29,14 @@ concrete NounFin of Noun = CatFin ** open ResFin, MorphoFin, StemFin, Prelude in _ => -- kytkin, kytkimen,... } in { - s = \\c => let - k = ncase c ; - in - det.s1 ! k.p1 ++ cn.s ! k.p2 ++ det.s2 ! cn.h ; - a = agrP3 (case of { + s = \\c => let + k = ncase c ; + in + det.s1 ! k.p1 ++ -- minun + cn.s ! k.p2 ++ -- kytkime + det.s2 ! cn.h ++ -- ni + cn.postmod ! numN k.p2 ; -- jonka/jotka myin + a = agrP3 (case of { => Sg ; -- kolme kytkintä on _ => det.n }) ; @@ -179,49 +182,67 @@ concrete NounFin of Noun = CatFin ** open ResFin, MorphoFin, StemFin, Prelude in ncase : Case -> NForm = \c -> NCase n c ; in { s = \\c => let k = npform2case n c in - cn.s ! ncase k ; + cn.s ! ncase k ++ cn.postmod ! n ; a = agrP3 Sg ; isPron = False ; isNeg = False } ; - UseN n = snoun2nounSep n ; + UseN n = snoun2nounSep n ** { + postmod = \\_ => [] + } ; - UseN2 n = snoun2nounSep n ; + UseN2 n = snoun2nounSep n ** { + postmod = n.postmod + } ; Use2N3 f = { s = f.s ; c2 = f.c2 ; h = f.h ; - isPre = f.isPre + isPre = f.isPre ; + postmod = \\_ => [] ; } ; Use3N3 f = { s = f.s ; c2 = f.c3 ; h = f.h ; - isPre = f.isPre2 + isPre = f.isPre2 ; + postmod = \\_ => [] ; } ; - ---- If a possessive suffix is added here it goes after the complements... - ComplN2 f x = { - s = \\nf => preOrPost f.isPre ((snoun2nounSep f).s ! nf) (appCompl True Pos f.c2 x) ; - h = f.h } ; - ComplN3 f x = { - s = \\nf => preOrPost f.isPre (f.s ! nf) (appCompl True Pos f.c2 x) ; - c2 = f.c3 ; - h = f.h ; - isPre = f.isPre2 + s = \\nf => + case f.isPre of { + True => cn.s ! nf ; + False => compl ++ cn.s ! nf } ; + postmod = \\num => + case f.isPre of { -- If N2 comes from ComplN3, postmod may be filled + True => cn.postmod ! num ++ compl ; + False => cn.postmod ! num } ; + h = f.h } + where { + compl : Str = appCompl True Pos f.c2 x ; + cn : CN = UseN2 f ; } ; - AdjCN ap cn = { + -- reuse the pre/post logic from ComplN2. + -- we just need to make the N3 into the lincat of N2 + ComplN3 f x = ComplN2 (toN2 f) x ** { + c2 = f.c3 ; + isPre = f.isPre2 } + where { + toN2 : N3 -> N2 = \n3 -> lin N2 (n3 ** {postmod = \\_ => []}) + } ; + + AdjCN ap cn = cn ** { s = case ap.hasPrefix of { True => \\nf => ap.p ++ BIND ++ cn.s ! nf ; False => \\nf => ap.s ! True ! (n2nform nf) ++ cn.s ! nf } ; h = cn.h } ; - RelCN cn rs = {s = \\nf => cn.s ! nf ++ BIND ++ "," ++ rs.s ! agrP3 (numN nf) ; - h = cn.h } ; + RelCN cn rs = cn ** { + postmod = \\num => cn.postmod ! num ++ BIND ++ "," ++ rs.s ! agrP3 num ; + } ; RelNP np rs = { s = \\c => np.s ! c ++ BIND ++ "," ++ rs.s ! np.a ; @@ -230,22 +251,26 @@ concrete NounFin of Noun = CatFin ** open ResFin, MorphoFin, StemFin, Prelude in isNeg = np.isNeg } ; - AdvCN cn ad = {s = \\nf => cn.s ! nf ++ ad.s ; - h = cn.h} ; + AdvCN cn ad = cn ** { + postmod = \\num => cn.postmod ! num ++ ad.s ; + } ; - SentCN cn sc = {s = \\nf=> cn.s ! nf ++ sc.s; - h = cn.h } ; + SentCN cn sc = cn **{ + postmod = \\num => cn.postmod ! num ++ sc.s ; + } ; - ApposCN cn np = {s = \\nf=> cn.s ! nf ++ np.s ! NPSep ; - h = cn.h } ; --- luvun x + ApposCN cn np = cn ** { -- luvun x + postmod = \\num => cn.postmod ! num ++ np.s ! NPSep ; + } ; - PossNP cn np = {s = \\nf => np.s ! NPCase Gen ++ cn.s ! nf ; - h = cn.h - } ; + PossNP cn np = cn ** { + s = \\nf => np.s ! NPCase Gen ++ cn.s ! nf ; + h = cn.h + } ; - PartNP cn np = {s = \\nf => cn.s ! nf ++ np.s ! NPCase Part ; - h = cn.h ---- gives "lasin viiniänsa" ; should be "lasinsa viiniä" - } ; + PartNP cn np = cn ** { + postmod = \\num => np.s ! NPCase Part ++ cn.postmod ! num ; + } ; CountNP det np = diff --git a/src/finnish/ParadigmsFin.gf b/src/finnish/ParadigmsFin.gf index 82841f01..c988ae5d 100644 --- a/src/finnish/ParadigmsFin.gf +++ b/src/finnish/ParadigmsFin.gf @@ -631,7 +631,7 @@ mkVS = overload { mkN2 : N -> Prep -> N2 = mmkN2 } ; - mmkN2 : N -> Prep -> N2 = \n,c -> n ** {c2 = c ; isPre = mkIsPre c ; lock_N2 = <>} ; + mmkN2 : N -> Prep -> N2 = \n,c -> n ** {c2 = c ; isPre = mkIsPre c ; lock_N2 = <> ; postmod = \\_ => []} ; mkN3 = \n,c,e -> n ** {c2 = c ; c3 = e ; isPre = mkIsPre c ; -- matka Lontoosta Pariisiin isPre2 = mkIsPre e ; -- Suomen voitto Ruotsista diff --git a/src/finnish/README.md b/src/finnish/README.md index 82493493..e3ac0c1b 100644 --- a/src/finnish/README.md +++ b/src/finnish/README.md @@ -29,7 +29,13 @@ matching, so that the suffixing functions dp and tk are in heavy use. ## Known issues * The object case in passives may come out wrong. -* If a possessive suffix is added for a NP that is built out of N2 or N3, the possessive suffix will go after the complements, and not after the head noun as it's supposed to. +* Adjectives don't have vowel harmony, so `AdjAsCN` has by default back harmony. +* Conjunction of CNs doesn't repeat possessive suffix: you get _minun [[kissa] ja [koira]]ni_ instead of _minun kissani ja koirani_ 'my cat and dog'. + * If you want it repeated correctly, use ConjNP. Out of the box it repeats "minun", so _minun kissani ja minun koirani_ 'my cat and my dog'. + * If you want _kissani ja koirani_, use [ProDropPoss](https://github.com/GrammaticalFramework/gf-rgl/blob/master/src/finnish/ExtraFin.gf#L190-L202) for both cat and dog. + * `ConjNP and_Conj (BaseNP (DetCN (DetQuant (ProDropPoss i_Pron) NumSg) (UseN cat_N)) (DetCN (DetQuant (ProDropPoss i_Pron) NumSg) (UseN dog_N)))` + * If you want _minun kissani ja koirani_, use ProDropPoss for only `UseN dog_N`: + * `ConjNP and_Conj (BaseNP (DetCN (DetQuant (PossPron i_Pron) NumSg) (UseN cat_N)) (DetCN (DetQuant (ProDropPoss i_Pron) NumSg) (UseN dog_N)))` ## Supplementary files