summaryrefslogtreecommitdiff
path: root/next-lib/src/arabic/ResAra.gf
diff options
context:
space:
mode:
authoraarne <aarne@cs.chalmers.se>2008-12-18 14:17:42 +0000
committeraarne <aarne@cs.chalmers.se>2008-12-18 14:17:42 +0000
commit98a4b6a8088273dfa55dfa1c3ea78e85cd9c7a8d (patch)
tree21e45db3182648b50f6d88557f33613efab5996a /next-lib/src/arabic/ResAra.gf
parent9d0df9e0b49e06f4e182269f563555e803ff27ac (diff)
Arabic compiles now in 1.5
Diffstat (limited to 'next-lib/src/arabic/ResAra.gf')
-rw-r--r--next-lib/src/arabic/ResAra.gf1171
1 files changed, 1171 insertions, 0 deletions
diff --git a/next-lib/src/arabic/ResAra.gf b/next-lib/src/arabic/ResAra.gf
new file mode 100644
index 000000000..e18dc5ebe
--- /dev/null
+++ b/next-lib/src/arabic/ResAra.gf
@@ -0,0 +1,1171 @@
+--# -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} ;
+
+ 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 <length rS : Ints 100> 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 <s,n> of {
+ <Const,Pl> => Def; --kullu l-kutubi, bacDu l-kutubi
+ <Const,Sg> => Indef; --kullu kitaabin
+ <Indef,_> => Indef; --kitaabun
+ _ => Def --Lkitaabu
+ };
+
+
+ --FIXME needs testing
+ nounCase : Case -> Size -> State -> Case =
+ \c,size,s ->
+ case <size,s> of {
+ <Teen,_> => Acc;
+ <NonTeen,_> => Acc;
+ <ThreeTen,_> => Gen;
+ <Hundreds,_> => 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 <s,n> of {
+ <Indef,Hundreds> => Const;
+ <Indef,ThreeTen> => 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 <isPron,isNum,s,d> of {
+ <True,_,_,_> => 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 <h,n> of {
+ <NoHum,Pl> => 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
+ };
+
+
+}