mirror of
https://github.com/GrammaticalFramework/gf-rgl.git
synced 2026-05-27 08:58:55 -06:00
(Est) Make N2, CN, NP & IP discontinuous
Needed for attaching case suffix in right place
This commit is contained in:
@@ -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 = {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 ;
|
||||
|
||||
|
||||
@@ -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} ;
|
||||
}
|
||||
|
||||
@@ -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} ;
|
||||
|
||||
@@ -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
|
||||
} ;
|
||||
|
||||
|
||||
@@ -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" (?)
|
||||
|
||||
@@ -22,7 +22,7 @@ concrete NounEst of Noun = CatEst ** open ResEst, HjkEst, MorphoEst, Prelude in
|
||||
<_, _, True,_> => <k, NCase Sg k> ; -- kolmeks kassiks (all other cases)
|
||||
_ => <k, NCase n k> -- 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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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} ;
|
||||
|
||||
}
|
||||
|
||||
@@ -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} ;
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
} ;
|
||||
|
||||
|
||||
@@ -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 ;
|
||||
|
||||
@@ -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" ;
|
||||
|
||||
@@ -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 ;
|
||||
|
||||
@@ -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} ;
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user