mirror of
https://github.com/GrammaticalFramework/gf-core.git
synced 2026-05-17 15:12:50 -06:00
700 lines
23 KiB
Plaintext
700 lines
23 KiB
Plaintext
-- ResMlt.gf: Language-specific parameter types, morphology, VP formation
|
|
--
|
|
-- Maltese GF Resource Grammar
|
|
-- John J. Camilleri 2011 -- 2013
|
|
-- Angelo Zammit 2012
|
|
-- Licensed under LGPL
|
|
|
|
--# -path=.:../abstract:../common:../prelude
|
|
|
|
resource ResMlt = ParamX ** open Prelude, Predef in {
|
|
|
|
flags coding=utf8 ;
|
|
|
|
{- General -------------------------------------------------------------- -}
|
|
|
|
param
|
|
|
|
Gender = Masc | Fem ;
|
|
|
|
GenNum =
|
|
GSg Gender -- dak, dik
|
|
| GPl -- dawk
|
|
;
|
|
|
|
oper
|
|
-- Agreement system corrected based on comments by [AZ]
|
|
Agr : Type = { g : Gender ; n : Number ; p : Person } ;
|
|
|
|
mkAgr : Gender -> Number -> Person -> Agr = \g,n,p -> {g = g ; n = n ; p = p} ;
|
|
|
|
toVAgr : Agr -> VAgr = \agr ->
|
|
case <agr.p,agr.n> of {
|
|
<P1,num> => AgP1 num;
|
|
<P2,num> => AgP2 num;
|
|
<P3,Sg> => AgP3Sg agr.g;
|
|
<P3,Pl> => AgP3Pl
|
|
} ;
|
|
|
|
toAgr : VAgr -> Agr = \vagr ->
|
|
case vagr of {
|
|
AgP1 num => mkAgr Masc num P1 ; --- sorry ladies
|
|
AgP2 num => mkAgr Masc num P2 ;
|
|
AgP3Sg gen => mkAgr gen Pl P3 ;
|
|
AgP3Pl => mkAgr Masc Pl P3
|
|
} ;
|
|
|
|
param
|
|
-- Agreement for verbs
|
|
VAgr =
|
|
AgP1 Number -- jiena, aħna
|
|
| AgP2 Number -- inti, intom
|
|
| AgP3Sg Gender -- huwa, hija
|
|
| AgP3Pl -- huma
|
|
;
|
|
|
|
param
|
|
NPCase = Nom | CPrep ; -- [AZ]
|
|
|
|
-- Animacy = Animate | Inanimate ;
|
|
|
|
-- Definiteness =
|
|
-- Definite -- eg IL-KARTA. In this context same as Determinate
|
|
-- | Indefinite -- eg KARTA
|
|
-- ;
|
|
|
|
|
|
{- Numeral -------------------------------------------------------------- -}
|
|
|
|
CardOrd = NCard | NOrd ;
|
|
|
|
-- Order of magnitude
|
|
DForm =
|
|
Unit -- 0..10
|
|
| Teen -- 11..19
|
|
| Ten -- 20..99
|
|
| Hund -- 100..999
|
|
| Thou -- 1000+
|
|
;
|
|
|
|
-- Indicate how a corresponding object should be treated
|
|
--- Overlap between Num Sg and Num1, but leaving as is for now
|
|
NumForm =
|
|
Num Number -- Sg | Pl
|
|
| Num0 -- 0 (l-edba SIEGĦA)
|
|
| Num1 -- 1, 101... (SIEGĦA, mija u SIEGĦA)
|
|
| Num2 -- 2 (SAGĦTEJN)
|
|
| Num3_10 -- 3..10, 102, 103... (tlett SIEGĦAT, għaxar SIEGĦAT, mija u żewġ SIEGĦAT, mija u tlett SIEGĦAT)
|
|
| Num11_19 -- 11..19, 111... (ħdax-il SIEGĦA, mija u dsatax-il SIEGĦA)
|
|
| Num20_99 -- 20..99, 120... (għoxrin SIEGĦA, disa' u disgħajn SIEGĦA)
|
|
;
|
|
|
|
NumCase =
|
|
NumNom -- "Type B" in {MDG, 133}, e.g. TNEJN, ĦAMSA, TNAX, MIJA
|
|
| NumAdj -- "Type A" in {MDG, 133}, e.g. ŻEWĠ, ĦAMES, TNAX-IL, MITT
|
|
;
|
|
|
|
{- Determiners etc. ----------------------------------------------------- -}
|
|
|
|
oper
|
|
-- [AZ]
|
|
Determiner : Type = {
|
|
s : Gender => Str ;
|
|
n : NumForm ;
|
|
clitic : Str ;
|
|
hasNum : Bool ;
|
|
isPron : Bool ;
|
|
} ;
|
|
-- Determiner = {
|
|
-- s : NPCase => Gender => NumCase => Str ;
|
|
-- s2 : NPCase => Gender => Str ; -- tieghi (possessive pronoun)
|
|
-- -- size : Num_Size ; -- One (agreement feature for noun)
|
|
-- isNum : Bool ; -- True (a numeral is present)
|
|
-- isDemo : Bool ; -- True (is a demostrative)
|
|
-- isDefn : Bool ;-- True (is definite)
|
|
-- } ;
|
|
|
|
-- [AZ]
|
|
Quantifier : Type = {
|
|
s : GenNum => Str ;
|
|
clitic : Str ;
|
|
isPron : Bool ;
|
|
isDemo : Bool ; -- Demonstrative (this/that/those/these)
|
|
} ;
|
|
-- Quantifier = {
|
|
-- s : NPCase => Gender => NumForm => Str ;
|
|
-- s2 : NPCase => Gender => NumForm => Str ;
|
|
-- isDemo : Bool ; -- Demonstrative (this/that/those/these)
|
|
-- isDefn : Bool ;
|
|
-- } ;
|
|
|
|
{- Nouns ---------------------------------------------------------------- -}
|
|
|
|
oper
|
|
Noun : Type = {
|
|
s : Noun_Number => Str ;
|
|
g : Gender ;
|
|
hasColl : Bool ; -- has a collective form? e.g. BAQAR
|
|
hasDual : Bool ; -- has a dual form? e.g. SAGĦTEJN
|
|
takesPron : Bool ; -- takes enclitic pronon? e.g. MISSIERI
|
|
-- anim : Animacy ; -- is the noun animate? e.g. TABIB
|
|
} ;
|
|
|
|
ProperNoun : Type = {
|
|
s : Str ;
|
|
a : Agr ; -- ignore a.p (always P3)
|
|
} ;
|
|
|
|
NounPhrase : Type = {
|
|
s : NPCase => Str ;
|
|
a : Agr ;
|
|
isPron : Bool ;
|
|
} ;
|
|
|
|
param
|
|
Noun_Sg_Type =
|
|
Singulative -- eg ĦUTA
|
|
| Collective -- eg ĦUT
|
|
;
|
|
Noun_Pl_Type =
|
|
Determinate -- eg ĦUTIET
|
|
| Indeterminate -- eg ĦWIET
|
|
;
|
|
Noun_Number =
|
|
Singular Noun_Sg_Type -- eg ĦUTA / ĦUT
|
|
| Dual -- eg WIDNEJN
|
|
| Plural Noun_Pl_Type -- eg ĦUTIET / ĦWIET
|
|
;
|
|
|
|
{- Pronoun -------------------------------------------------------------- -}
|
|
|
|
oper
|
|
Pronoun = {
|
|
-- s : PronForm => {c1, c2: Str} ;
|
|
s : PronForm => Str ; -- cases like omm-i / hi-ja are handled elsewhere
|
|
a : Agr ;
|
|
} ;
|
|
|
|
param
|
|
PronForm =
|
|
Personal -- JIENA
|
|
| Possessive -- TIEGĦI
|
|
| Suffixed PronCase
|
|
;
|
|
|
|
PronCase =
|
|
Acc -- Accusative: rajtu
|
|
| Dat -- Dative: rajtlu
|
|
| Gen -- Genitive: qalbu
|
|
;
|
|
|
|
{- Verb ----------------------------------------------------------------- -}
|
|
|
|
oper
|
|
Verb : Type = {
|
|
s : VForm => Str ;
|
|
i : VerbInfo ;
|
|
} ;
|
|
|
|
VerbInfo : Type = {
|
|
class : VClass ;
|
|
form : VDerivedForm ;
|
|
root : Root ; -- radicals
|
|
patt : Pattern ; -- vowels extracted from mamma
|
|
patt2: Pattern ; -- vowel changes; default to patt (experimental)
|
|
-- in particular, patt2 is used to indicate whether an IE sould be shortened
|
|
-- to an I or an E (same for entire verb)
|
|
imp : Str ; -- Imperative Sg. Gives so much information jaħasra!
|
|
} ;
|
|
|
|
param
|
|
-- Possible verb forms (tense + person)
|
|
VForm =
|
|
VPerf VAgr -- Perfect tense in all pronoun cases
|
|
| VImpf VAgr -- Imperfect tense in all pronoun cases
|
|
| VImp Number -- Imperative is always P2, Sg & Pl
|
|
-- | VPresPart GenNum -- Present Particible for Gender/Number
|
|
-- | VPastPart GenNum -- Past Particible for Gender/Number
|
|
-- | VVerbalNoun -- Verbal Noun
|
|
;
|
|
|
|
VDerivedForm =
|
|
FormI
|
|
| FormII
|
|
| FormIII
|
|
| FormIV
|
|
| FormV
|
|
| FormVI
|
|
| FormVII
|
|
| FormVIII
|
|
| FormIX
|
|
| FormX
|
|
| FormUnknown
|
|
;
|
|
|
|
-- Verb classification
|
|
VClass =
|
|
Strong VStrongClass
|
|
| Weak VWeakClass
|
|
| Quad VQuadClass
|
|
| Loan
|
|
| Irregular
|
|
;
|
|
VStrongClass =
|
|
Regular
|
|
| LiquidMedial
|
|
| Geminated
|
|
;
|
|
VWeakClass =
|
|
Assimilative
|
|
| Hollow
|
|
| Lacking
|
|
| Defective
|
|
;
|
|
VQuadClass =
|
|
QStrong
|
|
| QWeak
|
|
;
|
|
|
|
oper
|
|
|
|
VerbParts : Type = { stem, dir, ind, pol : Str } ;
|
|
mkVParts = overload {
|
|
mkVParts : Str -> Str -> VerbParts = \a,d -> {stem=a; dir=[]; ind=[]; pol=d} ;
|
|
mkVParts : Str -> Str -> Str -> Str -> VerbParts = \a,b,c,d -> {stem=a; dir=b; ind=c; pol=d} ;
|
|
} ;
|
|
joinVParts : VerbParts -> Str = \vb -> vb.stem ++ vb.dir ++ vb.ind ++ vb.ind ;
|
|
|
|
-- [AZ]
|
|
VP : Type = {
|
|
s : VPForm => Anteriority => Polarity => VerbParts ; -- verb
|
|
s2 : Agr => Str ; -- complement
|
|
-- a1 : Str ;
|
|
-- a2 : Str ;
|
|
} ;
|
|
|
|
param
|
|
-- [AZ]
|
|
VPForm =
|
|
VPIndicat Tense VAgr
|
|
| VPImperat Number
|
|
;
|
|
|
|
oper
|
|
|
|
-- [AZ]
|
|
insertObj : (Agr => Str) -> VP -> VP = \obj,vp -> {
|
|
s = vp.s ;
|
|
s2 = obj ;
|
|
-- a1 = vp.a1 ;
|
|
-- a2 = vp.a2 ;
|
|
} ;
|
|
|
|
copula_kien = {
|
|
s : (VForm => Str) = table {
|
|
VPerf (AgP1 Sg) => "kont" ;
|
|
VPerf (AgP2 Sg) => "kont" ;
|
|
VPerf (AgP3Sg Masc) => "kien" ;
|
|
VPerf (AgP3Sg Fem) => "kienet" ;
|
|
VPerf (AgP1 Pl) => "konna" ;
|
|
VPerf (AgP2 Pl) => "kontu" ;
|
|
VPerf (AgP3Pl) => "kienu" ;
|
|
VImpf (AgP1 Sg) => "nkun" ;
|
|
VImpf (AgP2 Sg) => "tkun" ;
|
|
VImpf (AgP3Sg Masc) => "jkun" ;
|
|
VImpf (AgP3Sg Fem) => "tkun" ;
|
|
VImpf (AgP1 Pl) => "nkunu" ;
|
|
VImpf (AgP2 Pl) => "tkunu" ;
|
|
VImpf (AgP3Pl) => "jkunu" ;
|
|
VImp (Pl) => "kun" ;
|
|
VImp (Sg) => "kunu"
|
|
} ;
|
|
i : VerbInfo = mkVerbInfo (Irregular) (FormI) (mkRoot "k-w-n") (mkPattern "ie") ;
|
|
} ;
|
|
|
|
-- Adapted from [AZ]
|
|
CopulaVP : VP = {
|
|
s = \\vpf,ant,pol =>
|
|
case <vpf> of {
|
|
<VPIndicat Past vagr> => polarise (copula_kien.s ! VPerf vagr) pol ;
|
|
<VPIndicat Pres vagr> => polarise (copula_kien.s ! VImpf vagr) pol ;
|
|
<VPImperat num> => polarise (copula_kien.s ! VImp num) pol ;
|
|
_ => Predef.error "tense not implemented"
|
|
} ;
|
|
s2 = \\agr => [] ;
|
|
} where {
|
|
polarise : Str -> Polarity -> VerbParts = \s,pol ->
|
|
mkVParts s (case pol of { Neg => BIND ++ "x" ; _ => [] }) ;
|
|
} ;
|
|
|
|
-- [AZ]
|
|
predV : Verb -> VP = \verb -> {
|
|
s = \\vpf,ant,pol =>
|
|
let
|
|
ma = "ma" ;
|
|
mhux = "mhux" ;
|
|
b1 : Str -> VerbParts = \s -> mkVParts s [] ;
|
|
b2 : Str -> VerbParts = \s -> mkVParts s (BIND ++ "x") ;
|
|
in
|
|
case vpf of {
|
|
VPIndicat tense vagr =>
|
|
let
|
|
kien = joinVParts (CopulaVP.s ! VPIndicat Past vagr ! Simul ! pol) ;
|
|
in
|
|
case <tense,ant,pol> of {
|
|
<Pres,Simul,Pos> => b1 (verb.s ! VImpf vagr) ; -- norqod
|
|
<Pres,Anter,Pos> => b1 (kien ++ verb.s ! VImpf vagr) ; -- kont norqod
|
|
<Past,Simul,Pos> => b1 (verb.s ! VPerf vagr) ; -- rqadt
|
|
<Past,Anter,Pos> => b1 (kien ++ verb.s ! VPerf vagr) ; -- kont rqadt
|
|
<Fut, Simul,Pos> => b1 ("se" ++ verb.s ! VImpf vagr) ; -- se norqod
|
|
<Fut, Anter,Pos> => b1 (kien ++ "se" ++ verb.s ! VImpf vagr) ; -- kont se norqod
|
|
|
|
<Pres,Simul,Neg> => b2 (ma ++ verb.s ! VImpf vagr) ; -- ma norqodx
|
|
<Pres,Anter,Neg> => b1 (ma ++ kien ++ verb.s ! VImpf vagr) ; -- ma kontx norqod
|
|
<Past,Simul,Neg> => b2 (ma ++ verb.s ! VPerf vagr) ; -- ma rqadtx
|
|
<Past,Anter,Neg> => b1 (ma ++ kien ++ verb.s ! VPerf vagr) ; -- ma kontx rqadt
|
|
<Fut, Simul,Neg> => b1 (mhux ++ "se" ++ verb.s ! VImpf vagr) ; -- mhux se norqod
|
|
<Fut, Anter,Neg> => b1 (ma ++ kien ++ "se" ++ verb.s ! VImpf vagr) ; -- ma kontx se norqod
|
|
|
|
<Cond,_,Pos> => b1 (kien ++ verb.s ! VImpf vagr) ; -- kont norqod
|
|
<Cond,_,Neg> => b1 (ma ++ kien ++ verb.s ! VImpf vagr) -- ma kontx norqod
|
|
} ;
|
|
VPImperat num => b2 (verb.s ! VImp num) -- torqodx
|
|
};
|
|
s2 = \\agr => [] ;
|
|
-- a1 = [] ;
|
|
-- n2 = \\_ => [] ;
|
|
-- a2 = [] ;
|
|
} ;
|
|
|
|
{- Adjective ------------------------------------------------------------ -}
|
|
|
|
oper
|
|
Adjective : Type = {
|
|
s : AForm => Str ;
|
|
} ;
|
|
|
|
param
|
|
AForm =
|
|
APosit GenNum
|
|
| ACompar
|
|
| ASuperl
|
|
;
|
|
|
|
{- Other ---------------------------------------------------------------- -}
|
|
|
|
oper
|
|
|
|
{- ~~~ Some character classes ~~~ -}
|
|
|
|
Letter : pattern Str = #( "a" | "b" | "ċ" | "d" | "e" | "f" | "ġ" | "g" | "għ" | "h" | "ħ" | "i" | "ie" | "j" | "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" | "s" | "t" | "u" | "v" | "w" | "x" | "ż" | "z" );
|
|
Consonant : pattern Str = #( "b" | "ċ" | "d" | "f" | "ġ" | "g" | "għ" | "h" | "ħ" | "j" | "k" | "l" | "m" | "n" | "p" | "q" | "r" | "s" | "t" | "v" | "w" | "x" | "ż" | "z" );
|
|
CoronalCons : pattern Str = #( "ċ" | "d" | "n" | "r" | "s" | "t" | "x" | "ż" | "z" ); -- "konsonanti xemxin"
|
|
LiquidCons : pattern Str = #( "l" | "m" | "n" | "r" | "għ" );
|
|
SonorantCons : pattern Str = #( "l" | "m" | "n" | "r" ); -- See {SA pg13}. Currently unused, but see DoublingConsN below
|
|
DoublingConsT : pattern Str = #( "ċ" | "d" | "ġ" | "s" | "x" | "ż" | "z" ); -- require doubling when prefixed with 't', eg DDUM, ĠĠORR, SSIB, TTIR, ŻŻID {GM pg68,2b} {OM pg90}
|
|
DoublingConsN : pattern Str = #( "l" | "m" | "r" ); -- require doubling when prefixed with 'n', eg LLAĦĦAQ, MMUR, RRID {OM pg90}
|
|
StrongCons : pattern Str = #( "b" | "ċ" | "d" | "f" | "ġ" | "g" | "għ" | "h" | "ħ" | "k" | "l" | "m" | "n" | "p" | "q" | "r" | "s" | "t" | "v" | "x" | "ż" | "z" );
|
|
WeakCons : pattern Str = #( "j" | "w" );
|
|
Vowel : pattern Str = #( "a" | "e" | "i" | "o" | "u" );
|
|
VowelIE : pattern Str = #( "a" | "e" | "i" | "ie" | "o" | "u" );
|
|
Digraph : pattern Str = #( "ie" );
|
|
SemiVowel : pattern Str = #( "għ" | "j" );
|
|
|
|
Vwl = Vowel ;
|
|
Cns = Consonant ;
|
|
LCns = LiquidCons ;
|
|
|
|
EorI : Str = "e" | "i" ;
|
|
IorE : Str = "i" | "e" ;
|
|
|
|
{- ~~~ Roots & Patterns ~~~ -}
|
|
|
|
Pattern : Type = {V1, V2 : Str} ;
|
|
Root : Type = {C1, C2, C3, C4 : Str} ;
|
|
|
|
-- Make a root object. Accepts following overloads:
|
|
-- mkoot (empty root)
|
|
-- mkRoot "k-t-b" / mkRoot "k-t-b-l"
|
|
-- mkRoot "k" "t" "b"
|
|
-- mkRoot "k" "t" "b" "l"
|
|
mkRoot : Root = overload {
|
|
mkRoot : Root =
|
|
{ C1=[] ; C2=[] ; C3=[] ; C4=[] } ;
|
|
mkRoot : Str -> Root = \s ->
|
|
case toLower s of {
|
|
c1 + "-" + c2 + "-" + c3 + "-" + c4 => { C1=c1 ; C2=c2 ; C3=c3 ; C4=c4 } ; -- "k-t-b-l"
|
|
c1 + "-" + c2 + "-" + c3 => { C1=c1 ; C2=c2 ; C3=c3 ; C4=[] } ; -- "k-t-b"
|
|
_ => Predef.error("Cannot make root from:"++s)
|
|
} ;
|
|
mkRoot : Str -> Str -> Str -> Root = \c1,c2,c3 ->
|
|
{ C1=toLower c1 ; C2=toLower c2 ; C3=toLower c3 ; C4=[] } ;
|
|
mkRoot : Str -> Str -> Str -> Str -> Root = \c1,c2,c3,c4 ->
|
|
{ C1=toLower c1 ; C2=toLower c2 ; C3=toLower c3 ; C4=toLower c4 } ;
|
|
} ;
|
|
|
|
mkPattern : Pattern = overload {
|
|
mkPattern : Pattern =
|
|
{ V1=[] ; V2=[] } ;
|
|
mkPattern : Str -> Pattern = \v1 ->
|
|
{ V1=toLower v1 ; V2=[] } ;
|
|
mkPattern : Str -> Str -> Pattern = \v1,v2 ->
|
|
{ V1=toLower v1 ; V2=case v2 of {"" => [] ; _ => toLower v2}} ;
|
|
} ;
|
|
|
|
-- Extract first two vowels from a token (designed for semitic verb forms)
|
|
--- potentially slow
|
|
extractPattern : Str -> Pattern = \s ->
|
|
case s of {
|
|
v1@"ie" + _ + v2@#Vowel + _ => mkPattern v1 v2 ; -- IEQAF
|
|
v1@#Vowel + _ + v2@#Vowel + _ => mkPattern v1 v2 ; -- IKTEB
|
|
_ + v1@"ie" + _ + v2@#Vowel + _ => mkPattern v1 v2 ; -- RIEQED
|
|
_ + v1@"ie" + _ => mkPattern v1 ; -- ŻIED
|
|
_ + v1@#Vowel + _ + v2@#Vowel + _ => mkPattern v1 v2 ; -- ĦARBAT
|
|
_ + v1@#Vowel + _ => mkPattern v1 ; -- ĦOBB
|
|
_ => mkPattern
|
|
} ;
|
|
|
|
-- Create a VerbInfo record, optionally omitting various fields
|
|
mkVerbInfo : VerbInfo = overload {
|
|
mkVerbInfo : VClass -> VDerivedForm -> VerbInfo = \c,f ->
|
|
{ class=c ; form=f ; root=mkRoot ; patt=mkPattern ; patt2=mkPattern ; imp=[] } ;
|
|
mkVerbInfo : VClass -> VDerivedForm -> Str -> VerbInfo = \c,f,i ->
|
|
{ class=c ; form=f ; root=mkRoot ; patt=mkPattern ; patt2=mkPattern ; imp=i } ;
|
|
mkVerbInfo : VClass -> VDerivedForm -> Root -> Pattern -> VerbInfo = \c,f,r,p ->
|
|
{ class=c ; form=f ; root=r ; patt=p ; patt2=p ; imp=[] } ;
|
|
mkVerbInfo : VClass -> VDerivedForm -> Root -> Pattern -> Str -> VerbInfo = \c,f,r,p,i ->
|
|
{ class=c ; form=f ; root=r ; patt=p ; patt2=p ; imp=i } ;
|
|
mkVerbInfo : VClass -> VDerivedForm -> Root -> Pattern -> Pattern -> Str -> VerbInfo = \c,f,r,p,p2,i ->
|
|
{ class=c ; form=f ; root=r ; patt=p ; patt2=p2 ; imp=i } ;
|
|
} ;
|
|
|
|
-- Change certain fields of a VerbInfo record
|
|
updateVerbInfo : VerbInfo = overload {
|
|
|
|
-- Root
|
|
updateVerbInfo : VerbInfo -> Root -> VerbInfo = \i,r ->
|
|
{ class=i.class ; form=i.form ; root=r ; patt=i.patt ; patt2=i.patt2 ; imp=i.imp } ;
|
|
|
|
-- DerivedForm
|
|
updateVerbInfo : VerbInfo -> VDerivedForm -> VerbInfo = \i,f ->
|
|
{ class=i.class ; form=f ; root=i.root ; patt=i.patt ; patt2=i.patt2 ; imp=i.imp } ;
|
|
|
|
-- DerivedForm, Imperative
|
|
updateVerbInfo : VerbInfo -> VDerivedForm -> Str -> VerbInfo = \i,f,imp ->
|
|
{ class=i.class ; form=f ; root=i.root ; patt=i.patt ; patt2=i.patt2 ; imp=imp } ;
|
|
|
|
} ;
|
|
|
|
|
|
{- ~~~ Conversions ~~~ -}
|
|
|
|
numform2nounnum : NumForm -> Noun_Number = \n ->
|
|
case n of {
|
|
Num Sg => Singular Singulative ;
|
|
Num Pl => Plural Indeterminate ;
|
|
Num0 => Singular Singulative ;
|
|
Num1 => Singular Singulative ;
|
|
Num2 => Dual ;
|
|
Num3_10 => Singular Collective ;
|
|
Num11_19 => Singular Singulative ;
|
|
Num20_99 => Plural Indeterminate
|
|
} ;
|
|
|
|
{- ~~~ Useful helper functions ~~~ -}
|
|
|
|
-- Non-existant form
|
|
--- If changed, also see: MorphoMlt.verbPolarityTable
|
|
noexist : Str = "NOEXIST" ;
|
|
|
|
-- New names for the drop/take operations
|
|
--- dependent on defn of ResMlt.noexist
|
|
takePfx : Int -> Str -> Str = \n,s -> case s of { "NOEXIST" => noexist ; _ => Predef.take n s } ;
|
|
dropPfx : Int -> Str -> Str = \n,s -> case s of { "NOEXIST" => noexist ; _ => Predef.drop n s } ;
|
|
takeSfx : Int -> Str -> Str = \n,s -> case s of { "NOEXIST" => noexist ; _ => Predef.dp n s } ;
|
|
dropSfx : Int -> Str -> Str = \n,s -> case s of { "NOEXIST" => noexist ; _ => Predef.tk n s } ;
|
|
-- takePfx = Predef.take ;
|
|
-- dropPfx = Predef.drop ;
|
|
-- takeSfx = Predef.dp ;
|
|
-- dropSfx = Predef.tk ;
|
|
|
|
-- Get the character at the specific index (0-based).
|
|
-- Negative indices behave as 0 (first character). Out of range indexes return the empty string.
|
|
charAt : Int -> Str -> Str ;
|
|
charAt i s = takePfx 1 (dropPfx i s) ;
|
|
|
|
-- Delete character at the specific index (0-based).
|
|
-- Out of range indices are just ignored.
|
|
delCharAt : Int -> Str -> Str ;
|
|
delCharAt i s = (takePfx i s) + (dropPfx (plus i 1) s) ;
|
|
|
|
-- -- Replace first substring
|
|
-- replace : Str -> Str -> Str -> Str ;
|
|
-- replace needle haystack replacement =
|
|
-- case haystack of {
|
|
-- x + needle + y => x + replacement + y ;
|
|
-- _ => haystack
|
|
-- } ;
|
|
|
|
-- Prefix with a 'n'/'t' or double initial consonant, as necessary. See {OM pg 90}
|
|
pfx_N : Str -> Str = \s -> case s of {
|
|
"" => [] ;
|
|
"NOEXIST" => noexist ; --- dependent on defn of ResMlt.noexist
|
|
m@#DoublingConsN + _ => m + s ;
|
|
_ => "n" + s
|
|
} ;
|
|
pfx_T : Str -> Str = \s -> case s of {
|
|
"" => [] ;
|
|
"NOEXIST" => noexist ; --- dependent on defn of ResMlt.noexist
|
|
d@#DoublingConsT + _ => d + s ;
|
|
_ => "t" + s
|
|
} ;
|
|
pfx_J : Str -> Str = \s -> pfx "j" s ;
|
|
|
|
-- Generically prefix a string (avoiding empty strings)
|
|
pfx : Str -> Str -> Str = \p,s -> case <p,s> of {
|
|
<_, ""> => [] ;
|
|
<"", str> => str ;
|
|
<_, "NOEXIST"> => noexist ; --- dependent on defn of ResMlt.noexist
|
|
<"NOEXIST", str> => str ; --- dependent on defn of ResMlt.noexist
|
|
<px, str> => px + str
|
|
} ;
|
|
|
|
-- Add suffix, avoiding triple letters {GO pg96-7}
|
|
--- add more cases?
|
|
--- potentially slow
|
|
sfx : Str -> Str -> Str = \a,b ->
|
|
case <a,takePfx 1 b> of {
|
|
<"",_> => [] ;
|
|
<"NOEXIST",_> => noexist ; --- dependent on defn of ResMlt.noexist
|
|
<ke+"nn","n"> => ke+"n"+b ;
|
|
<ha+"kk","k"> => ha+"k"+b ;
|
|
<ho+"ll","l"> => ho+"l"+b ;
|
|
<si+"tt","t"> => si+"t"+b ;
|
|
<be+"xx","x"> => be+"x"+b ;
|
|
_ => a + b
|
|
} ;
|
|
|
|
-- Replace any IE in the word with an I or E --- potentially slow
|
|
ie2i : Str -> Str = ie2_ "i" ;
|
|
ie2e : Str -> Str = ie2_ "e" ;
|
|
ie2_ : Str -> Str -> Str = \iore,serviet ->
|
|
case serviet of {
|
|
x + "ie" => x + iore ;
|
|
x + "ie" + y => x + iore + y ;
|
|
x => x
|
|
} ;
|
|
|
|
-- Is a word mono-syllabic?
|
|
--- potentially slow
|
|
isMonoSyl : Str -> Bool = \s ->
|
|
case s of {
|
|
#Consonant + ("ie" | #Vowel) => True ; -- ra
|
|
#Consonant + #Consonant + ("ie" | #Vowel) => True ; -- bla
|
|
|
|
("ie" | #Vowel) + #Consonant => True ; -- af
|
|
("ie" | #Vowel) + #Consonant + #Consonant => True ; -- elf
|
|
|
|
#Consonant + ("ie" | #Vowel) + #Consonant => True ; -- miet
|
|
#Consonant + ("ie" | #Vowel) + #Consonant + #Consonant => True ; -- mort
|
|
#Consonant + #Consonant + ("ie" | #Vowel) + #Consonant => True ; -- ħliet
|
|
#Consonant + #Consonant + ("ie" | #Vowel) + #Consonant + #Consonant => True ; -- ħriġt
|
|
_ => False
|
|
} ;
|
|
|
|
|
|
-- Add a definite preposition in front of your token
|
|
addDefinitePreposition : Str -> Str -> Str = \prep,n -> (getDefinitePreposition prep n) ++ n ;
|
|
addDefiniteArticle = addDefinitePreposition "il" ;
|
|
getDefiniteArticle = getDefinitePreposition "il" ;
|
|
|
|
-- Correctly inflect definite preposition
|
|
-- A more generic version of getDefiniteArticle
|
|
-- Params:
|
|
-- preposition (eg TAL, MAL, BĦALL)
|
|
-- noun
|
|
-- NOTE trying to call this with a runtime string will cause a world of pain. Design around it.
|
|
getDefinitePreposition : Str -> Str -> Str = \prep,noun ->
|
|
let
|
|
-- Remove either 1 or 2 l's
|
|
prepStem : Str = case prep of {
|
|
_ + "ll" => Predef.tk 2 prep ;
|
|
_ + "l" => Predef.tk 1 prep ;
|
|
_ => prep -- this should never happen, I don't think
|
|
}
|
|
in
|
|
case noun of {
|
|
("s"|#LiquidCons) + #Consonant + _ => prep + "-i" ; -- L-ISKOLA
|
|
("għ" | #Vowel) + _ => case prep of { -- L-GĦATBA...
|
|
("fil"|"bil") => (Predef.take 1 prep) + "l-" ;
|
|
"il" => "l" + "-" ;
|
|
_ => prep + "-"
|
|
};
|
|
K@#CoronalCons + _ => prepStem + K + "-" ; -- IĊ-ĊISK
|
|
#Consonant + _ => prep + "-" ; -- IL-QADDIS
|
|
_ => [] -- ?
|
|
} ;
|
|
|
|
artIndef : Str = "" ;
|
|
|
|
artDef : Str =
|
|
pre {
|
|
"il- &+" ; --- ugly hack! but won't let me use ++
|
|
"l-" ++ BIND / strs { "a" ; "e" ; "i" ; "o" ; "u" ; "h" ; "għ" } ;
|
|
"iċ-" ++ BIND / strs { "ċ" } ;
|
|
"id-" ++ BIND / strs { "d" } ;
|
|
"in-" ++ BIND / strs { "n" } ;
|
|
"ir-" ++ BIND / strs { "r" } ;
|
|
"is-" ++ BIND / strs { "s" } ;
|
|
"it-" ++ BIND / strs { "t" } ;
|
|
"ix-" ++ BIND / strs { "x" } ;
|
|
"iż-" ++ BIND / strs { "ż" } ;
|
|
"iz-" ++ BIND / strs { "z" }
|
|
} ;
|
|
|
|
{- ~~~ Worst-case functions ~~~ -}
|
|
|
|
-- Noun: Takes all forms and a gender
|
|
-- Params:
|
|
-- Singulative, eg KOXXA
|
|
-- Collective, eg KOXXOX
|
|
-- Double, eg KOXXTEJN
|
|
-- Determinate Plural, eg KOXXIET
|
|
-- Indeterminate Plural
|
|
-- Gender
|
|
mkNoun : (_,_,_,_,_ : Str) -> Gender -> Noun = \sing,coll,dual,det,ind,gen -> {
|
|
s = table {
|
|
Singular Singulative => sing ;
|
|
Singular Collective => coll ;
|
|
Dual => dual ;
|
|
Plural Determinate => det ;
|
|
Plural Indeterminate => ind
|
|
} ;
|
|
g = gen ;
|
|
takesPron = False ;
|
|
hasDual = notB (isNil dual) ;
|
|
hasColl = notB (isNil coll) ;
|
|
-- anim = Inanimate ;
|
|
} ;
|
|
|
|
-- adjective: Takes all forms (except superlative)
|
|
-- Params:
|
|
-- Masculine, eg SABIĦ
|
|
-- Feminine, eg SABIĦA
|
|
-- Plural, eg SBIEĦ
|
|
-- Comparative, eg ISBAĦ
|
|
mkAdjective : (_,_,_,_ : Str) -> Adjective = \masc,fem,plural,compar -> {
|
|
s = table {
|
|
APosit gn => case gn of {
|
|
GSg Masc => masc ;
|
|
GSg Fem => fem ;
|
|
GPl => plural
|
|
} ;
|
|
ACompar => compar ;
|
|
ASuperl => addDefiniteArticle compar
|
|
} ;
|
|
} ;
|
|
|
|
}
|
|
|