--# -path=.:../abstract:../common:../../prelude -- ----1 Arabic 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 ResAra = PatternsAra ** open Prelude, Predef in { flags optimize=noexpand ; coding=utf8 ; param Vowel = u | a | i ; Number = Sg | Dl | Pl; Gender = Masc | Fem ; Case = Nom | Acc | Gen ; Person = P1 | P2 | P3 ; Species = NoHum | Hum ; State = Def | Indef | Const ; Mood = Ind | Cnj | Jus ; Voice = Act | Pas ; Tense = Pres | Past | Fut ; Order = Verbal | Nominal ; oper --roots, patterns, and making words: Pattern : Type = {h, m1, m2, t : Str}; Root : Type = {f : Str}; Root2 : Type = Root ** {c : Str} ; Root3 : Type = Root2 ** {l : Str} ; -- AR 7/12/2009 changed this to avoid duplication of consonants mkRoot3 : Str -> Root3 = \fcl -> case fcl of { f@? + c@? + l => {f = f ; c = c ; l = l} } ; {- mkRoot3 : Str -> Root3 = \fcl -> let { cl = drop 2 fcl; --drop 1 fcl l' = dp 2 fcl; --last fcl c' = take 2 cl} in --take 1 cl {f = take 2 fcl; c = c'; --take 1 fcl l = case l' of { "ّ" => c'; _ => l' } }; -} --for roots with 2 consonants (works also for assimilated strs, like fc~, --because the function discards anything after the first two characters mkRoot2 : Str -> Root2 = \fcl -> let { cl = drop 2 fcl} in --drop 1 fcl {f = take 2 fcl; c = take 2 cl}; --take 1 --opers to interdigitize (make words out of roots and patterns: oper --regular case, 3 non-weak consonants mkStrong : Pattern -> Root3 -> Str = \p,fcl -> p.h + fcl.f + p.m1 + fcl.c + p.m2 + fcl.l + p.t; mkDefective: Pattern -> Root3 -> Str = \p,fcl -> p.h + fcl.f + p.m1 + fcl.c + p.t; mkHollow: Pattern -> Root3 -> Str = \p,fcl -> p.h + fcl.f + p.m1 + fcl.l + p.t; mkAssimilated: Pattern -> Root3 -> Str = \p,fcl -> p.h + fcl.c + p.m1 + fcl.l + p.t; -- takes a weak pattern and a triliteral root and makes -- a word, deducing which root consonant is weak mkWeak : Pattern -> Str -> Str = \pat,root -> let fcl = mkRoot3 root in case root of { _ + ("و"|"ي"|"ّ") => mkDefective pat fcl; _ + ("و"|"ي") + _ => mkHollow pat fcl; ("و"|"ي") + _ => mkAssimilated pat fcl }; mkBilit : Pattern -> Root2 -> Str = \p,fcl -> p.h + fcl.f + p.m1 + fcl.c + p.t; --takes a pattern string and root string and makes a word mkWord : Str -> Str -> Str =\pS, rS -> case pS of { w@_ + "ف" + x@_ + "ع" + y@_ + "ل" + z@_ => mkStrong { h = w ; m1 = x; m2 = y; t = z} (mkRoot3 rS); w@_ + "ف" + x@_ + "ع" + y@_ => let pat = { h = w ; m1 = x; m2 = ""; t = y} in case of { 6 | 5 => mkWeak pat rS ; --3=> 4 | 3 => mkBilit pat (mkRoot2 rS) ; --2=> _ => rS ---- AR error "expected 3--6" } }; --types of open classes: NTable = Number => State => Case => Str; Noun : Type = {s : NTable ; g : Gender; h : Species} ; -- Adj : Type = {s : Gender => NTable} ; Adj : Type = {s : AForm => Str} ; Verb : Type = {s : VForm => Str} ; param VForm = VPerf Voice PerGenNum | VImpf Mood Voice PerGenNum | VImp Gender Number | VPPart ; PerGenNum = Per3 Gender Number | Per2 Gender Number | Per1 SgPl; SgPl = Sing | Plur; AForm = APosit Gender Number State Case | AComp State Case ; --verbal morphology oper --macro for sound verb --PerfAct, PerfPas, ImpfAct, ImpfPas, Imp, PPart verb : (_,_,_,_,_,_ : Str) -> Verb = \katab,kutib,aktub,uktab,euktub,maktUb -> { s = table { VPerf Act pgn => katab + suffixPerf ! pgn ; VPerf Pas pgn => kutib + suffixPerf ! pgn ; VImpf Ind Act pgn => prefixImpf!pgn + aktub + suffixImpfInd !pgn; VImpf Ind Pas pgn => prefixImpf!pgn + uktab + suffixImpfInd !pgn; VImpf m Act pgn => prefixImpf!pgn + aktub + suffixImpfCJ m ! pgn; VImpf m Pas pgn => prefixImpf !pgn + uktab + suffixImpfCJ m !pgn; VImp g n => euktub + suffixImpfCJ Jus ! (Per2 g n); VPPart => maktUb } } ; --affixes of sound verbs suffixPerf : PerGenNum => Str = table { Per3 Masc Sg => "َ" ; Per3 Masc Dl => "َا" ; Per3 Masc Pl => "ُوا" ; Per3 Fem Sg => "َتْ" ; Per3 Fem Dl => "َتَا" ; Per3 Fem Pl => "ْنَ" ; Per2 Masc Sg => "ْتَ" ; Per2 _ Dl => "ْتُمَا" ; Per2 Masc Pl => "ْتُمْ" ; Per2 Fem Sg => "ْتِ" ; Per2 Fem Pl => "ْتُنَّ" ; Per1 Sing => "ْتُ" ; Per1 Plur => "ْنَا" } ; prefixImpf : PerGenNum => Str = table { Per1 Sing => "أ" ; Per1 Plur => "ن" ; Per3 Masc _ => "ي" ; Per3 Fem Pl => "ي" ; _ => "ت" } ; suffixImpfInd : PerGenNum => Str = table { Per3 Masc Pl => "ُونَ" ; Per3 Fem Pl => "ْنَ" ; Per3 g Dl => "َانِ" ; Per2 Masc Pl => "ُونَ" ; Per2 Fem Sg => "ِينَ" ; Per2 g Dl => "َانِ" ; Per2 Fem Pl => "ْنَ" ; _ => "ُ" } ; suffixImpfCJ : Mood -> PerGenNum => Str = \m -> table { Per3 Masc Pl => "ُوا" ; Per3 Fem Pl => "ْنَ" ; Per3 g Dl => "َا" ; Per2 Masc Pl => "ُوا" ; Per2 Fem Sg => "ِي" ; Per2 g Dl => "َا" ; Per2 Fem Pl => "ْنَ" ; _ => endVowel ! m } ; --macro for geminate verbs: FIXME, change the misleading variable names verbGeminate : (_,_,_,_,_,_,_,_,_,_,_ : Str) -> Verb = \xAf,xif,xyf,xuf,axAf,axaf,uxAf,uxaf,xaf,xAf',ppart -> let { perfPattern = patHollowPerf xAf xif xyf xuf ; impfPattern = patHollowImpf axAf axaf uxAf uxaf ; impPattern = patHollowImp xaf xAf' } in { s = table { VPerf v pgn => perfPattern ! v ! pgn + suffixPerf ! pgn ; VImpf Ind v pgn => prefixImpf ! pgn + impfPattern ! v ! pgn + suffixImpfInd ! pgn ; VImpf m v pgn => prefixImpf ! pgn + impfPattern ! v ! pgn + suffixImpfCJ m ! pgn ; VImp g n => impPattern ! g ! n + suffixImpfCJ Jus ! (Per2 g n); VPPart => ppart } } ; --macro for hollow verbs: verbHollow : (_,_,_,_,_,_,_,_,_,_,_ : Str) -> Verb = \xAf,xif,xyf,xuf,axAf,axaf,uxAf,uxaf,xaf,xAf',ppart -> let { perfPattern = patHollowPerf xAf xif xyf xuf ; impfPattern = patHollowImpf axAf axaf uxAf uxaf ; impPattern = patHollowImp axaf xAf' ; jusPattern = patHollowJus axaf axAf uxaf uxAf ; } in { s = table { VPerf v pgn => perfPattern ! v ! pgn + suffixPerf ! pgn ; VImpf Ind v pgn => prefixImpf ! pgn + impfPattern ! v ! pgn + suffixImpfInd ! pgn ; VImpf Cnj v pgn => prefixImpf ! pgn + impfPattern ! v ! pgn + suffixImpfCJ Cnj ! pgn ; VImpf Jus v pgn => prefixImpf ! pgn + jusPattern ! v ! pgn + suffixImpfCJ Jus ! pgn ; VImp g n => impPattern ! g ! n + suffixImpfCJ Jus ! (Per2 g n); VPPart => ppart } } ; --macro for defective verbs: verbDef: (_,_,_,_,_,_,_,_,_,_,_ : Str) -> Vowel -> Verb = \rama,ramay,rumi,rumu,rumiy,armi,armu,urma,Irmi,Irmu,ppart,vowel -> let { patPerf = patDefPerf rama ramay rumi rumu rumiy ; patImpfAct = patDefImpfAct armi armu ; patImp = patDefImp Irmi Irmu } in { s = table { VPerf v pgn => patPerf ! v ! pgn + (suffixPerfDef v) ! pgn ; VImpf m Act pgn => prefixImpf ! pgn + patImpfAct ! pgn + (suffixImpfDef Act vowel) ! m ! pgn ; VImpf m Pas pgn => prefixImpf ! pgn + urma + (suffixImpfDef Pas vowel) ! m ! pgn ; VImp g n => patImp ! g ! n + (suffixImpfDef Act vowel) ! Jus ! (Per2 g n) ; VPPart => ppart } } ; patDefPerf : (_,_,_,_,_ :Str) -> Voice => PerGenNum => Str = \rama,ramay,rumi,rumu,rumy -> table { Act => table { Per3 Fem Pl => ramay ; Per3 _ _ => rama ; _ => ramay } ; Pas => table { Per3 Masc Pl => rumu ; Per3 Fem Pl => rumy ; Per3 _ _ => rumi ; _ => rumy } } ; --ignores the vowel=u case, eg "دعو" patDefImpfAct : (_,_ : Str) -> PerGenNum => Str = \rmi,rmu -> table { Per3 Masc Pl => rmu ; Per2 Masc Pl => rmu ; _ => rmi } ; patDefImp : (_,_ : Str) -> Gender => Number => Str = \rmi, rmu -> table { Masc => table {Pl => rmu ; _ => rmi} ; _ => table {_ => rmi} } ; suffixPerfDef : Voice -> PerGenNum => Str = \v -> let {p3ms = case v of { Act => "ى" ; Pas => "يَ" } ; ya = case v of { Act => "" ; Pas => "يَ" } } in table { Per3 Masc Sg => p3ms ; Per3 Masc Dl => "يَا" ; Per3 Masc Pl => "وْا" ; Per3 Fem Sg => ya + "تْ" ; Per3 Fem Dl => ya + "تَا" ; Per3 Fem Pl => "نَ" ; Per2 Masc Sg => "تَ" ; Per2 _ Dl => "تُمَا" ; Per2 Masc Pl => "تُمْ" ; Per2 Fem Sg => "تِ" ; Per2 Fem Pl => "تُنَّ" ; Per1 Sing => "تُ" ; Per1 Plur => "نَا" } ; suffixImpfDef : Voice -> Vowel -> Mood => PerGenNum => Str = \vc,vw -> let { default : Mood -> Str = \m -> case vc of { Pas => case m of {Jus => "" ; _ => "ى"} ; Act => case vw of { u => case m of {Ind => "و" ; Cnj => "وَ" ; Jus => ""} ; i => case m of {Ind => "ي" ; Cnj => "يَ" ; Jus => ""} ; a => case m of {Ind => "ى" ; Cnj => "ى" ; Jus => ""} } } } in table { Ind => table { Per3 Masc Pl => "وْنَ" ; Per2 Masc Pl => "وْنَ" ; Per3 g Dl => "يَانِ" ; Per2 g Dl => "يَانِ" ; Per3 Fem Pl => "يْنَ" ; Per2 Fem _ => "يْنَ" ; _ => default Ind } ; m => table { Per3 Masc Pl => "وْا" ; Per2 Masc Pl => "وْا" ; Per3 g Dl => "يَا" ; Per2 g Dl => "يَا" ; Per3 Fem Pl => "يْنَ" ; Per2 Fem Pl => "يْنَ" ; Per2 Fem Sg => "ي" ; _ => default m } } ; --now is used for the sound, assimilated (weak C1), and when C1 = hamza: v1sound : Root3 -> Vowel -> Vowel -> Verb = \fcl,vPerf,vImpf -> let { qf = {f = fcl.c ; c = fcl.l} ; qif = mkBilit (fvc ! vImpf) qf; katab = mkStrong (patV1Perf ! vPerf) fcl ; kutib = mkStrong fucil fcl ; --FIXME no passive if vPerf == u ktub = mkStrong (patV1Impf ! vImpf) fcl ; aktub = "َ" + case fcl.f of { "و"|"ي" => qif ; _ => ktub }; uktab = mkStrong ufcal fcl ; euktub = case fcl.f of { "؟"|"و"|"ي" => qif ; _ => prefixImp ! vImpf + ktub }; maktUb = mkStrong mafcUl fcl } in verb katab kutib aktub uktab euktub maktUb ; v1hollow : Root3 -> Vowel -> Verb = \xwf,vowel -> let { xAf = mkHollow fAc xwf ; xif = mkHollow (patHol1 ! vowel) xwf ; xyf = mkHollow fIc xwf ; xuf = mkHollow (patHol2 ! vowel) xwf ; xaf = mkHollow (fvc ! vowel) xwf ; axaf= "َ" + xaf ; uxAf= mkHollow ufAc xwf ; uxaf= "ُ" + xaf ; xAf'= mkHollow (patHol3 ! vowel) xwf ; axAf= "َ" + xAf'; ppart = "مَ" + xAf' -- FIXME actually wierd anomalies happen with the a vowel.. } in verbHollow xAf xif xyf xuf axAf axaf uxAf uxaf xaf xAf' ppart ; patHol1 : Vowel => Pattern = table { u => fuc ; _ => fic} ; patHol2 : Vowel => Pattern = table { u => fic ; _ => fuc} ; patHol3 : Vowel => Pattern = table { u => fUc ; i => fIc ; a => fAc } ; --used in assimilated (wqf -> qif, wqc -> qac..) and hollow (qwl -> qul, xwf->xaf..) fvc : Vowel => Pattern = table { u => fuc ; i => fic ; a => fac } ; v1geminate : Str -> Vowel -> Vowel -> Verb = \rootStr,vPerf,vImpf -> let { mdd = mkRoot3 rootStr ; --fcc md = mkRoot2 rootStr ; --fc madd = mkBilit facc md ; madad = mkStrong (patGem1 ! vPerf) mdd ; mudd = mkBilit fucc md ; mudid = mkStrong fucil mdd ; mudd' = mkBilit (patGem2 ! vImpf) md ; amudd = "َ" + mudd' ; mdud = mkStrong (patGem3 ! vImpf) mdd ; amdud = "َ" + mdud ; umadd = "ُ" + madd ; umdad = "ُ" + mkStrong fcal mdd ; Umdud = (prefixImp ! vImpf) + mdud; mamdUd = mkStrong mafcUl mdd } in verbGeminate madd madad mudd mudid amudd amdud umadd umdad Umdud mudd' mamdUd; patGem1 : Vowel => Pattern = table { a => facal ; u => facul ; i => facil } ; patGem2 : Vowel => Pattern = table { u => fucc ; a => facc ; i => ficc --no such verb probably exists } ; patGem3 : Vowel => Pattern = table { u => fcul ; a => fcal ; i => fcil --no such verb probably exists } ; v1defective : Root3 -> Vowel -> Verb = \rmy,vowel -> let { rama = mkDefective faca rmy ; ramay = mkStrong facalo rmy ; rumi = mkDefective fuci rmy ; rumu = mkDefective fucu rmy ; rumiy = mkStrong fucilo rmy ; rmi = mkDefective (patDef1 ! vowel) rmy ; armi = "َ" + rmi ; rmu = mkDefective (patDef2 ! vowel) rmy ; armu = "َ" + rmu ; urma = mkDefective ufca rmy ; eirmi = prefixImp ! vowel + rmi; eirmu = prefixImp ! vowel + rmu; marmiy = mkStrong mafcil rmy } in verbDef rama ramay rumi rumu rumiy armi armu urma eirmi eirmu marmiy vowel ; patDef1 : Vowel => Pattern = table { u => fcu ; a => fca ; i => fci } ; patDef2 : Vowel => Pattern = table { a => fca ; _ => fcu } ; v2sound : Root3 -> Verb = \qsm -> let { qassam = mkStrong faccal qsm ; qussim = mkStrong fuccil qsm ; qassim = mkStrong faccil qsm ; uqassim = "ُ" + qassim ; uqassam = "ُ" + qassam ; muqassam = "مُ" + qassam } in verb qassam qussim uqassim uqassam qassim muqassam; v2defective : Root3 -> Verb = \gny -> let { ganna = mkDefective facca gny ; gannay = mkStrong faccalo gny ; gunni = mkDefective fucci gny ; gunnu = mkDefective fuccu gny ; gunniy = mkStrong fuccilo gny ; ganni = mkDefective facci gny; uganni = "ُ" + ganni; gannu = mkDefective faccu gny; ugannu = "ُ" + gannu; uganna = "ُ" + ganna; mugannaY = "مُ" + ganna + "ى" } in verbDef ganna gannay gunni gunnu gunniy uganni ugannu uganna ganni gannu mugannaY i; v3sound : Root3 -> Verb = \tbc -> let { tAbac = mkStrong fAcal tbc ; twbic = mkStrong fUcil tbc ; tAbic = mkStrong fAcil tbc ; utAbic = "ُ" + tAbic ; utAbac = mkStrong ufAcal tbc ; mutAbac = "م" + utAbac } in verb tAbac twbic utAbic utAbac tAbic mutAbac; v4sound : Root3 -> Verb = \qnc -> let { eaqnac = mkStrong eafcal qnc; euqnic = mkStrong eufcil qnc; uqnic = mkStrong ufcil qnc; uqnac = mkStrong ufcal qnc; eaqnic = mkStrong eafcil qnc; muqnac = "م" + uqnac } in verb eaqnac euqnic uqnic uqnac eaqnic muqnac; v4defective : Root3 -> Verb = \cTy -> let { cTa = mkDefective fca cTy; cTu = mkDefective fcu cTy; cTi = mkDefective fci cTy; eacTa = "أَ" + cTa; eacTay = mkStrong eafcal cTy ; ucTi = "ُ" + cTi; eucTi = "أُ" + cTi; ucTu = "ُ" + cTu; eucTu = "أُ" + cTu; eucTiy = mkStrong eufcil cTy ; ucTa = "ُ" + cTa; eacTi = "أَ" + cTi; eacTu = "أَ" + cTu; mucTaY = "م" + ucTa +"ى" } in verbDef eacTa eacTay eucTi eucTu eucTiy ucTi ucTu ucTa eacTi eacTu mucTaY i; v5sound : Root3 -> Verb = \nfs -> let { tanaffas = mkStrong tafaccal nfs ; tunuffis = mkStrong tufuccil nfs ; atanaffas = "َ" + tanaffas ; utanaffas = "ُ" + tanaffas ; mutanaffas = "م" + tanaffas } in verb tanaffas tunuffis atanaffas utanaffas tanaffas mutanaffas; v6sound : Root3 -> Verb = \fqm -> let { tafAqam = mkStrong tafAcal fqm ; tufUqim = mkStrong tufUcil fqm ; atafAqam = "َ" + tafAqam ; utafAqam = "ُ" + tafAqam ; mutafAqam = "م" + utafAqam } in verb tafAqam tufUqim atafAqam utafAqam tafAqam mutafAqam; v8sound : Root3 -> Verb = \rbT -> let { rtabiT = mkStrong ftacil rbT ; rtabaT = mkStrong ftacal rbT ; eirtabaT = "إِ" + rtabaT ; eurtubiT = mkStrong euftucil rbT ; artabiT = "َ" + rtabiT ; urtabaT = "ُ" + rtabaT ; eirtabiT = "إِ" + rtabiT ; murtabaT = "م" + urtabaT } in verb eirtabaT eurtubiT artabiT urtabaT eirtabiT murtabaT; patV1Perf : Vowel => Pattern = table { a => facal ; --katab u => facul ; --Hasun i => facil --rabiH } ; patV1Impf : Vowel => Pattern = table { u => fcul ; --ktub a => fcal ; --rbaH i => fcil --Hsin } ; endVowel : Mood => Str = table { Cnj => "َ" ; Jus => "ْ" ; Ind => "" } ; prefixImp : Vowel => Str = table { u => "أُ" ; _ => "إِ" } ; patHollowPerf : (_,_,_,_ :Str) -> Voice => PerGenNum => Str = \xAf,xif,xyf,xuf -> table { Act => table { Per3 Fem Pl => xif ; Per3 _ _ => xAf ; _ => xif } ; Pas => table { Per3 Fem Pl => xuf ; Per3 _ _ => xyf ; _ => xuf } } ; --this is the pattern of imperfect hollow (ind & conj) and geminate verbs (all) patHollowImpf : (_,_,_,_ :Str) -> Voice => PerGenNum => Str = \axAf,axaf,uxAf,uxaf -> table { Act => table { Per3 Fem Pl => axaf ; Per2 Fem Pl => axaf ; _ => axAf } ; Pas => table { Per3 Fem Pl => uxaf ; Per2 Fem Pl => uxaf ; _ => uxAf } } ; patHollowJus : (_,_,_,_ : Str) -> Voice => PerGenNum => Str =\axaf,axAf,uxaf,uxAf-> table { Act => table { Per3 g Sg => axaf ; Per3 Fem Pl => axaf; Per2 Fem Pl => axaf; Per2 Masc Sg => axaf; Per1 _ => axaf; _ => axAf } ; Pas => table { Per3 g Sg => uxaf ; Per3 Fem Pl => uxaf; Per2 Fem Pl => uxaf; Per2 Masc Sg => uxaf; Per1 _ => uxaf; _ => uxAf } } ; patHollowImp : (_,_ :Str) -> Gender => Number => Str =\xaf,xAf -> table { Masc => table { Sg => xaf ; _ => xAf} ; Fem => table { Pl => xaf ; _ => xAf} } ; --Nominal Morphology --takes the adjective lemma and gives the Posit table positAdj : Str -> Gender => NTable = \kabIr -> let kabIra = kabIr + "َة" in table { Masc => sndm kabIr; Fem => sndf kabIra }; clr : Str -> Str -> Str -> AForm => Str = \aHmar,HamrA',Humr -> table { APosit Masc n d c => case n of { Sg => indeclN aHmar ! d ! c ; Dl => dual aHmar ! d ! c ; Pl => sing Humr ! d ! c }; APosit Fem n d c => case n of { Sg => indeclN HamrA' ! d ! c; Dl => dual ((tk 2 HamrA') + "و") ! d ! c; Pl => sing Humr ! d ! c }; AComp d c => indeclN aHmar ! d ! c }; -- indeclinable nominal word (mamnuu3 mina S-Sarf) indeclN : Str -> State => Case => Str = \aHmar -> \\s,c => Al!s + aHmar + indecl!c; -- takes 2 words, singular and broken plural, and gives the -- complete noun inflection table reg : Str -> Str -> NTable = \kitAb,kutub -> table { Sg => sing kitAb ; Dl => dual kitAb ; Pl => sing kutub }; --takes the sound noun in singular and gives the --complete noun inflection table of sound feminine plural sndf : Str -> NTable = \lawHa -> table { Sg => sing lawHa ; Dl => dual lawHa ; Pl => plurF lawHa }; --takes the sound noun in singular and gives the --complete inflection table of sound masculine plural nominals sndm : Str -> NTable = \muzAric -> table { Sg => sing muzAric ; Dl => dual muzAric ; Pl => plurM muzAric }; -- takes a singular or broken plural word and tests the ending to -- determine the declension and gives the corresponding inf table sing : Str -> State => Case => Str = \word -> case word of { lemma + "ِي" => \\s,c => Al ! s + lemma + dec2sg ! s ! c ; _ + ("ا"|"ى") => \\s,c => Al ! s + word + dec3sg ! s ! c ; _ => \\s,c => Al ! s + word + dec1sg ! s ! c }; -- takes a singular word and tests the ending to -- determine the declension and gives the corresponding dual inf table dual : Str -> State => Case => Str = \caSaA -> case caSaA of { lemma + ("ا"|"ى") => \\s,c => Al ! s + lemma + "ي" + dl ! s ! c ; _ => \\s,c => Al ! s + caSaA + dl ! s ! c }; -- takes a singular word and gives the corresponding sound --plural feminine table plurF : Str -> State => Case => Str = \kalima -> \\s,c => Al ! s + (mkAt kalima) + f_pl ! s ! c ; -- takes a singular word and gives the corresponding sound --plural masculine table. FIXME: consider declension 3 plurM : Str -> State => Case => Str = \mucallim -> \\s,c => Al ! s + mucallim + m_pl ! s ! c ; -- to add the Al prefix for Definite words Al : State => Str = table { Def => "ال"; _ => "" }; --declection 1 (strong ending) of the singular or broken plural words dec1sg : State => Case => Str = table { Indef => table { Nom => "ٌ"; Acc => "ً"; Gen => "ٍ" }; _ => table { --think of ?axU, ?axA, (the five nouns) Nom => "ُ"; Acc => "َ"; Gen => "ِ" } }; --indeclinables (mamnuu3 mina S-Sarf) indecl : Case => Str = table { Nom => "ُ"; _ => "َ" }; --declection 2 (ends in yaa') dec2sg : State => Case => Str = table { Indef => table { Acc => "ِياً"; _ => "ٍ" }; _ => table { Acc => "ِيَ"; _ => "ِي" } }; --declention 3 (ending in alif) dec3sg : State => Case => Str = table { Indef => table { _ => "ً" }; _ => table { _ => "" } }; --dual suffixes dl : State => Case => Str = table { Const => table { Nom => "َا"; _ => "َي" }; _ => table { Nom => "َانِ"; _ => "َينِ" } }; --sound mascualine plural suffixes m_pl : State => Case => Str = table { Const => table { Nom => "ُو"; _ => "ِي" }; _ => table { Nom => "ُونَ"; _ => "ِينَ" } }; --sound feminine plural suffixes f_pl : State => Case => Str = table { Indef => table { Nom => "ٌ"; _ => "ٍ" }; _ => table { Nom => "ُ"; _ => "ِ" } }; mkAt : Str -> Str = \bayDo -> case bayDo of { bayD + "ة" => bayD + "ات"; bayD + "اء" => bayD + "اوات"; bayD + "ى" => bayD + "يَات"; _ => bayDo + "ات" }; oper sizeToNumber : Size -> Number = \s -> case s of { ThreeTen | None => Pl; Two => Dl; _ => Sg } ; numberToSize : Number -> Size = \n -> case n of { Pl => ThreeTen; Dl => Two ; Sg => One -- or Hundreds or NonTeen } ; detGender : Gender -> Size -> Gender = \g,s -> case s of { ThreeTen | Teen => genPolarity ! g; _ => g }; nounState : State -> Number -> State = \s,n -> case of { => Def; --kullu l-kutubi, bacDu l-kutubi => Indef; --kullu kitaabin => Indef; --kitaabun _ => Def --Lkitaabu }; --FIXME needs testing nounCase : Case -> Size -> State -> Case = \c,size,s -> case of { => Acc; => Acc; => Gen; => Gen; <_,Const> => Gen; _ => c }; definite : State => State = table { Indef => Indef; _ => Def }; --things like mi{aö and vlAva and >alf should be treated as Const --before the counted noun, so (vlAvaöN kutubK) is wrong toDef : State -> Size -> State = \s,n -> case of { => Const; => Const; _ => s }; -- in a NP, sometimes the common noun preceedes the determiner -- e.g. some determiners act as adjectives modifying the noun they count -- 'the three children, two children' -- e.g. possesive pronouns: his book ('kitaabuhu' cnB4det : Bool -> Bool -> Size -> State -> Bool = \isPron,isNum,s,d -> case of { => True; <_,False,_,_> => False; --non-numerals <_,True,_,Def> => True; --definite numbers act as adjectives <_,True,Two,_> => True; --numerals one and two always adjectives <_,True,One,_> => True; --numerals one and two always adjectives _ => False }; agrP3 : Species -> Gender -> Number -> PerGenNum= \h,g,n -> case of { => Per3 Fem Sg; _ => Per3 g n }; pgn2gn : PerGenNum -> {g : Gender; n : Number} = \pgn -> case pgn of { Per3 gn nm => {g = gn; n = nm}; Per2 gn nm => {g = gn; n = nm}; _ => {g = Masc; n = Sg} --randomly }; mkIP : Str -> Number -> {s : Str ; n : Number} = \s,n -> {s = s ; n = n} ; mkOrd : (_,_ : Str) -> {s : Gender => State => Case => Str ; n : Size } = \aysar,yusra -> { s = \\g,s,c => case g of { Masc => (sing aysar) ! s ! c; Fem => (sing yusra) ! s ! c }; n = None }; oper Det : Type = { s : Species => Gender => Case => Str ; d : State; n : Size; isNum : Bool; -- for genitive pronouns (suffixes). if true, then "cn ++ det" --should be used instead of "det ++ cn" when constructing the NP isPron : Bool } ; Predet : Type = { s : Case => Str; isDecl : Bool }; Agr = { pgn : PerGenNum; isPron : Bool} ; AAgr = { g : Gender ; n : Number} ; Comp : Type = { s : AAgr => Case => Str } ; Obj : Type = { s : Str ; a : Agr }; NP : Type = { s : Case => Str ; a : Agr } ; param VPForm = VPPerf | VPImpf Mood | VPImp ; oper VP : Type = { s : PerGenNum => VPForm => Str; obj : Obj; pred : Comp; isPred : Bool; --indicates if there is a predicate (xabar) s2 : Str }; predV : Verb -> VP = \v -> { s = \\pgn,vf => let gn = pgn2gn pgn in case vf of { VPPerf => v.s ! (VPerf Act pgn); VPImpf m => v.s ! (VImpf m Act pgn); VPImp => v.s ! (VImp Masc Sg)--gn.g gn.n) }; obj = { s = [] ; a = {pgn = Per3 Masc Sg ; isPron = False} }; --or anything! s2 = []; pred = { s = \\_,_ => []}; isPred = False }; -- in verbal sentences, the verb agrees with the subject -- in Gender but not in number verbalAgr : PerGenNum -> PerGenNum = \pgn -> case pgn of { Per3 g _ => Per3 g Sg; _ => pgn }; insertObj : NP -> VP -> VP = \np,vp -> { s = vp.s; obj = {s = np.s ! Acc ; a = np.a}; s2 = vp.s2; pred = vp.pred; isPred = vp.isPred }; insertPred : {s : AAgr => Case => Str} -> VP -> VP = \p,vp -> { s = vp.s; obj = vp.obj; s2 = vp.s2; pred = p; isPred = True }; insertStr : Str -> VP -> VP = \str,vp -> { s = vp.s; obj = vp.obj; s2 = str; pred = vp.pred; isPred = vp.isPred }; kaan : {s : AAgr => Case => Str} -> VP = \xabar -> insertPred xabar (predV (v1hollow {f = "ك"; c = "و" ; l = "ن"} u) ); param Size = One | Two | ThreeTen | Teen | NonTeen | Hundreds | None ; DForm = unit | ten ; CardOrd = NCard | NOrd ; oper --digits 1, 3 - 10: take the lemmas of the card ords & in masculine --form and calculates the whole table regNum : Str -> Str -> {s : DForm => CardOrd => Gender => State => Case => Str} = \xams,xAmis -> let { xamsa = xams + "َة"; xAmisa = xAmis + "َة"} in mkNum xamsa xAmis xAmisa; mkNum : Str -> Str -> Str -> {s : DForm => CardOrd => Gender => State => Case => Str} = \wAhid,awwal,Ula -> let { wAhida = wAhid + "َة"} in { s= table { unit => table { NCard => table { Masc => \\s,c => (sing wAhid) ! s ! c ; --all fem are first declension: Fem => \\s,c => Al ! s + wAhida + dec1sg ! s ! c }; NOrd => table { Masc => \\s,c => Al ! s + awwal + dec1sg ! s ! c; Fem => \\s,c => (sing Ula) ! s ! c } }; ten => table { NCard => \\_,s,c => Al ! s + wAhid + m_pl ! Indef ! c; NOrd => \\_,s,c => Al ! s + awwal + m_pl ! Indef ! c } } }; num3_10 : Str -> Str -> { s : DForm => CardOrd => Gender => State => Case => Str ; n : Size } = \xams,xAmis -> regNum xams xAmis ** { n = ThreeTen }; num2 : { s : DForm => CardOrd => Gender => State => Case => Str} = { s = table { unit => table { NCard => table { Masc => \\s,c => Al ! s + "ٱِثن" + dl ! s ! c ; Fem => \\s,c => Al ! s + "ٱِثنَت" + dl ! s ! c }; NOrd => table { Masc => \\s,c => Al ! s + "ثان" + dec2sg ! s ! c ; Fem => \\s,c => Al ! s + "ثانِيَة" + dec1sg ! s ! c } }; ten => \\_,_,s,c => Al ! s + "عِشر" + m_pl ! Indef ! c } }; num100 : State => Case => Str = \\s,c => Al ! s + "مِٱَة" + dec1sg ! s ! c; num200 : State => Case => Str = \\s,c => Al ! s + "مِٱَة" + dl ! s ! c ; num1000 : State => Case => Str = \\s,c => Al ! s + "أَلف" + dec1sg ! s ! c; num2000 : State => Case => Str = \\s,c => Al ! s + "أَلف" + dl ! s ! c ; teen : Gender => Str = table { Masc => "عَشَرَ"; Fem => "عَشرَةَ" }; genPolarity : Gender => Gender = table { Masc => Fem; Fem => Masc }; }