--# -path=.:../abstract:../common:../../prelude --1 Hungarian auxiliary operations. -- This module contains operations that are needed to make the -- resource syntax work. -- Some parameters, such as $Number$, are inherited from $ParamX$. resource ResHun = NounMorphoHun ** open Prelude, Predef in { -------------------------------------------------------------------------------- -- NP -- Noun morphology is in NounMorphoHun oper CNoun : Type = Noun ** { compl : Number => Case => Str ; postmod : Str ; } ; mkCaseNoun : Str -> Number => Case => Str = \s -> \\n,c => caseFromStem (\a,b -> a+b) (mkNoun s) c n ; mkCaseNoun2 : (n,a : Str) -> Number => Case => Str = \no,ac -> \\n,c => caseFromStem (\a,b -> a+b) (regNounNomAcc no ac) c n ; caseFromStem : (Str->Str->Str) -> Noun -> Case -> Number -> Str = \bind,cn,cas,n -> let applyCase' : NumCaseStem -> Str = applyCase bind cas cn in case of { => cn.s ! SgNom ; => bind (cn.s ! SgAccStem) "t" ; => cn.s ! SgSup ; => cn.s ! SgAll ; => cn.s ! PlStem ; -- don't use applyCase', it adds a BIND which breaks everything! => applyCase' SgInsStem ; => bind (bind (cn.s ! PlStem) "k") (endCase cas ! cn.h) ; => applyCase' SgStem ; => applyCase' PlStem } ; caseFromPossStem : CNoun -> Determiner -> Case -> Str = \cn,det,cas -> let st : PossStem = case det.dt of { DetPoss x => x ; _ => Predef.error "caseFromPossStem: Not possessive Det" } ; casetable : Case->HarmForms = case of { -- P3 Sg possessive suffix ends in vowel, others in consonant. => endCasePossVow ; _ => endCase } ; stem : NumCaseStem = case det.n of { Pl => PossdPl ; Sg => case st of { dSg_rP3 _ => PossdSg_PossrP3 ; dSg_rPl1 => PossdSg_PossrPl1 ; dSg_rSg1P2 => PossdSg_PossrSg1P2 } } ; -- possessive suffix e.g. "their cats-3pl" is just k. not uk/ük -- possessive suffix e.g. "her cat-3sg" is ∅, we store suf = case of { => "k" ; => "" ; _ => det.poss ! cn.h } ; in case of { -- Possessor is P3 Sg, possessed is plural, case is Nom: -- just use the stored PossdPl stem, e.g. 'madarai' => cn.s ! PossdPl ; -- Any number of possr or possd, case Nom = empty case ending => glue (cn.s ! stem) suf ; -- Other forms have non-empty poss. suffix and case ending _ => applyCaseSuf suf cas cn stem casetable } ; BaseNP : Type = { agr : Person*Number ; objdef : ObjDef ; empty : Str ; -- standard trick for pro-drop } ; NounPhrase : Type = BaseNP ** { s : Possessor => Case => Str ; postmod : Str ; } ; emptyNP : NounPhrase = { s = \\_,_ => [] ; agr = ; objdef = Indef ; postmod, empty = [] ; } ; indeclNP : Str -> NounPhrase = \s -> emptyNP ** {s = \\p,c => s} ; defNP : Str -> Number -> NounPhrase = \s,n -> emptyNP ** { s = \\c => mkCaseNoun s ! n ; n = n ; objdef = Def ; } ; defNPPrefix : (p,n : Str) -> Number -> NounPhrase = \vala,mi,n -> emptyNP ** { s = \\p,c => vala + mkCaseNoun mi ! n ! c ; n = n ; objdef = Def ; } ; linCN : CNoun -> Str = \cn -> cn.s ! SgNom ++ cn.compl ! Sg ! Nom ++ cn.postmod ; linNP' : Possessor -> Case -> NounPhrase -> Str = \p,c,np -> np.s ! p ! c ++ np.postmod ; linNP : NounPhrase -> Str = linNP' NoPoss Nom ; -------------------------------------------------------------------------------- -- Pronouns Pronoun : Type = BaseNP ** { s : Case => Str ; poss : HarmForms ; -- for PossPron : Pron -> Quant } ; possForms : Person*Number => HarmForms = \\agr => case agr of { => harm1 "m" ; => harm1 "d" ; => harm "a" "e" ; --TODO: wovel cases with "ja"? See verb forms below => harm1 "nk" ; -- u/ü/other vowel in stem => harm "tok" "tök" ; => harm "uk" "ük" } ; pronTable : Person*Number => Pronoun = \\agr => case agr of { => emptyNP ** { s = caseTable "én" "engem" "nekem" "belém" "bennem" "belőlem" -- inner locatives "hozzám" "nálam" "tőlem" -- outer locatives "rám" "rajtam" "rólam" -- outer locatives "értem" -- Causative "velem" -- Instrumental nonExist ; -- Translative agr = agr ; objdef = Def ; poss = possForms ! agr } ; => emptyNP ** { s = caseTable "te" "teged" "neked" "beléd" "benned" "belőled" "hozzád" "nálad" "tőled" "rád" "rajtad" "rólad" "érted" -- Causative "veled" -- Instrumental nonExist ; -- Translative agr = agr ; objdef = Def ; poss = possForms ! agr } ; => emptyNP ** { s = caseTable "ő" "őt" "neki" "belé" "benne" "belőle" "hozzá" "nála" "tőle" "rá" "rajta" "róla" "érte" -- Causative "vele" -- Instrumental nonExist ; -- Translative objdef = Def ; poss = possForms ! agr } ; => emptyNP ** { s = caseTable "mi" "minket" "nekünk" "belénk" "bennünk" "belőlünk" "hozzánk" "nálunk" "tőlünk" "ránk" "rajtunk" "rólunk" "értünk" -- Causative "velünk" -- Instrumental nonExist ; -- Translative agr = agr ; objdef = Def ; poss = possForms ! agr } ; => emptyNP ** { s = caseTable "ti" "titeket" "nektek" "belétek" "bennetek" "belőletek" "hozzátok" "nálatok" "tőletek" "rátok" "rajtatok" "rólatok" "értetek" -- Causative "veletek" -- Instrumental nonExist ; -- Translative agr = agr ; objdef = Def ; poss = possForms ! agr } ; => emptyNP ** { s = caseTable "ők" "őket" "nekik" "beléjük" "bennük" "belőlük" "hozzájuk" "náluk" "tőlük" "rájuk" "rajtuk" "róluk" "értük" -- Causative "velük" -- Instrumental nonExist ; -- Translative agr = agr ; objdef = Def ; poss = possForms ! agr } } ; -------------------------------------------------------------------------------- -- Det, Quant, Card, Ord BaseQuant : Type = { poss : HarmForms ; -- Quants made by PossPron need this, empty for others caseagr : Bool ; -- If it agrees in case: "azoknak a nőknek" vs. "sok nőknek" } ; -- Quant has variable number: -- e.g. this_Quant has both "this" and "these" Quant : Type = BaseQuant ** { s, -- form that comes before noun: "{this} car" sp : Number => Case => Str ; -- independent form, "I like {this}" (DetNP) dt : DetType ; } ; mkQuant : (s,sp : Str) -> Quant = \s,sp -> { s = mkCaseNoun s ; sp = mkCaseNoun sp ; dt = DefDet ; caseagr = True ; poss = harm1 [] ; } ; -- Det is formed in DetQuant : Quant -> Num -> Det -- so it has an inherent number. Determiner : Type = BaseQuant ** { s, sp : Case => Str ; n : Number ; dt : DetType ; } ; mkDet : (s : Str) -> ObjDef -> Number -> Bool -> Determiner = \s,d,n,ca -> { s, sp = mkCaseNoun s ! n ; n = n ; numtype = NoNum ; caseagr = ca ; dt = objdef2dt d ; poss = harm1 [] ; } ; mkDet2 : (n,a : Str) -> ObjDef -> Number -> Bool -> Determiner = \no,ac,d,n,ca -> let reg : Determiner = mkDet no d n ca in reg ** { s,sp = mkCaseNoun2 no ac ! n ; } ; -- No need for number: -- https://en.wikisource.org/wiki/Simplified_Grammar_of_the_Hungarian_Language/Nouns -- "Nouns are used in the singular only, if preceded by a numeral or any other -- word expressing quantity; as két ember, two men; sok fa, many trees." Numeral : Type = { s : Place => Str ; -- Independent or attribute -- TODO add ordinal } ; {- Numeral can become Num via Noun.gf: NumNumeral : Numeral -> Card ; Noun.gf: NumCard : Card -> Num ; -} Num : Type = Numeral ** { n : NumType ; -- Singular, plural or numeral } ; baseNum : Num = { s = \\_ => [] ; n = NoNum Sg ; } ; -------------------------------------------------------------------------------- -- Adpositions -- TODO: personal suffixes, e.g. felettem, általam, not *felett/által én Adposition : Type = { pr : Str ; -- Preposition s : Str ; -- Postposition c : Case ; } ; nomAdp : Str -> Adposition = \s -> postpos Nom s ; caseAdp = overload { caseAdp : Case -> Adposition = \c -> postpos c [] ; caseAdp : Case -> Str -> Adposition = \c,s -> postpos c s ; } ; postpos : Case -> Str -> Adposition = \c,s-> {s=s ; c=c ; pr=[]} ; prepos : Case -> Str -> Adposition = \c,s -> {s=[] ; c=c ; pr=s} ; emptyAdp : Adposition = nomAdp [] ; applyAdp : Adposition -> NounPhrase -> Str = \adp,np -> adp.pr ++ np.s ! NoPoss ! adp.c ++ adp.s ++ np.postmod ; applyCase : (Str->Str->Str) -> Case -> Noun -> NumCaseStem -> Str = \bind,cas,cn,stem -> bind (cn.s ! stem) (endCase cas ! cn.h) ; applyCaseSuf : Str -> Case -> CNoun -> NumCaseStem -> (Case -> HarmForms) -> Str = \suf,cas,cn,stem,casetable -> glue (glue (cn.s ! stem) suf) (casetable cas ! cn.h) ; ------------------ -- Conj Conj : Type = { s1 : Str ; s2 : Str ; n : Number ; } ; mkConj : Str -> Number -> Conj = mkDConj [] ; mkDConj : (s1,s2 : Str) -> Number -> Conj = \s1,s2,num -> { s1 = s1 ; s2 = s2 ; n = num ; } ; -------------------------------------------------------------------------------- -- Adjectives AdjPhrase : Type = { s : Number => Case => Str ; compl : Number => Str -- Discontinuous comparative: Én nagyobb vagyok nálad. -- This depends on Number to allow postmodifier APs. } ; emptyAP : AdjPhrase = { s = \\_,_ => [] ; compl = \\_ => [] ; } ; Adjective : Type = { s : Degree => NumCaseStem => Str ; h : Harm ; } ; Adjective2 : Type = Adjective ** { c2 : Adposition ; isPost : Bool ; -- put adjective past the thing it modifies } ; mkAdj : Str -> Adjective = \sgnom -> mkAdj2 sgnom (regNoun sgnom) ; mkAdj2 : Str -> Noun -> Adjective = \sgnom,adjAsNoun -> adjAsNoun ** { s = \\d => let adj : Noun = case d of { Compar => mkNoun (comparAdj sgnom) ; Superl => mkNoun ("leg" + comparAdj sgnom) ; _ => adjAsNoun } ; in adj.s ; } ; invarAP : Str -> AdjPhrase = \s -> emptyAP ** {s = \\_,_ => s} ; -- https://en.wikisource.org/wiki/Simplified_Grammar_of_the_Hungarian_Language/Adjectives comparAdj : Str -> Str = \stem -> case stem of { -- Final a and e become lengthened at the end of a word, if the comparative suffix -bb is joined to it—e.g., drága, drágább; fekete, feketébb, &c.; ó shortens its sound only in jó; jobb, legjobb. "szép" => "szebb" ; "könnyű" => "könnyebb" ; "ifju" => "ifjabb" ; "hosszú" => "hosszabb" ; "sok" => "több" ; "felső" => "felsőbb" ; "belső" => "belsőbb" ; _ + #v => stem + "bb" ; _ => stem + harm "abb" "ebb" ! getHarm stem } ; pluralAdj : Str -> Str = \stem -> case vowFinal stem of { True => -- https://en.wikisource.org/wiki/Simplified_Grammar_of_the_Hungarian_Language/Adjectives case last stem of { "ü" => "ek" ; "i" => harm "ak" "ek" ! getHarm stem ; _ => "k" } ; False => harm3 "ok" "ek" "ök" ! getHarm stem } ; -------------------------------------------------------------------------------- -- Verbs VerbEndings : Type = Person*Number => HarmForms ; -- TODO: incomplete endingsDef : VerbEndings = table { => harm3 "om" "em" "öm" ; => harm3 "od" "ed" "öd" ; => harm "ja" "i" ; => harm "juk" "jük" ; => harm "játok" "itek" ; => harm "ják" "ik" } ; -- by EG 2009, needs more special cases endingsIndef : VerbEndings = table { => harm3 "ok" "ek" "ök" ; => harm1 "sz" ; => harm1 [] ; => harm "unk" "ünk" ; => harm3 "tok" "tek" "tök" ; -- TODO allomorphs -otok, -etek, -ötök => harm "nak" "nek" -- TODO allomorphs -anak, -enek } ; BaseVerb : Type = { sc : SubjCase ; -- subject case } ; Verb : Type = BaseVerb ** { s : VForm => Str ; } ; Verb2 : Type = BaseVerb ** { s : ObjDef => VForm => Str ; c2 : Case -- object case } ; Verb3 : Type = Verb2 ** { -- c3 : Case -- indirect object case } ; datV2 : Verb -> Verb2 = \v -> { s = \\_ => v.s ; sc = SCDat ; c2 = Nom } ; mkVerb2 : Str -> Verb2 = \sg3 -> vtov2 (mkVerb sg3) ; mkVerb3 : Str -> Verb3 = \sg3 -> v2tov3 (mkVerb2 sg3) ; vtov2 : Verb -> Verb2 = \v -> v ** { s = table { Def => let vDef : Verb = mkVerbReg endingsDef (v.s ! VInf) (v.s ! VPres P3 Sg) in vDef.s ; Indef => v.s } ; c2 = Acc } ; v2tov3 : Verb2 -> Verb3 = \v -> v ** {c3 = Dat} ; mkVerb : (sg3 : Str) -> Verb = mkVerbReg endingsIndef "TODO:infinitive" ; -- TODO mkVerbReg : VerbEndings -> (inf, stem : Str) -> Verb = \hf,inf,stem -> let h : Harm = getHarm stem ; sg1 : Str = stem + hf ! ! h ; sg2 : Str = stem + hf ! ! h ; sg3 : Str = stem + hf ! ! h ; pl1 : Str = stem + hf ! ! h ; pl2 : Str = stem + hf ! ! h ; pl3 : Str = stem + hf ! ! h ; in mkVerbFull sg1 sg2 sg3 pl1 pl2 pl3 inf ; mkVerbFull : (x1,_,_,_,_,_,x7 : Str) -> Verb = \sg1,sg2,sg3,pl1,pl2,pl3,inf -> { s = table { VInf => inf ; VPres P1 Sg => sg1 ; VPres P2 Sg => sg2 ; VPres P3 Sg => sg3 ; VPres P1 Pl => pl1 ; VPres P2 Pl => pl2 ; VPres P3 Pl => pl3 } ; sc = SCNom } ; copula : Verb = mkVerbFull "vagyok" "vagy" "van" "vagyunk" "vagytok" "vannak" "lenni" ; megvan : Verb = copula ** { s = \\vf => "meg" + copula.s ! vf ; } ; ------------------ -- VP VerbPhrase : Type = Verb ** { obj : Str ; -- Person*Number => Str, if we want open word order in have_V2 adv : Str ; c2 : Case ; -- for RelSlash } ; -- TODO more fields VPSlash : Type = Verb2 ** { adv : Str ; } ; useV : Verb -> VerbPhrase = \v -> v ** { obj = [] ; adv = [] ; c2 = Acc ; -- TODO check } ; useVc : Verb2 -> VPSlash = \v2 -> v2 ** { adv = [] ; } ; insertAdv : VerbPhrase -> SS -> VerbPhrase = \vp,adv -> vp ** {adv = adv.s} ; insertAdvSlash : VPSlash -> SS -> VPSlash = \vps,adv -> vps ** {adv = adv.s} ; -------------------------------------------------------------------------------- -- Cl, S Clause : Type = {s : Tense => Anteriority => Polarity => Str} ; {- After PredVP, we might still want to add more adverbs (QuestIAdv), but we're done with verb inflection. -} ClSlash : Type = Clause ** { c2 : Case ; -- For RelSlash } ; QClause : Type = Clause ; Sentence : Type = {s : Str} ; predVP : NounPhrase -> VerbPhrase -> ClSlash = \np,vp -> vp ** { s = \\t,a,p => let subjcase : Case = case vp.sc of { SCNom => Nom ; SCDat => Dat } in linNP' NoPoss subjcase np ++ if_then_Pol p [] "nem" ++ vp.s ! agr2vf np.agr ++ vp.obj -- ! np.agr ++ vp.adv ++ np.empty -- standard trick for prodrop+metavariable problem } ; -- Relative RP : Type = {s : Number => Case => Str} ; RClause : Type = {s : Tense => Anteriority => Polarity => Number => Case => Str} ; relVP : RP -> VerbPhrase -> RClause = \rp -> relVP' (rp ** {agr=}) ; relVP' : RP ** {agr : Person*Number} -> VerbPhrase -> RClause = \rp,vp -> { s = \\t,a,p,n,c => let subjcase : Case = case vp.sc of { SCNom => Nom ; SCDat => Dat } in rp.s ! n ! subjcase ++ if_then_Pol p [] "nem" ++ vp.obj -- ! ++ vp.adv ++ vp.s ! VPres rp.agr.p1 n -- variable by number } ; relSlash : RP -> ClSlash -> RClause = \rp,cls -> { s = \\t,a,p,n,c => let objcase : Case = case cls.c2 of { Acc => c ; _ => cls.c2 } in rp.s ! n ! objcase ++ cls.s ! t ! a ! p } ; -------------------------------------------------------------------------------- -- linrefs }