summaryrefslogtreecommitdiff
path: root/next-lib/src/bulgarian/ResBul.gf
diff options
context:
space:
mode:
Diffstat (limited to 'next-lib/src/bulgarian/ResBul.gf')
-rw-r--r--next-lib/src/bulgarian/ResBul.gf626
1 files changed, 626 insertions, 0 deletions
diff --git a/next-lib/src/bulgarian/ResBul.gf b/next-lib/src/bulgarian/ResBul.gf
new file mode 100644
index 000000000..795b9a746
--- /dev/null
+++ b/next-lib/src/bulgarian/ResBul.gf
@@ -0,0 +1,626 @@
+--# -path=.:../abstract:../common:../../prelude
+
+--1 Bulgarian auxiliary operations.
+
+-- This module contains operations that are needed to make the
+-- resource syntax work. To define everything that is needed to
+-- implement $Test$, it moreover contains regular lexical
+-- patterns needed for $Lex$.
+
+resource ResBul = ParamX ** open Prelude in {
+ flags coding=cp1251 ;
+
+
+ flags optimize=all ;
+
+-- Some parameters, such as $Number$, are inherited from $ParamX$.
+
+--2 For $Noun$
+
+-- This is the worst-case $Case$ needed for pronouns.
+
+ param
+ Role = RSubj | RObj Case | RVoc ;
+ Case = Acc | Dat;
+
+ NForm =
+ NF Number Species
+ | NFSgDefNom
+ | NFPlCount
+ | NFVocative
+ ;
+
+ GenNum = GSg Gender | GPl ;
+
+-- Agreement of $NP$ is a record. We'll add $Gender$ later.
+
+ oper
+ Agr = {gn : GenNum ; p : Person} ;
+
+ param
+ Gender = Masc | Fem | Neut ;
+
+ Species = Indef | Def ;
+
+-- The plural never makes a gender distinction.
+
+--2 For $Verb$
+
+ Aspect = Imperf | Perf ;
+
+ VForm =
+ VPres Number Person
+ | VAorist Number Person
+ | VImperfect Number Person
+ | VPerfect AForm
+ | VPluPerfect AForm
+ | VPassive AForm
+ | VPresPart AForm
+ | VImperative Number
+ | VGerund
+ ;
+
+ VType =
+ VNormal
+ | VMedial Case
+ | VPhrasal Case
+ ;
+
+-- The order of sentence is needed already in $VP$.
+
+ Order = Main | Inv | Quest ;
+
+--2 For $Adjective$
+
+ AForm =
+ ASg Gender Species
+ | ASgMascDefNom
+ | APl Species
+ ;
+
+--2 For $Numeral$
+
+ DGender =
+ DMasc
+ | DMascPersonal
+ | DFem
+ | DNeut
+ ;
+
+ DGenderSpecies =
+ DMascIndef
+ | DMascDef
+ | DMascDefNom
+ | DMascPersonalIndef
+ | DMascPersonalDef
+ | DMascPersonalDefNom
+ | DFemIndef
+ | DFemDef
+ | DNeutIndef
+ | DNeutDef
+ ;
+
+ CardOrd = NCard DGenderSpecies | NOrd AForm ;
+ DForm = unit | teen | ten | hundred ;
+
+--2 Transformations between parameter types
+
+ oper
+ agrP3 : GenNum -> Agr = \gn ->
+ {gn = gn; p = P3} ;
+
+ conjGenNum : GenNum -> GenNum -> GenNum = \a,b ->
+ case <a,b> of {
+ <GSg _,GSg g> => GSg g ;
+ _ => GPl
+ } ;
+
+ conjAgr : Agr -> Agr -> Agr = \a,b -> {
+ gn = conjGenNum a.gn b.gn ;
+ p = conjPerson a.p b.p
+ } ;
+
+ gennum : DGender -> Number -> GenNum = \g,n ->
+ case n of {
+ Sg => GSg (case g of {
+ DMasc => Masc ;
+ DMascPersonal => Masc ;
+ DFem => Fem ;
+ DNeut => Neut
+ }) ;
+ Pl => GPl
+ } ;
+
+ numGenNum : GenNum -> Number = \gn ->
+ case gn of {
+ GSg _ => Sg ;
+ GPl => Pl
+ } ;
+
+ aform : GenNum -> Species -> Role -> AForm = \gn,spec,role ->
+ case gn of {
+ GSg g => case <g,spec,role> of {
+ <Masc,Def,RSubj> => ASgMascDefNom ;
+ _ => ASg g spec
+ } ;
+ GPl => APl spec
+ } ;
+
+ dgenderSpecies : DGender -> Species -> Role -> DGenderSpecies =
+ \g,spec,role -> case <g,spec> of {
+ <DMasc,Indef> => DMascIndef ;
+ <DMasc,Def> => case role of {
+ RSubj => DMascDefNom ;
+ _ => DMascDef
+ } ;
+ <DMascPersonal,Indef> => DMascPersonalIndef ;
+ <DMascPersonal,Def> => case role of {
+ RSubj => DMascPersonalDefNom ;
+ _ => DMascPersonalDef
+ } ;
+ <DFem ,Indef> => DFemIndef ;
+ <DFem ,Def> => DFemDef ;
+ <DNeut,Indef> => DNeutIndef ;
+ <DNeut,Def> => DNeutDef
+ } ;
+
+ nform2aform : NForm -> DGender -> AForm
+ = \nf,g -> case nf of {
+ NF n spec => aform (gennum g n) spec (RObj Acc) ;
+ NFSgDefNom => aform (gennum g Sg) Def RSubj ;
+ NFPlCount => APl Indef ;
+ NFVocative => aform (gennum g Sg) Indef (RObj Acc)
+ } ;
+
+ indefNForm : NForm -> NForm
+ = \nf -> case nf of {
+ NF n spec => NF n Indef ;
+ NFSgDefNom => NF Sg Indef ;
+ NFPlCount => NFPlCount ;
+ NFVocative => NFVocative
+ } ;
+
+ numNForm : NForm -> Number
+ = \nf -> case nf of {
+ NF n spec => n ;
+ NFSgDefNom => Sg ;
+ NFPlCount => Pl ;
+ NFVocative => Sg
+ } ;
+
+ oper
+-- For $Verb$.
+ VTable = VForm => Str ;
+
+ Verb : Type = {
+ s : Aspect => VTable ;
+ vtype : VType
+ } ;
+
+ VP : Type = {
+ s : Aspect => VTable ;
+ ad : {isEmpty : Bool; s : Str} ; -- sentential adverb
+ compl : Agr => Str ;
+ vtype : VType
+ } ;
+
+ VPSlash = {
+ s : Aspect => VTable ;
+ ad : {isEmpty : Bool; s : Str} ; -- sentential adverb
+ compl1 : Agr => Str ;
+ compl2 : Agr => Str ;
+ vtype : VType ;
+ c2 : Preposition
+ } ;
+
+ predV : Verb -> VP = \verb -> {
+ s = verb.s ;
+ ad = {isEmpty=True; s=[]} ;
+ compl = \\_ => [] ;
+ vtype = verb.vtype ;
+ } ;
+
+ slashV : Verb -> Preposition -> VPSlash = \verb,prep -> {
+ s = verb.s ;
+ ad = {isEmpty=True; s=[]} ;
+ compl1 = \\_ => [] ;
+ compl2 = \\_ => [] ;
+ vtype = verb.vtype ;
+ c2 = prep ;
+ } ;
+
+ insertObj : (Agr => Str) -> VP -> VP = \obj,vp -> {
+ s = vp.s ;
+ ad = vp.ad ;
+ compl = \\a => vp.compl ! a ++ obj ! a ;
+ vtype = vp.vtype
+ } ;
+
+ insertSlashObj1 : (Agr => Str) -> VPSlash -> VPSlash = \obj,slash -> {
+ s = slash.s ;
+ ad = slash.ad ;
+ compl1 = \\a => slash.compl1 ! a ++ obj ! a ;
+ compl2 = slash.compl2 ;
+ vtype = slash.vtype ;
+ c2 = slash.c2
+ } ;
+
+ insertSlashObj2 : (Agr => Str) -> VPSlash -> VPSlash = \obj,slash -> {
+ s = slash.s ;
+ ad = slash.ad ;
+ compl1 = slash.compl1 ;
+ compl2 = \\a => slash.compl2 ! a ++ obj ! a ;
+ vtype = slash.vtype ;
+ c2 = slash.c2
+ } ;
+
+ auxBe : VTable =
+ table {
+ VPres Sg P1 => "съм" ;
+ VPres Sg P2 => "си" ;
+ VPres Sg P3 => "е" ;
+ VPres Pl P1 => "сме" ;
+ VPres Pl P2 => "сте" ;
+ VPres Pl P3 => "са" ;
+ VAorist Sg P1 => "бях" ;
+ VAorist Sg _ => "беше" ;
+ VAorist Pl P1 => "бяхме" ;
+ VAorist Pl P2 => "бяхте" ;
+ VAorist Pl P3 => "бяха" ;
+ VImperfect Sg P1 => "бях" ;
+ VImperfect Sg _ => "беше" ;
+ VImperfect Pl P1 => "бяхме" ;
+ VImperfect Pl P2 => "бяхте" ;
+ VImperfect Pl P3 => "бяха" ;
+ VPerfect aform => regAdjective "бил" ! aform ;
+ VPluPerfect aform => regAdjective "бил" ! aform ;
+ VPassive aform => regAdjective "бъден" ! aform ;
+ VPresPart aform => regAdjective "бъдещ" ! aform ;
+ VImperative Sg => "бъди" ;
+ VImperative Pl => "бъдете" ;
+ VGerund => "бидейки"
+ } ;
+
+ auxWould : VTable =
+ table {
+ VPres Sg P1 => "бъда" ;
+ VPres Sg P2 => "бъдеш" ;
+ VPres Sg P3 => "бъде" ;
+ VPres Pl P1 => "бъдем" ;
+ VPres Pl P2 => "бъдете" ;
+ VPres Pl P3 => "бъдат" ;
+ VAorist Sg P1 => "бих" ;
+ VAorist Sg _ => "би" ;
+ VAorist Pl P1 => "бихме" ;
+ VAorist Pl P2 => "бихте" ;
+ VAorist Pl P3 => "биха" ;
+ VImperfect Sg P1 => "бъдех" ;
+ VImperfect Sg _ => "бъдеше" ;
+ VImperfect Pl P1 => "бъдехме" ;
+ VImperfect Pl P2 => "бъдехте" ;
+ VImperfect Pl P3 => "бъдеха" ;
+ VPerfect aform => regAdjective "бил" ! aform ;
+ VPluPerfect aform => regAdjective "бъдел" ! aform ;
+ VPassive aform => regAdjective "бъден" ! aform ;
+ VPresPart aform => regAdjective "бъдещ" ! aform ;
+ VImperative Sg => "бъди" ;
+ VImperative Pl => "бъдете" ;
+ VGerund => "бъдейки"
+ } ;
+
+ verbBe : Verb = {s=\\_=>auxBe ; vtype=VNormal} ;
+ verbWould : Verb = {s=\\_=>auxWould ; vtype=VNormal} ;
+
+ reflClitics : Case => Str = table {Acc => "се"; Dat => "си"} ;
+
+ personalClitics : Case => GenNum => Person => Str =
+ table {
+ Acc => table {
+ GSg g => table {
+ P1 => "ме" ;
+ P2 => "те" ;
+ P3 => case g of {
+ Masc => "го" ;
+ Fem => "я" ;
+ Neut => "го"
+ }
+ } ;
+ GPl => table {
+ P1 => "ни" ;
+ P2 => "ви" ;
+ P3 => "ги"
+ }
+ } ;
+ Dat => table {
+ GSg g => table {
+ P1 => "ми" ;
+ P2 => "ти" ;
+ P3 => case g of {
+ Masc => "му" ;
+ Fem => "й" ;
+ Neut => "му"
+ }
+ } ;
+ GPl => table {
+ P1 => "ни" ;
+ P2 => "ви" ;
+ P3 => "им"
+ }
+ }
+ } ;
+
+ ia2e : Str -> Str = -- to be used when the next syllable has vowel different from "а","ъ","о" or "у"
+ \s -> case s of {
+ x@(_*+_) + "я" + y@(("б"|"в"|"г"|"д"|"ж"|"з"|"к"|"л"|"м"|"н"|"п"|"р"|"с"|"т"|"ф"|"х"|"ц"|"ч"|"ш"|"щ")*)
+ => x+"e"+y;
+ _ => s
+ };
+
+ regAdjective : Str -> AForm => Str =
+ \base ->
+ let base0 : Str
+ = case base of {
+ x+"и" => x;
+ x => x
+ }
+ in table {
+ ASg Masc Indef => base ;
+ ASg Masc Def => (base0+"ия") ;
+ ASgMascDefNom => (base0+"ият") ;
+ ASg Fem Indef => (base0+"a") ;
+ ASg Fem Def => (base0+"ата") ;
+ ASg Neut Indef => (base0+"о") ;
+ ASg Neut Def => (base0+"ото") ;
+ APl Indef => (ia2e base0+"и") ;
+ APl Def => (ia2e base0+"ите")
+ };
+
+-- For $Sentence$.
+
+ Clause : Type = {
+ s : Tense => Anteriority => Polarity => Order => Str
+ } ;
+
+ mkClause : Str -> Agr -> VP -> Clause =
+ \subj,agr,vp -> {
+ s = \\t,a,p,o =>
+ let
+ verb : Bool => Str
+ = \\q => vpTenses vp ! t ! a ! p ! agr ! q ! Perf ;
+ compl = vp.compl ! agr
+ in case o of {
+ Main => subj ++ verb ! False ++ compl ;
+ Inv => verb ! False ++ compl ++ subj ;
+ Quest => subj ++ verb ! True ++ compl
+ }
+ } ;
+
+ vpTenses : VP -> Tense => Anteriority => Polarity => Agr => Bool => Aspect => Str =
+ \verb -> \\t,a,p,agr,q0,asp =>
+ let clitic = case verb.vtype of {
+ VNormal => {s=[]; agr=agr} ;
+ VMedial c => {s=reflClitics ! c; agr=agr} ;
+ VPhrasal c => {s=personalClitics ! c ! agr.gn ! agr.p; agr={gn=GSg Neut; p=P3}}
+ } ;
+
+ present = verb.s ! asp ! (VPres (numGenNum clitic.agr.gn) clitic.agr.p) ;
+ presentImperf = verb.s ! Imperf ! (VPres (numGenNum clitic.agr.gn) clitic.agr.p) ;
+ aorist = verb.s ! asp ! (VAorist (numGenNum clitic.agr.gn) clitic.agr.p) ;
+ perfect = verb.s ! asp ! (VPerfect (aform clitic.agr.gn Indef (RObj Acc))) ;
+
+ auxPres = auxBe ! VPres (numGenNum clitic.agr.gn) clitic.agr.p ;
+ auxAorist = auxBe ! VAorist (numGenNum clitic.agr.gn) clitic.agr.p ;
+ auxCond = auxWould ! VAorist (numGenNum clitic.agr.gn) clitic.agr.p ;
+
+ apc : Str -> Str = \s ->
+ case <numGenNum clitic.agr.gn, clitic.agr.p> of {
+ <Sg, P3> => clitic.s++auxPres++s ;
+ _ => auxPres++s++clitic.s
+ } ;
+
+ li0 = case <verb.ad.isEmpty,q0> of {<False,True> => "ли"; _ => []} ;
+
+ q = case verb.ad.isEmpty of {True => q0; False => False} ;
+ li = case q of {True => "ли"; _ => []} ;
+
+ vf1 : Str -> {s1 : Str; s2 : Str} = \s ->
+ case p of {
+ Pos => case q of {True => {s1=[]; s2="ли"++apc []};
+ False => {s1=apc []; s2=[]}} ;
+ Neg => {s1="не"++apc li; s2=[]}
+ } ;
+
+ vf2 : Str -> {s1 : Str; s2 : Str} = \s ->
+ case p of {
+ Pos => case q of {True => {s1=[]; s2="ли"++s};
+ False => {s1=s; s2=[]}} ;
+ Neg => case verb.vtype of
+ {VNormal => {s1="не"; s2=li} ;
+ _ => {s1="не"++s++li; s2=[]}}
+ } ;
+
+ vf3 : Str -> {s1 : Str; s2 : Str} = \s ->
+ case p of {
+ Pos => {s1="ще"++s; s2=li} ;
+ Neg => {s1="няма"++li++"да"++s; s2=[]}
+ } ;
+
+ vf4 : Str -> {s1 : Str; s2 : Str} = \s ->
+ case p of {
+ Pos => {s1= s++li++clitic.s; s2=[]} ;
+ Neg => {s1="не"++s++li++clitic.s; s2=[]}
+ } ;
+
+ verbs : {aux:{s1:Str; s2:Str}; main:Str} =
+ case <t,a> of {
+ <Pres,Simul> => {aux=vf2 clitic.s; main=presentImperf} ;
+ <Pres,Anter> => {aux=vf1 clitic.s; main=perfect} ;
+ <Past,Simul> => {aux=vf2 clitic.s; main=aorist} ;
+ <Past,Anter> => {aux=vf4 auxAorist; main=perfect} ;
+ <Fut, Simul> => {aux=vf3 clitic.s; main=present} ;
+ <Fut, Anter> => {aux=vf3 (apc []); main=perfect} ;
+ <Cond,_ > => {aux=vf4 auxCond ; main=perfect}
+ }
+
+ in verb.ad.s ++ li0 ++ verbs.aux.s1 ++ verbs.main ++ verbs.aux.s2 ;
+
+ daComplex : VP -> Aspect => Agr => Str =
+ \vp -> \\asp,agr =>
+ let clitic = case vp.vtype of {
+ VNormal => {s=[]; agr=agr} ;
+ VMedial c => {s=reflClitics ! c; agr=agr} ;
+ VPhrasal c => {s=personalClitics ! c ! agr.gn ! agr.p; agr={gn=GSg Neut; p=P3}}
+ }
+ in vp.ad.s ++ "да" ++ clitic.s ++ vp.s ! asp ! VPres (numGenNum clitic.agr.gn) clitic.agr.p ++ vp.compl ! agr ;
+
+-- For $Numeral$.
+
+ mkDigit : Str -> Str -> Str -> Str -> Str -> {s : DForm => CardOrd => Str} =
+ \dva, dvama, dve, vtori, dvesta ->
+ {s = table {
+ unit => mkCardOrd dva dvama dve vtori ;
+ teen => mkCardOrd (dva+"надесет") (dva+"надесетима") (dva+"надесет") (dva+"надесети") ;
+ ten => mkCardOrd (dva+"десет") (dva+"десетима") (dva+"десет") (dva+"десети") ;
+ hundred => let dvesten : Str
+ = case dvesta of {
+ dvest+"а" => dvest+"ен" ;
+ chetiristot+"ин" => chetiristot+"ен"
+ }
+ in mkCardOrd dvesta dvesta dvesta dvesten
+ }
+ } ;
+
+ mkCardOrd : Str -> Str -> Str -> Str -> CardOrd => Str =
+ \dva, dvama, dve, vtori ->
+ table {
+ NCard dg => digitGenderSpecies dva dvama dve ! dg ;
+ NOrd aform => let vtora = init vtori + "а" ;
+ vtoro = init vtori + "о"
+ in case aform of {
+ ASg Masc Indef => vtori ;
+ ASg Masc Def => vtori+"я" ;
+ ASgMascDefNom => vtori+"ят" ;
+ ASg Fem Indef => vtora ;
+ ASg Fem Def => vtora+"та" ;
+ ASg Neut Indef => vtoro ;
+ ASg Neut Def => vtoro+"то" ;
+ APl Indef => vtori ;
+ APl Def => vtori+"те"
+ }
+ } ;
+
+ digitGenderSpecies : Str -> Str -> Str -> DGenderSpecies => Str =
+ \dva, dvama, dve
+ -> let addDef : Str -> Str =
+ \s -> case s of {
+ dves+"та" => dves+"тате" ;
+ dv+"а" => dv+"ата" ;
+ x => x+"те"
+ }
+ in table {
+ DMascIndef => dva ;
+ DMascDef => addDef dva ;
+ DMascDefNom => addDef dva ;
+ DMascPersonalIndef => dvama ;
+ DMascPersonalDef => addDef dvama ;
+ DMascPersonalDefNom => addDef dvama ;
+ DFemIndef => dve ;
+ DFemDef => addDef dve ;
+ DNeutIndef => dve ;
+ DNeutDef => addDef dve
+ } ;
+
+ mkIP : Str -> Str -> GenNum -> {s : Role => QForm => Str ; gn : GenNum} =
+ \koi,kogo,gn -> {
+ s = table {
+ RSubj => table QForm [koi; koi+"то"] ;
+ RObj Acc => table QForm [kogo; kogo+"то"] ;
+ RObj Dat => table QForm ["на" ++ kogo; kogo+"то"] ;
+ RVoc => table QForm [koi; koi+"то"]
+ } ;
+ gn = gn
+ } ;
+
+ mkPron : (az,men,mi,moj,moia,moiat,moia_,moiata,moe,moeto,moi,moite : Str) -> GenNum -> Person -> {s : Role => Str; gen : AForm => Str; a : Agr} =
+ \az,men,mi,moj,moia,moiat,moia_,moiata,moe,moeto,moi,moite,gn,p -> {
+ s = table {
+ RSubj => az ;
+ RObj Acc => men ;
+ RObj Dat => mi ;
+ RVoc => az
+ } ;
+ gen = table {
+ ASg Masc Indef => moj ;
+ ASg Masc Def => moia ;
+ ASgMascDefNom => moiat ;
+ ASg Fem Indef => moia_ ;
+ ASg Fem Def => moiata ;
+ ASg Neut Indef => moe ;
+ ASg Neut Def => moeto ;
+ APl Indef => moi ;
+ APl Def => moite
+ } ;
+ a = {
+ gn = gn ;
+ p = p
+ }
+ } ;
+
+ mkNP : Str -> GenNum -> Person -> {s : Role => Str; a : Agr} =
+ \s,gn,p -> {
+ s = table {
+ RSubj => s ;
+ RObj Acc => s ;
+ RObj Dat => "на" ++ s ;
+ RVoc => s
+ } ;
+ a = {
+ gn = gn ;
+ p = p
+ }
+ } ;
+
+ Preposition : Type = {s : Str; c : Case};
+
+ mkQuestion :
+ {s : QForm => Str} -> Clause ->
+ {s : Tense => Anteriority => Polarity => QForm => Str} = \wh,cl ->
+ {
+ s = \\t,a,p,qform =>
+ let cls = cl.s ! t ! a ! p ;
+ in wh.s ! qform ++ cls ! case qform of {
+ QDir => Inv ;
+ QIndir => Main
+ }
+ } ;
+
+ whichRP : GenNum => Str
+ = table {
+ GSg Masc => "който" ;
+ GSg Fem => "която" ;
+ GSg Neut => "което" ;
+ GPl => "които"
+ } ;
+
+ suchRP : GenNum => Str
+ = table {
+ GSg Masc => "такъв" ;
+ GSg Fem => "такава" ;
+ GSg Neut => "такова" ;
+ GPl => "такива"
+ } ;
+
+ thisRP : GenNum => Str
+ = table {
+ GSg Masc => "този" ;
+ GSg Fem => "тaзи" ;
+ GSg Neut => "това" ;
+ GPl => "тези"
+ } ;
+
+ linCoord : Bool => Str ;
+ linCoord = table {True => "и"; False=>"или"} ;
+
+ linCoordSep : Str -> Bool => Bool => Str ;
+ linCoordSep s = table {True => linCoord; False=> \\_ => s} ;
+}