Files
gf-core/lib/resource/arabic/ResAra.gf
2007-12-12 20:30:11 +00:00

1117 lines
29 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
--# -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=all ;
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 ;
PerGenNum =
Per3 Gender Number
| Per2 Gender Number
| Per1 SgPl;
SgPl = Sing | Plur;
AForm =
APosit Gender Number State Case
| AComp Case ;
--verbal morphology
oper
--macro for sound verb
verb : (_,_,_,_,_ : Str) -> Verb = --PerfAct, PerfPas, ImpfAct, ImpfPas, Imp
\katab,kutib,aktub,uktab,euktub ->
{ 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)
}
} ;
--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' ->
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)
}
} ;
--macro for hollow verbs:
verbHollow : (_,_,_,_,_,_,_,_,_,_ : Str) -> Verb =
\xAf,xif,xyf,xuf,axAf,axaf,uxAf,uxaf,xaf,xAf' ->
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)
}
} ;
--macro for defective verbs:
verbDef: (_,_,_,_,_,_,_,_,_,_ : Str) -> Vowel -> Verb =
\rama,ramay,rumi,rumu,rumiy,armi,armu,urma,Irmi,Irmu,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)
}
} ;
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
}
} in
verb katab kutib aktub uktab euktub ;
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'
} in verbHollow xAf xif xyf xuf axAf axaf uxAf uxaf xaf xAf' ;
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
} in verbGeminate madd madad mudd mudid amudd amdud umadd umdad Umdud mudd' ;
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
} in verbDef rama ramay rumi rumu rumiy armi armu urma eirmi eirmu 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
} in
verb qassam qussim uqassim uqassam qassim ;
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;
} in verbDef ganna gannay gunni gunnu gunniy uganni ugannu uganna ganni gannu i;
v3sound : Root3 -> Verb =
\tbc ->
let {
tAbac = mkStrong fAcal tbc ;
twbic = mkStrong fUcil tbc ;
tAbic = mkStrong fAcil tbc ;
utAbic = "ُ" + tAbic ;
utAbac = mkStrong ufAcal tbc ;
} in verb tAbac twbic utAbic utAbac tAbic;
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
} in
verb eaqnac euqnic uqnic uqnac eaqnic ;
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;
} in verbDef eacTa eacTay eucTi eucTu eucTiy ucTi ucTu ucTa eacTi eacTu i;
v5sound : Root3 -> Verb =
\nfs ->
let {
tanaffas = mkStrong tafaccal nfs ;
tunuffis = mkStrong tufuccil nfs ;
atanaffas = "َ" + tanaffas ;
utanaffas = "ُ" + tanaffas ;
} in verb tanaffas tunuffis atanaffas utanaffas tanaffas ;
v6sound : Root3 -> Verb =
\fqm ->
let {
tafAqam = mkStrong tafAcal fqm ;
tufUqim = mkStrong tufUcil fqm ;
atafAqam = "َ" + tafAqam ;
utafAqam = "ُ" + tafAqam ;
} in verb tafAqam tufUqim atafAqam utafAqam tafAqam ;
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 ;
} in verb eirtabaT eurtubiT artabiT urtabaT eirtabiT;
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
adj : Str -> Gender => NTable =
\kabIr ->
let kabIra = kabIr + "َة" in
table {
Masc => sndm kabIr;
Fem => sndf kabIra
};
clr : Str -> Str -> Str -> Gender => NTable =
\aHmar,HamrA',Humr ->
table {
Masc => table {
Sg => indeclN aHmar;
Dl => dual aHmar;
Pl => sing Humr
};
Fem => table {
Sg => indeclN HamrA';
Dl => dual ((tk 2 HamrA') + "و");
Pl => sing Humr
}
};
-- 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') of the singular or broken plural words
dec2sg : State => Case => Str =
table {
Indef =>
table {
Acc => "ِياً";
_ => "ٍ"
};
_ =>
table {
Acc => "ِيَ";
_ => "ِي"
}
};
--declection 3 (ending in alif) of the singular or broken plural words
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, should be wrong!
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
};
--some determiners act as adjectives modifying the noun they count
detAsAdj : Bool -> Size -> State -> Bool = \isNum,s,d ->
case <isNum,s,d> of {
<False,_,_> => False; --this doesn't hold for 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
} ;
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 ;
oper
--digits 3 to 10: take the digit in masculine form and
--calculates the whole table
num1_10 : Str -> { s : DForm => Gender => State => Case => Str } =
\xams ->
let xamsa = xams + "َة" in {
s= table {
unit => table {
Masc => \\s,c => (sing xams) ! s ! c ;
Fem => \\s,c => Al ! s + xamsa + dec1sg ! s ! c --we know it's dec1
};
ten => \\_,s,c => Al ! s + xams + m_pl ! Indef ! c
}
};
num3_10 : Str ->{ s : DForm => Gender => State => Case => Str ;
n : Size } =
\xams ->
num1_10 xams ** { n = ThreeTen };
num2 : { s : DForm => Gender => State => Case => Str} =
{ s = table {
unit =>
table {
Masc => \\s,c => Al ! s + "ٱِثن" + dl ! s ! c ;
Fem => \\s,c => Al ! s + "ٱِثنَت" + dl ! 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
};
}