mirror of
https://github.com/GrammaticalFramework/gf-core.git
synced 2026-04-20 10:19:32 -06:00
1170 lines
31 KiB
Plaintext
1170 lines
31 KiB
Plaintext
--# -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 ;
|
||
|
||
|
||
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) of {
|
||
6 | 5 => mkWeak pat rS; --3=>
|
||
4 | 3 => mkBilit pat (mkRoot2 rS)--2=>
|
||
}
|
||
};
|
||
|
||
--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 ;
|
||
lemma + ("ا"|"ى") => \\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
|
||
};
|
||
|
||
|
||
}
|