diff --git a/src/persian/CatPes.gf b/src/persian/CatPes.gf index 3146f3e9..2cc00b12 100644 --- a/src/persian/CatPes.gf +++ b/src/persian/CatPes.gf @@ -12,7 +12,7 @@ concrete CatPes of Cat = CommonX ** open ResPes, Prelude in { ---- Sentence - Cl = ResPes.Clause ; -- TODO: like romance does "no tiene ningún", i.e. negative quant/det/NP forces negation in Cl and S + Cl = ResPes.Clause ; ClSlash = { subj : Str ; vp : ResPes.TAnt => Polarity => Order => Str ; diff --git a/src/persian/ExtendPes.gf b/src/persian/ExtendPes.gf index c5e33350..3d3f22ee 100644 --- a/src/persian/ExtendPes.gf +++ b/src/persian/ExtendPes.gf @@ -10,7 +10,7 @@ concrete ExtendPes of Extend = lin -- NP -> Quant ; -- this man's - GenNP np = makeQuant [] [] ** np ** { + GenNP np = makeQuant [] [] Ezafe False ** np ** { mod = Ezafe ; -- the possessed will get Ezafe s = \\num,cmpd => np2str np -- possesser is unmarked; https://sites.la.utexas.edu/persian_online_resources/language-specific-grammar/ezfe/ } ; diff --git a/src/persian/IdiomPes.gf b/src/persian/IdiomPes.gf index dd363825..07bdb023 100644 --- a/src/persian/IdiomPes.gf +++ b/src/persian/IdiomPes.gf @@ -1,4 +1,4 @@ -concrete IdiomPes of Idiom = CatPes ** open Prelude,ParadigmsPes,ResPes in { +concrete IdiomPes of Idiom = CatPes ** open Prelude,ParadigmsPes,ResPes,(N=NounPes) in { flags optimize=all_subs ; flags coding = utf8; @@ -17,20 +17,14 @@ lin ExistNP np = mkSClause [] (agrP3 (fromAgr np.a).n) - (insertComp (\\_ => np2str np) (predV existVerb)) ; - - ExistNPAdv np adv = - mkSClause [] (agrP3 (fromAgr np.a).n) - (insertComp (\\_ => np2str np ++ adv.s) - (predV existVerb) - ) ; + (complSlash (predVc existVerb) np) ; + ExistNPAdv np adv = ExistNP (N.AdvNP np adv) ; ExistIP ip = let cl = mkSClause ip.s (agrP3 ip.n) (predV beVerb); in {s = \\t,p => cl.s ! t ! p ! ODir}; - ProgrVP vp = predProg vp ; ImpPl1 vp = let a = agrP1 Pl in @@ -39,6 +33,6 @@ lin {s = "بگذارید" ++ np2str np ++ showVPH (VSubj Pos np.a) np.a vp}; oper - existVerb = mkV "وجود" haveVerb ; + existVerb : V2 = mkV2 (mkV "وجود" haveVerb) noPrep ; } diff --git a/src/persian/MorphoPes.gf b/src/persian/MorphoPes.gf index 70e01755..714a825f 100644 --- a/src/persian/MorphoPes.gf +++ b/src/persian/MorphoPes.gf @@ -102,6 +102,16 @@ oper Clitic => mkEnclic str ; Poss => mkPossStem str } ; + -- Can happen that a complement (of N2, or e.g. PossNP) wants one form + -- and determiner wants another form. Heuristic: whichever wants Bare loses. + -- Will have to see if this works 100%, the grammar books I've seen + -- aren't very clear about this, just basing on some data. /IL + replaceBare : Mod -> (Mod=>Str) -> (Mod=>Str) = \m,tbl -> + table { + Bare => tbl ! m ; + mod => tbl ! mod + } ; + Noun = { s : Number => Mod => Str ; animacy : Animacy ; @@ -124,7 +134,9 @@ oper --Determiners -------------------- BaseQuant : Type = { - mod : Mod} ; + mod : Mod ; + isNeg : Bool + } ; Determiner : Type = BaseQuant ** { s : Str ; @@ -137,16 +149,18 @@ oper s : Number => CmpdStatus => Str ; isDef : Bool } ; - makeDet : Str -> Number -> Bool -> Determiner = \str,n,b -> { + makeDet : Str -> Number -> (isNum, isNeg : Bool) -> Determiner = \str,n,isNum,isNeg -> { s,sp = str; - isNum = b; + isNum = isNum; + isNeg = isNeg ; mod = Bare ; n = n }; - makeQuant : Str -> Str -> Quant = \sg,pl -> { + makeQuant : Str -> Str -> Mod -> (isNeg : Bool) -> Quant = \sg,pl,mod,isNeg -> { s = table {Sg => \\_ => sg ; Pl => \\_ => pl} ; - mod = Bare ; + mod = mod ; + isNeg = isNeg ; isDef = True }; --------------------------- @@ -223,7 +237,6 @@ oper vf => (modifyFiniteForms f v).s ! vf } } ; - mkVerb : (inf,pres : Str) -> Verb = \kardan,kon -> { s = table { Inf => kardan ; diff --git a/src/persian/NounPes.gf b/src/persian/NounPes.gf index 18e731e9..195bf69d 100644 --- a/src/persian/NounPes.gf +++ b/src/persian/NounPes.gf @@ -15,9 +15,11 @@ concrete NounPes of Noun = CatPes ** open ResPes, Prelude in { NotCmpd => det.s ; -- possessive suffix IsCmpd => det.sp } ; -- full form in case mod of { - Bare => detStr ++ cn.s ! num ! m ++ cn.compl ! det.n ; -- det doesn't require a special form, keep the Mod=>Str table - x => cn.s ! num ! x ++ detStr ++ cn.compl ! det.n } ; -- det requires a special form - a = agrP3 det.n + Bare => detStr ++ cn.s ! num ! m ++ cn.compl ! det.n ; -- det doesn't require a special form, keep the Mod=>Str table + Clitic => detStr ++ cn.s ! num ! Clitic ++ cn.compl ! det.n ; -- In RGL this is only for no_Quant. If other determiners with different word order take Clitic, will change. /IL + x => cn.s ! num ! x ++ detStr ++ cn.compl ! det.n } ; -- Ezafe or Poss: comes after noun, Mod table is overwritten to the given form + a = agrP3 det.n ; + isNeg = det.isNeg ; -- affects polarity in Cl: "*nothing is real" -> "nothing isn't real" } ; UsePN pn = emptyNP ** pn ** {s = \\_ => pn.s} ; @@ -49,28 +51,27 @@ concrete NounPes of Noun = CatPes ** open ResPes, Prelude in { DetQuantOrd quant num ord = let cs : CmpdStatus => Str = case of { - => \\_ => num.s ++ ord.s ; + => \\_ => num.s ++ ord.s ; -- to prevent "a 1" _ => \\c => quant.s ! num.n ! c ++ num.s ++ ord.s} ; - in { + in quant ** { s = cs ! NotCmpd ; sp = cs ! IsCmpd ; -- only matters for PossPron isNum = orB num.isNum ord.isNum ; mod = quant.mod ; - n = num.n + n = case quant.isNeg of {True => Sg ; _ => num.n} ; } ; DetQuant quant num = let cs : CmpdStatus => Str = case of { - => \\_ => num.s ; + => \\_ => num.s ; -- to prevent "a 1" _ => \\c => quant.s ! num.n ! c ++ num.s } ; - - in { + in quant ** { s = cs ! NotCmpd ; sp = cs ! IsCmpd ; -- only matters for PossPron isNum = num.isNum; mod = quant.mod ; - n = num.n + n = case quant.isNeg of {True => Sg ; _ => num.n} ; } ; DetNP det = emptyNP ** { @@ -104,8 +105,8 @@ concrete NounPes of Noun = CatPes ** open ResPes, Prelude in { OrdSuperl a = {s = a.s ! Comparative ! Bare ++ BIND ++ "ین" ; n = Sg ; isNum=False ; isPre = True} ; - DefArt = makeQuant [] [] ; - IndefArt = makeQuant IndefArticle [] ** {isDef = False} ; + DefArt = makeQuant [] [] Bare False ; + IndefArt = makeQuant IndefArticle [] Bare False ** {isDef = False} ; MassNP cn = emptyNP ** cn ** { s = \\m => cn.s ! Sg ! m ++ cn.compl ! Sg ; @@ -126,13 +127,13 @@ concrete NounPes of Noun = CatPes ** open ResPes, Prelude in { } ; ComplN2 n2 np = n2 ** { - s = \\n,m => n2.s ! n ! n2.c2.mod ; + s = \\n => replaceBare n2.c2.mod (n2.s ! n) ; compl = \\_ => n2.compl ++ n2.c2.s ++ np2str np ; hasAdj = False }; ComplN3 n3 np = n3 ** { - s = \\n,m => n3.s ! n ! n3.c2.mod ; + s = \\n => replaceBare n3.c2.mod (n3.s ! n) ; compl = n3.c2.s ++ np2str np ; c = n3.c3; } ; @@ -161,6 +162,6 @@ concrete NounPes of Noun = CatPes ** open ResPes, Prelude in { -- : CN -> NP -> CN ; -- house of Paris, house of mine PossNP cn np = cn ** { - s = \\n,m => cn.s ! n ! Ezafe ; -- TODO or here for " " + s = \\n => replaceBare Ezafe (cn.s ! n) ; -- alternative: place np2str np here for " " compl = \\n => cn.compl ! n ++ np2str np } ; -- " " } diff --git a/src/persian/ParadigmsPes.gf b/src/persian/ParadigmsPes.gf index c5e33b59..d93937fd 100644 --- a/src/persian/ParadigmsPes.gf +++ b/src/persian/ParadigmsPes.gf @@ -72,11 +72,13 @@ oper mkDet = overload { mkDet : Str -> Number -> Det -- Takes a string, number (sg/pl) and returns a det which is not a numeral - = \s,n -> lin Det (makeDet s n False); - mkDet : Str -> Number -> Bool -> Det -- As above + a Boolean for whether the det is a numeral - = \s,n,b -> lin Det (makeDet s n b) ; - mkDet : Str -> Number -> Bool -> Mod -> Det -- As above + Mod for which form the determiner expects its argument to be (default bare) - = \s,n,b,m -> lin Det (makeDet s n b ** {mod=m}) + = \s,n -> lin Det (makeDet s n False False); + mkDet : Str -> Number -> (isNum : Bool) -> Det -- As above + a Boolean for whether the det is a numeral + = \s,n,b -> lin Det (makeDet s n b False) ; + mkDet : Str -> Number -> (isNum, isNeg : Bool) -> Det -- As above + a Boolean for whether the det is negative + = \s,n,nu,ne -> lin Det (makeDet s n nu ne) ; + mkDet : Str -> Number -> (isNum, isNeg : Bool) -> Mod -> Det -- As above + Mod for which form the determiner expects its argument to be (default bare) + = \s,n,nu,ne,m -> lin Det (makeDet s n nu ne ** {mod=m}) }; {- @@ -423,7 +425,11 @@ oper mkQuant = overload { -- mkQuant : Pron -> Quant = \p -> {s = \\_,_,c => p.s!c ;a = p.a ; lock_Quant = <>}; mkQuant : Str -> Str -> Quant -- hidden from public API - = \sg,pl -> makeQuant sg pl; + = \sg,pl -> makeQuant sg pl Bare False; + mkQuant : Str -> Str -> (isNeg : Bool) -> Quant -- hidden from public API + = \sg,pl,isneg -> makeQuant sg pl Bare isneg; + mkQuant : Str -> Str -> Mod -> (isNeg : Bool) -> Quant -- hidden from public API + = \sg,pl,mod,isneg -> makeQuant sg pl mod isneg; } ; } diff --git a/src/persian/ResPes.gf b/src/persian/ResPes.gf index 40186e41..e0453bdd 100644 --- a/src/persian/ResPes.gf +++ b/src/persian/ResPes.gf @@ -30,6 +30,7 @@ resource ResPes = MorphoPes ** open Prelude,Predef in { BaseNP : Type = { a : Agr ; + isNeg : Bool ; -- negative determiner forces negation in Cl and S hasAdj : Bool ; -- to get the right form when NP is a predicate animacy : Animacy ; -- to get the right pronoun in FunRP isClitic : Bool ; -- if isPron, becomes clitic as a direct object @@ -42,6 +43,7 @@ resource ResPes = MorphoPes ** open Prelude,Predef in { emptyNP : NP = { s = \\_ => [] ; a = defaultAgr ; + isNeg = False ; hasAdj = False ; animacy = Inanimate ; isClitic = False ; @@ -102,6 +104,7 @@ oper vComp : Agr => VVTense => Str; -- when a verb is used as a complement of an auxiliary verb. Unlike ‘comp’ or ‘obj’, this type of complement follows the auxiliary verb. obj : Str ; -- object of a verb; so far only used for A ("paint it black") ad : Str ; + isNeg : Bool ; -- whether the object is a negative NP: "*there is nothing" -> "there isn't nothing" embComp : Str ; -- when a declarative or interrogative sentence is used as a complement of a verb. vvtype : VVType ; -- no VV, fully inflecting VV or defective VV } ; @@ -145,6 +148,7 @@ oper obj, embComp = []; vvtype = NoVV ; + isNeg = False ; comp = \\_,_ => [] ; vComp = \\_,_ => [] } ; @@ -202,7 +206,7 @@ oper comp = \\a,wo => case of { => [] ; -- clitic is attached to the verb or prefix - => appCompVP vp.c2 (\\_ => (BIND ++ np.clitic)) ! wo ++ vp.comp ! a ! wo ; + => appCompVP vp.c2 (\\_ => BIND ++ np.clitic) ! wo ++ vp.comp ! a ! wo ; _ => appCompVP vp.c2 np.s ! wo ++ vp.comp ! a ! wo } ; @@ -211,7 +215,8 @@ oper => (addClitic vp.lightverb np.clitic vp).s ; _ => vp.s } ; - obj = vp.obj ++ vp.agrObj ! np.a -- "beg her to buy", buy agrees with her + obj = vp.obj ++ vp.agrObj ! np.a ; -- "beg her to buy", buy agrees with her + isNeg = np.isNeg } ; ---- AR 14/9/2017 trying to fix isAux = True case by inserting conjThat @@ -279,7 +284,8 @@ oper OQuest => "آیا" } ; subj = np2str np ; vp = \\ta,p,ord => - let vps = clTable vp ! np.a ! ta ! p ; + let pol = case orB np.isNeg vp.isNeg of {True => Neg ; _ => p} ; + vps = clTable vp ! np.a ! ta ! pol ; vvt = ta2vvt ta vp.vvtype ; in case vp.vvtype of { DefVV @@ -292,7 +298,8 @@ oper --Clause : Type = {s : TAnt => Polarity => Order => Str} ; mkSClause : Str -> Agr -> VPH -> Clause = \subj,agr,vp -> { s = \\ta,p,ord => - let vps = clTable vp ! agr ! ta ! p ; + let pol = case vp.isNeg of {True => Neg ; _ => p} ; + vps = clTable vp ! agr ! ta ! pol ; quest = case ord of { ODir => [] ; OQuest => "آیا" } ; vvt = ta2vvt ta vp.vvtype ; in quest ++ subj ++ vp.ad ++ vp.comp ! agr ! OV ++ vp.obj diff --git a/src/persian/StructuralPes.gf b/src/persian/StructuralPes.gf index dff9008d..922015a2 100644 --- a/src/persian/StructuralPes.gf +++ b/src/persian/StructuralPes.gf @@ -44,7 +44,7 @@ concrete StructuralPes of Structural = CatPes ** in_Prep = mkPrep "در" ; it_Pron = R.agr2pron ! Ag Sg P3; less_CAdv = {s = "کمتر" ; p = ""} ; - many_Det = mkDet "بسیار" Pl False Ezafe ; + many_Det = let isNum, isNeg = False in mkDet "بسیار" Pl isNum isNeg Ezafe ; more_CAdv = {s = "بیشتر" ; p = "" } ; most_Predet = ss "اکثر"; much_Det = mkDet ["مقدار زیادی"] Pl ; @@ -101,12 +101,12 @@ concrete StructuralPes of Structural = CatPes ** youSg_Pron = R.agr2pron ! Ag Sg P2 ; youPl_Pron = R.agr2pron ! Ag Pl P2 ; youPol_Pron = R.agr2pron ! Ag Pl P2 ; - no_Quant = mkQuant "هیچ" "هیچ" ; -- TODO: takes object in clitic form + is always singular + VP is negated + no_Quant = mkQuant "هیچ" "هیچ" Clitic True ; not_Predet = {s="نه"} ; if_then_Conj = sd2 "اگر" "آنگاه" ** {n = Sg} ; at_least_AdN = ss "حداقل" ; at_most_AdN = ss "حداکثر"; - nothing_NP = R.indeclNP "هیچ چیز" ; + nothing_NP = R.indeclNP "هیچ چیز" ** {isNeg = True} ; except_Prep = mkPrep ["به جز"] ; nobody_NP = R.indeclNP "هیچ کس";