From 1f3a35a95c2a2f27e9c462fc028a29f384f75aef Mon Sep 17 00:00:00 2001 From: Inari Listenmaa Date: Fri, 15 Aug 2025 20:40:33 +0200 Subject: [PATCH 01/15] start Gla by cloning the template --- src/gaelic/AdjectiveGla.gf | 68 ++++++ src/gaelic/AdverbGla.gf | 39 ++++ src/gaelic/AllGla.gf | 6 + src/gaelic/CatGla.gf | 121 ++++++++++ src/gaelic/ConjunctionGla.gf | 147 ++++++++++++ src/gaelic/ConstructionGla.gf | 117 ++++++++++ src/gaelic/ExtendGla.gf | 35 +++ src/gaelic/GrammarGla.gf | 17 ++ src/gaelic/IdiomGla.gf | 56 +++++ src/gaelic/LangGla.gf | 5 + src/gaelic/LexiconGla.gf | 419 ++++++++++++++++++++++++++++++++++ src/gaelic/MissingGla.gf | 313 +++++++++++++++++++++++++ src/gaelic/NamesGla.gf | 36 +++ src/gaelic/NounGla.gf | 210 +++++++++++++++++ src/gaelic/NumeralGla.gf | 115 ++++++++++ src/gaelic/ParadigmsGla.gf | 211 +++++++++++++++++ src/gaelic/PhraseGla.gf | 27 +++ src/gaelic/QuestionGla.gf | 105 +++++++++ src/gaelic/RelativeGla.gf | 24 ++ src/gaelic/ResGla.gf | 275 ++++++++++++++++++++++ src/gaelic/SentenceGla.gf | 76 ++++++ src/gaelic/StructuralGla.gf | 171 ++++++++++++++ src/gaelic/SymbolGla.gf | 73 ++++++ src/gaelic/VerbGla.gf | 114 +++++++++ 24 files changed, 2780 insertions(+) create mode 100644 src/gaelic/AdjectiveGla.gf create mode 100644 src/gaelic/AdverbGla.gf create mode 100644 src/gaelic/AllGla.gf create mode 100644 src/gaelic/CatGla.gf create mode 100644 src/gaelic/ConjunctionGla.gf create mode 100644 src/gaelic/ConstructionGla.gf create mode 100644 src/gaelic/ExtendGla.gf create mode 100644 src/gaelic/GrammarGla.gf create mode 100644 src/gaelic/IdiomGla.gf create mode 100644 src/gaelic/LangGla.gf create mode 100644 src/gaelic/LexiconGla.gf create mode 100644 src/gaelic/MissingGla.gf create mode 100644 src/gaelic/NamesGla.gf create mode 100644 src/gaelic/NounGla.gf create mode 100644 src/gaelic/NumeralGla.gf create mode 100644 src/gaelic/ParadigmsGla.gf create mode 100644 src/gaelic/PhraseGla.gf create mode 100644 src/gaelic/QuestionGla.gf create mode 100644 src/gaelic/RelativeGla.gf create mode 100644 src/gaelic/ResGla.gf create mode 100644 src/gaelic/SentenceGla.gf create mode 100644 src/gaelic/StructuralGla.gf create mode 100644 src/gaelic/SymbolGla.gf create mode 100644 src/gaelic/VerbGla.gf diff --git a/src/gaelic/AdjectiveGla.gf b/src/gaelic/AdjectiveGla.gf new file mode 100644 index 00000000..39c79158 --- /dev/null +++ b/src/gaelic/AdjectiveGla.gf @@ -0,0 +1,68 @@ +concrete AdjectiveGla of Adjective = CatGla ** open ResGla, Prelude in { + + flags optimize=all_subs ; + + lin + + -- : AP -> Adv -> AP ; -- warm by nature + AdvAP ap adv = ap ** { + s = ap.s ++ adv.s ; + } ; + + -- : A -> AP ; + PositA a = a ** { + compar = [] ; + } ; + + -- : A -> NP -> AP ; + ComparA a np = a ** { + compar = np.s + } ; + + -- : A2 -> NP -> AP ; -- married to her + -- ComplA2 a2 np = a2 ** { } ; + + -- : A2 -> AP ; -- married to itself + -- ReflA2 a2 = a2 ** { } ; + + -- : A2 -> AP ; -- married + UseA2 = PositA ; + + -- : A -> AP ; -- warmer + -- UseComparA a = a ** { + -- s = \\af => "???" ++ a.s ! af ; + -- compar = [] + -- } ; + + + -- : CAdv -> AP -> NP -> AP ; -- as cool as John + -- CAdvAP adv ap np = ap ** { } ; + +-- The superlative use is covered in $Ord$. + + -- : Ord -> AP ; -- warmest + -- AdjOrd ord = ord ** { + -- compar = [] + -- } ; + -- AdjOrd : Ord -> AP = + AdjOrd ord = ord ; + +-- Sentence and question complements defined for all adjectival +-- phrases, although the semantics is only clear for some adjectives. + + -- : AP -> SC -> AP ; -- good that she is here + -- SentAP ap sc = ap ** { + -- s = \\af => ap.s ! af ++ sc.s + -- } ; + +-- An adjectival phrase can be modified by an *adadjective*, such as "very". + + -- : AdA -> AP -> AP ; + -- AdAP ada ap = ap ** { } ; + + +-- It can also be postmodified by an adverb, typically a prepositional phrase. + + + +} diff --git a/src/gaelic/AdverbGla.gf b/src/gaelic/AdverbGla.gf new file mode 100644 index 00000000..dd89e853 --- /dev/null +++ b/src/gaelic/AdverbGla.gf @@ -0,0 +1,39 @@ +concrete AdverbGla of Adverb = CatGla ** open ResGla, ParadigmsGla, Prelude in { +{- +lin + + -- : A -> Adv ; + PositAdvAdj adj = + + -- : CAdv -> A -> NP -> Adv ; -- more warmly than John + ComparAdvAdj cadv a np = + + -- : CAdv -> A -> S -> Adv ; -- more warmly than he runs + ComparAdvAdjS cadv a s = + + -- : Prep -> NP -> Adv ; + PrepNP prep np = ; + +-- Adverbs can be modified by 'adadjectives', just like adjectives. + + -- : AdA -> Adv -> Adv ; -- very quickly + AdAdv ada adv = adv ** + +-- Like adverbs, adadjectives can be produced by adjectives. + + -- : A -> AdA ; -- extremely + PositAdAAdj a = + + -- Subordinate clauses can function as adverbs. + + -- : Subj -> S -> Adv ; + SubjS subj s = {s = subj.s ++ s.s} ; + +-- Comparison adverbs also work as numeral adverbs. + + -- : CAdv -> AdN ; -- less (than five) + AdnCAdv cadv = ; + +-} + +} diff --git a/src/gaelic/AllGla.gf b/src/gaelic/AllGla.gf new file mode 100644 index 00000000..29b533cb --- /dev/null +++ b/src/gaelic/AllGla.gf @@ -0,0 +1,6 @@ +--# -path=.:../abstract:../common:../prelude + +concrete AllGla of AllGlaAbs = + LangGla, + ExtendGla + ; diff --git a/src/gaelic/CatGla.gf b/src/gaelic/CatGla.gf new file mode 100644 index 00000000..a8032fe9 --- /dev/null +++ b/src/gaelic/CatGla.gf @@ -0,0 +1,121 @@ +concrete CatGla of Cat = CommonX ** open ResGla, Coordination, Prelude in { + + flags optimize=all_subs ; + + lincat + +--2 Sentences and clauses +-- Constructed in SentenceGla, and also in IdiomGla + S = SS ; + QS = SS ; + RS = SS ; + -- relative sentence. Tense and polarity fixed, + -- but agreement may depend on the CN/NP it modifies. + + Cl = ResGla.LinCl ; + ClSlash = SS ; + SSlash = SS ; -- sentence missing NP; e.g. "she has looked at" + Imp = SS ; -- imperative e.g. "look at this" + +--2 Questions and interrogatives + +-- Constructed in QuestionGla. + QCl = SS ; + IComp = SS ; -- interrogative complement of copula e.g. "where" + IDet = SS ; -- interrogative determiner e.g. "how many" + IQuant = SS ; -- interrogative quantifier e.g. "which" + IP = SS ; -- interrogative pronoun e.g. "who" + +--2 Subord clauses and pronouns + + RCl = SS ; + RP = SS ; + +--2 Verb phrases + +-- Constructed in VerbGla. + VP = ResGla.LinVP ; + VPSlash = SS ; + Comp = SS ; + +--2 Adjectival phrases + +-- Constructed in AdjectiveGla. + AP = SS ; + +--2 Nouns and noun phrases + +-- Constructed in NounGla. +-- Many atomic noun phrases e.g. "everybody" +-- are constructed in StructuralGla. + + CN = ResGla.LinCN ; + NP = ResGla.LinNP ; + Pron = SS ; -- NB. Pronouns need enough info to become NP or Quant. + Det = ResGla.LinDet ; -- s : Str , n : Number + Predet = SS ; + Quant = ResGla.LinQuant ; -- s : Number => Str + Num = ResGla.LinDet ; + Card = ResGla.LinDet ; + ACard = SS ; + Ord = SS ; + DAP = SS ; + + +--2 Numerals + +-- Constructed in NumeralGla. + + Numeral = ResGla.LinNumeral ; + Digits = ResGla.LinNumeral ; + +--2 Structural words + +-- Constructed in StructuralGla. + Conj = Coordination.ConjunctionDistr ** { + n : Number -- The number of the NP that results from + -- coordinating a list of NPs with that Conj. + } ; -- "[Ann and Bob] are children" → and_Conj.n = Pl + Subj = SS ; + Prep = SS ; + + + +--2 Words of open classes + +-- These are constructed in LexiconGla and in +-- additional lexicon modules. + + -- TODO: eventually different lincats + VS, -- sentence-complement verb e.g. "claim" + VQ, -- question-complement verb e.g. "wonder" + VA, -- adjective-complement verb e.g. "look" + V = ResGla.LinV ; + + VV -- verb-phrase-complement verb e.g. "want" + = SS ; + + V2A, -- verb with NP and AP complement e.g. "paint" + V2V, -- verb with NP and V complement e.g. "cause" + V2S, -- verb with NP and S complement e.g. "tell" + V2Q, -- verb with NP and Q complement e.g. "ask" + V2 = SS ; + V3 = SS ; + + A = SS ; + A2 = SS ; + + N = ResGla.LinN ; + N2 = ResGla.LinN ; + N3 = ResGla.LinN ; + PN = SS ; + + -- From the Names module, not in the official API as of 2023-08 + GN = SS ; -- Given name, e.g. "George" + SN = SS ; -- Second name, e.g. "Washington" + LN = SS ; -- Location name, e.g. "Sweden" + + linref + Cl = linCl ; + +} diff --git a/src/gaelic/ConjunctionGla.gf b/src/gaelic/ConjunctionGla.gf new file mode 100644 index 00000000..7191a485 --- /dev/null +++ b/src/gaelic/ConjunctionGla.gf @@ -0,0 +1,147 @@ +concrete ConjunctionGla of Conjunction = + CatGla ** open ResGla, Coordination, Prelude in { + + flags optimize=all_subs ; + + {- Conjunction for category X needs four things: + lincat [X] + lin BaseX + lin ConsX + lin ConjX + + For example, if X is defined as + + lincat X = {s : Number => Str ; g : Gender} ; + + then [X] will split its s field into two, and retain its other fields as is: + + lincat [X] = {s1,s2 : Number => Str ; g : Gender} ; + + Let us look at a simple case: Adv is of type {s : Str} + Then [Adv] is {s1,s2 : Str}. + BaseAdv, ConsAdv and ConjAdv can all use functions defined in prelude/Coordination: + + BaseAdv = twoSS ; + ConsAdv = consrSS comma ; + ConjAdv = conjunctSS ; + + --} + +----------------------------------------------------------------------------- +-- Adverb and other simple {s : Str} types. +lincat + [Adv],[AdV],[IAdv] = {s1,s2 : Str} ; + +lin + BaseAdv, BaseAdV, BaseIAdv = twoSS ; + ConsAdv, ConsAdV, ConsIAdv = consrSS comma ; + ConjAdv, ConjAdV, ConjIAdv = conjunctDistrSS ; + +{- + +----------------------------------------------------------------------------- +-- S is sometimes already {s : Str}, sometimes open for mood or word order. +-- Simply take the lincat of S, and split the s field into s1 and s2. +-- Then make sure that all of the other fields are retained. + +lincat + [S] = {s1, s2 : …} ; + +lin + -- : S -> S -> ListS ; -- John walks, Mary runs + BaseS x y = + + -- : S -> ListS -> ListS ; -- John walks, Mary runs, Bill swims + ConsS x xs = + + -- : Conj -> ListS -> S ; -- he walks and she runs + ConjS conj xs = + +----------------------------------------------------------------------------- +-- RS is variable on … and has inherent … +-- RS can modify CNs, which are open for …, and have inherent … + +lincat + [RS] = {s1,s2 : … => Str} ; + +lin + + -- : RS -> RS -> ListRS ; -- who walks, whom I know + BaseRS x y = + + -- : RS -> ListRS -> ListRS ; -- who wals, whom I know, who is here + ConsRS x xs = + + -- : Conj -> ListRS -> RS ; -- who walks and whose mother runs + ConjRS conj xs = + + +----------------------------------------------------------------------------- +-- NP is variable on … and has inherent … + +lincat + [NP] = {s1, s2 : …} ; + +lin + -- : NP -> NP -> ListNP ; -- John, Mary + BaseNP x y = + + -- : NP -> ListNP -> ListNP ; -- John, Mary, Bill + ConsNP x xs = + + -- : Conj -> ListNP -> NP ; -- she or we + ConjNP conj xs = + +----------------------------------------------------------------------------- +-- AP is variable on … and has an inherent … + +lincat + [AP] = {s1, s2 : …} ; + +lin + -- : AP -> AP -> ListAP ; -- red, white + BaseAP x y = + + -- : AP -> ListAP -> ListAP ; -- red, white, blue + ConsAP x xs = + + -- : Conj -> ListAP -> AP ; -- cold and warm + ConjAP conj xs = + +----------------------------------------------------------------------------- +-- CN is variable on … +-- CN conjunction is not in the API, so this can be lower prio + +lincat + [CN] = {s1, s2 : …} ; + +lin + -- : CN -> CN -> ListCN ; -- man, woman + BaseCN x y = + + -- : CN -> ListCN -> ListCN ; -- man, woman, child + ConsCN x xs = + + -- : Conj -> ListCN -> CN ; -- man and woman + ConjCN conj xs = + +----------------------------------------------------------------------------- +-- Det and DAP +-- Note that there is no [Det], the way to coordinate Dets is to make them +-- into DAP first, using Noun.DetDAP : Det -> DAP ; +-- DAP ("three small") isn't used in any API functions, so lower prio. + +lincat + [DAP] = {s1, s2 : …} ; + +lin + -- : DAP -> DAP -> ListDAP ; + BaseDAP x y = + + -- : DAP -> ListDAP -> ListDAP ; + ConsDAP xs x = + + -- : Conj -> ListDAP -> Det ; -- his or her + ConjDet conj xs = +-} +} diff --git a/src/gaelic/ConstructionGla.gf b/src/gaelic/ConstructionGla.gf new file mode 100644 index 00000000..abf40ebf --- /dev/null +++ b/src/gaelic/ConstructionGla.gf @@ -0,0 +1,117 @@ +concrete ConstructionGla of Construction = CatGla ** open ParadigmsGla in { + +lincat + Timeunit = N ; + Weekday = N ; + Monthday = NP ; + Month = N ; + Year = NP ; +{- +lin + + timeunitAdv n time = + let n_card : Card = n ; + n_hours_NP : NP = mkNP n_card time ; + in SyntaxGla.mkAdv for_Prep n_hours_NP | mkAdv (n_hours_NP.s ! R.npNom) ; + + weekdayPunctualAdv w = ; -- on Sunday + weekdayHabitualAdv w = ; -- on Sundays + weekdayNextAdv w = -- next Sunday + weekdayLastAdv w = -- last Sunday + + monthAdv m = mkAdv in_Prep (mkNP m) ; + yearAdv y = mkAdv in_Prep y ; + dayMonthAdv d m = ; -- on 17 Gla + monthYearAdv m y = ; -- in Gla 2012 + dayMonthYearAdv d m y = ; -- on 17 Gla 2013 + + intYear = symb ; + intMonthday = symb ; + +lincat Language = N ; + +lin InLanguage l = mkAdv ???_Prep (mkNP l) ; + +lin + weekdayN w = w ; + monthN m = m ; + + weekdayPN w = mkPN w ; + monthPN m = mkPN m ; + + languageCN l = mkCN l ; + languageNP l = mkNP l ; + + +oper mkLanguage : Str -> N = \s -> mkN s ; + +---------------------------------------------- +---- lexicon of special names + +lin second_Timeunit = mkN "second" ; +lin minute_Timeunit = mkN "minute" ; +lin hour_Timeunit = mkN "hour" ; +lin day_Timeunit = mkN "day" ; +lin week_Timeunit = mkN "week" ; +lin month_Timeunit = mkN "month" ; +lin year_Timeunit = mkN "year" ; + +lin monday_Weekday = mkN "Monday" ; +lin tuesday_Weekday = mkN "Tuesday" ; +lin wednesday_Weekday = mkN "Wednesday" ; +lin thursday_Weekday = mkN "Thursday" ; +lin friday_Weekday = mkN "Friday" ; +lin saturday_Weekday = mkN "Saturday" ; +lin sunday_Weekday = mkN "Sunday" ; + +lin january_Month = mkN "January" ; +lin february_Month = mkN "February" ; +lin march_Month = mkN "March" ; +lin april_Month = mkN "April" ; +lin may_Month = mkN "May" ; +lin june_Month = mkN "June" ; +lin july_Month = mkN "July" ; +lin august_Month = mkN "August" ; +lin september_Month = mkN "September" ; +lin october_Month = mkN "October" ; +lin november_Month = mkN "November" ; +lin december_Month = mkN "December" ; + +lin afrikaans_Language = mkLanguage "Afrikaans" ; +lin amharic_Language = mkLanguage "Amharic" ; +lin arabic_Language = mkLanguage "Arabic" ; +lin bulgarian_Language = mkLanguage "Bulgarian" ; +lin catalan_Language = mkLanguage "Catalan" ; +lin chinese_Language = mkLanguage "Chinese" ; +lin danish_Language = mkLanguage "Danish" ; +lin dutch_Language = mkLanguage "Dutch" ; +lin english_Language = mkLanguage "Euslish" ; +lin estonian_Language = mkLanguage "Estonian" ; +lin finnish_Language = mkLanguage "Finnish" ; +lin french_Language = mkLanguage "French" ; +lin german_Language = mkLanguage "German" ; +lin greek_Language = mkLanguage "Greek" ; +lin hebrew_Language = mkLanguage "Hebrew" ; +lin hindi_Language = mkLanguage "Hindi" ; +lin japanese_Language = mkLanguage "Japanese" ; +lin italian_Language = mkLanguage "Italian" ; +lin latin_Language = mkLanguage "Latin" ; +lin latvian_Language = mkLanguage "Latvian" ; +lin maltese_Language = mkLanguage "Maltese" ; +lin nepali_Language = mkLanguage "Nepali" ; +lin norwegian_Language = mkLanguage "Norwegian" ; +lin persian_Language = mkLanguage "Persian" ; +lin polish_Language = mkLanguage "Polish" ; +lin punjabi_Language = mkLanguage "Punjabi" ; +lin romanian_Language = mkLanguage "Romanian" ; +lin russian_Language = mkLanguage "Russian" ; +lin sindhi_Language = mkLanguage "Sindhi" ; +lin spanish_Language = mkLanguage "Spanish" ; +lin swahili_Language = mkLanguage "Swahili" ; +lin swedish_Language = mkLanguage "Swedish" ; +lin thai_Language = mkLanguage "Thai" ; +lin turkish_Language = mkLanguage "Turkish" ; +lin urdu_Language = mkLanguage "Urdu" ; + +-} +} diff --git a/src/gaelic/ExtendGla.gf b/src/gaelic/ExtendGla.gf new file mode 100644 index 00000000..5e70f743 --- /dev/null +++ b/src/gaelic/ExtendGla.gf @@ -0,0 +1,35 @@ +--# -path=.:../common:../abstract + +concrete ExtendGla of Extend = CatGla + ** ExtendFunctor - [ + VPS -- finite VP's with tense and polarity + , ListVPS + , VPI + , ListVPI -- infinitive VP's (TODO: with anteriority and polarity) + , MkVPS + , PredVPS + + -- excluded because RGL funs needed for them not implemented yet + , SlashBareV2S + , PredAPVP + , ComplBareVS + , AdvIsNP, AdvIsNPAP + , CompBareCN + , CompIQuant + , ComplSlashPartLast + , ComplDirectVQ + , ComplDirectVS + , DetNPFem, DetNPMasc + , ExistCN, ExistMassCN, ExistPluralCN, ExistsNP + , ExistIPQS, ExistNPQS, ExistS + , PredIAdvVP + , PrepCN + , ReflPossPron + , UttVP, UttVPShort, UttAccNP, UttDatNP, UttAccIP, UttDatIP + , EmptyRelSlash, StrandQuestSlash, StrandRelSlash + , SubjRelNP + , UseComp_ser, UseComp_estar + , iFem_Pron, weFem_Pron, youFem_Pron, youPlFem_Pron, youPolFem_Pron, youPolPlFem_Pron, youPolPl_Pron, theyFem_Pron, theyNeutr_Pron + , GenModNP + + ] with (Grammar=GrammarGla) ; diff --git a/src/gaelic/GrammarGla.gf b/src/gaelic/GrammarGla.gf new file mode 100644 index 00000000..1688ad9a --- /dev/null +++ b/src/gaelic/GrammarGla.gf @@ -0,0 +1,17 @@ +concrete GrammarGla of Grammar = + NounGla + , VerbGla + , AdjectiveGla + , AdverbGla + , NumeralGla + , SentenceGla + , QuestionGla + , RelativeGla + , ConjunctionGla + , PhraseGla + , TextX + , StructuralGla + , IdiomGla + , TenseX + , NamesGla -- Not part of original Grammar, here to trigger compilation + ; diff --git a/src/gaelic/IdiomGla.gf b/src/gaelic/IdiomGla.gf new file mode 100644 index 00000000..ab6a3acc --- /dev/null +++ b/src/gaelic/IdiomGla.gf @@ -0,0 +1,56 @@ + +--1 Idiom: Idiomatic Expressions + +concrete IdiomGla of Idiom = CatGla ** open Prelude, ResGla, VerbGla, QuestionGla, NounGla, StructuralGla in { + +-- This module defines constructions that are formed in fixed ways, +-- often different even in closely related languages. + +{- + lin + + + -- ImpersCl : VP -> Cl ; -- it is hot + ImpersCl vp = { + } ; + + -- : NP -> Cl ; -- there is a house + ExistNP np = + + -- ExistIP : IP -> QCl ; -- which houses are there + ExistIP ip = + + -- GenericCl : VP -> Cl ; -- one sleeps + GenericCl vp = + + CleftNP : NP -> RS -> Cl ; -- it is I who did it + CleftAdv : Adv -> S -> Cl ; -- it is here she slept + + -- : NP -> Cl ; -- there is a house + ExistNP np = + + ExistIP : IP -> QCl ; -- which houses are there + +-- 7/12/2012 generalizations of these + + ExistNPAdv : NP -> Adv -> Cl ; -- there is a house in Paris + ExistIPAdv : IP -> Adv -> QCl ; -- which houses are there in Paris + + -- : VP -> VP ; + ProgrVP vp = vp ** { + } ; + + + -- : VP -> Utt ; -- let's go + ImpPl1 vp = { } ; + + ImpP3 : NP -> VP -> Utt ; -- let John walk + +-- 3/12/2013 non-reflexive uses of "self" + + SelfAdvVP : VP -> VP ; -- is at home himself + SelfAdVVP : VP -> VP ; -- is himself at home + SelfNP : NP -> NP ; -- the president himself (is at home) +-} + +} diff --git a/src/gaelic/LangGla.gf b/src/gaelic/LangGla.gf new file mode 100644 index 00000000..99fee6e3 --- /dev/null +++ b/src/gaelic/LangGla.gf @@ -0,0 +1,5 @@ +--# -path=.:../abstract:../common:../prelude:../api +concrete LangGla of Lang = + GrammarGla, + LexiconGla, + ConstructionGla ; diff --git a/src/gaelic/LexiconGla.gf b/src/gaelic/LexiconGla.gf new file mode 100644 index 00000000..96142b55 --- /dev/null +++ b/src/gaelic/LexiconGla.gf @@ -0,0 +1,419 @@ +concrete LexiconGla of Lexicon = CatGla ** + open ParadigmsGla, ResGla in { + +---- +-- A +{- +lin add_V3 = mkV3 (mkV "") ; +lin airplane_N = mkN "" ; +lin alas_Interj = mkInterj "" ; +lin already_Adv = mkA "" ; +lin animal_N = mkN "" ; +lin answer_V2S = mkV2S (mkV "") ; +lin apartment_N = mkN "" ; +lin apple_N = mkN "" ; +lin art_N = mkN "" ; +lin ashes_N = mkN "" ; +lin ask_V2Q = mkV2Q (mkV "") ; + +---- +-- B + +lin baby_N = mkN "" ; +lin back_N = mkN "" ; +lin bad_A = mkA "" ; +lin bank_N = mkN "" ; +lin bark_N = mkN "" ; +lin beautiful_A = mkA "" ; +lin become_VA = mkVA (mkV "") ; +lin beer_N = mkN "" ; +lin beg_V2V = mkV2V (mkV "") ; +lin belly_N = mkN "" ; +lin big_A = mkA "" ; +lin bike_N = mkN "" ; +lin bird_N = mkN "" ; +lin bite_V2 = mkV2 "" ; +lin black_A = mkA "" ; -} +lin blood_N = mkN "blood" ; +{-lin blow_V = mkV "" ; +lin blue_A = mkA "" ; +lin boat_N = mkN "" ; +lin bone_N = mkN "" ; +lin boot_N = mkN "" ; +lin boss_N = mkN "" ; +lin book_N = mkN "" ; +lin boy_N = mkN "" ; +lin bread_N = mkN "" ; +lin break_V2 = mkV2 "" ; +lin breast_N = mkN "" ; +lin breathe_V = mkV "" ; +lin broad_A = mkA "" ; +lin brother_N2 = mkN "" ; +lin brown_A = mkA "" ; +lin burn_V = mkV "" ; +lin butter_N = mkN "" ; +lin buy_V2 = mkV2 "" ; + +---- +-- C + +lin camera_N = mkN "" ; +lin cap_N = mkN "" ; +lin car_N = mkN "" ; +lin carpet_N = mkN "" ; +lin cat_N = mkN "" ; +lin ceiling_N = mkN "" ; +lin chair_N = mkN "" ; +lin cheese_N = mkN "" ; +lin child_N = mkN "" ; +lin church_N = mkN "" ; +lin city_N = mkN "" ; +lin clean_A = mkA "" ; +lin clever_A = mkA "" ; +lin close_V2 = mkV2 "" ; +lin cloud_N = mkN "" ; +lin coat_N = mkN "" ; +lin cold_A = mkA "" ; +lin come_V = mkV "" ; +lin computer_N = mkN "" ; +lin correct_A = mkA "" ; +lin count_V2 = mkV2 "" ; +lin country_N = mkN "" ; +lin cousin_N = mkN "" ; +lin cow_N = mkN "" ; +lin cut_V2 = mkV2 "" ; + +---- +-- D + +lin day_N = mkN "" ; -} +lin die_V = mkV "die" ; +{-lin dig_V = mkV "" ; +lin dirty_A = mkA "" ; +lin distance_N3 = mkN3 (mkN "") ; +lin do_V2 = mkV2 "" ; +lin doctor_N = mkN "" ; +lin dog_N = mkN "" ; +lin door_N = mkN "" ; +lin drink_V2 = mkV2 "" ; +lin dry_A = mkA "" ; +lin dull_A = mkA "" ; +lin dust_N = mkN "" ; + +---- +-- E + +lin ear_N = mkN "" ; +lin earth_N = mkN "" ; +lin eat_V2 = mkV "" ; +lin egg_N = mkN "" ; +lin empty_A = mkA "" ; +lin enemy_N = mkN "" ; +lin eye_N = mkN "" ; + +---- +-- F + +lin factory_N = mkN "" ; +lin fall_V = mkV "" ; +lin far_Adv = mkA "" ; +lin fat_N = mkN "" ; +lin father_N2 = mkN2 (mkN "") ; +lin fear_V2 = mkV2 "" ; +lin fear_VS = mkVS (mkV "") ; +lin feather_N = mkN "" ; +lin fight_V2 = mkV2 "" ; +lin find_V2 = mkV2 "" ; +lin fingernail_N = mkN "" ; +lin fire_N = mkN "" ; +lin fish_N = mkN "" ; +lin float_V = mkV "" ; +lin floor_N = mkN "" ; +lin flow_V = mkV "" ; +lin flower_N = mkN "" ; +lin fly_V = mkV "" ; +lin fog_N = mkN "" ; +lin foot_N = mkN "" ; +lin forest_N = mkN "" ; +lin forget_V2 = mkV2 "" ; +lin freeze_V = mkV "" ; +lin fridge_N = mkN "" ; +lin friend_N = mkN "" ; +lin fruit_N = mkN "" ; +lin full_A = mkA "" ; +--lin fun_AV + +---- +-- G + +lin garden_N = mkN "" ; +lin girl_N = mkN "" ; +lin give_V3 = mkV3 (mkV "") ; +lin glove_N = mkN "" ; +lin go_V = mkV "" ; +lin gold_N = mkN "" ; +lin good_A = mkA "" ; +lin grammar_N = mkN "" ; +lin grass_N = mkN "" ; +lin green_A = mkA "" ; + +---- +-- H + +lin hair_N = mkN "" ; +lin hand_N = mkN "" ; +lin harbour_N = mkN "" ; +lin hat_N = mkN "" ; +lin hate_V2 = mkV2 "" ; +lin head_N = mkN "" ; +lin hear_V2 = mkV2 "" ; +lin heart_N = mkN "" ; +lin heavy_A = mkA "" ; +lin hill_N = mkN "" ; +lin hit_V2 = mkV2 "" ; +lin hold_V2 = mkV2 "" ; +lin hope_VS = mkV "" ; +lin horn_N = mkN "" ; +lin horse_N = mkN "" ; +lin hot_A = mkA "" ; +lin house_N = mkN "" ; +lin hunt_V2 = mkV2 "" ; +lin husband_N = mkN "" ; + +-------- +-- I - K + +lin ice_N = mkN "" ; +lin industry_N = mkN "" ; +lin iron_N = mkN "" ; +lin john_PN = mkPN "" ; +lin jump_V = mkV "" ; +lin kill_V2 = mkV2 "" ; +lin king_N = mkN "" ; +lin knee_N = mkN "" ; +lin know_V2 = mkV2 "" ; +lin know_VQ = mkVQ (mkV "") ; +lin know_VS = mkV "" ; + + +---- +-- L + +lin lake_N = mkN "" ; +lin lamp_N = mkN "" ; +lin language_N = mkN "" ; +lin laugh_V = mkV "" ; +lin leaf_N = mkN "" ; +lin learn_V2 = mkV2 "" ; +lin leather_N = mkN "" ; +lin leave_V2 = mkV2 "" ; +lin leg_N = mkN "" ; +lin lie_V = mkV "" ; +lin like_V2 = mkV2 "" ; +lin listen_V2 = mkV2 "" ; +lin live_V = mkV ""; +lin liver_N = mkN "" ; +lin long_A = mkA "" ; +lin lose_V2 = mkV2 "" ; +lin louse_N = mkN "" ; +lin love_N = mkN "" ; +lin love_V2 = mkV2 "" ; + +---- +-- M + +lin man_N = mkN "" ; +lin married_A2 = mkA2 (mkA "") ; +lin meat_N = mkN "" ; +lin milk_N = mkN "" ; +lin moon_N = mkN "" ; +lin mother_N2 = mkN2 (mkN "") ; +lin mountain_N = mkN "" ; +lin mouth_N = mkN "" ; +lin music_N = mkN "" ; + +---- +-- N + +lin name_N = mkN "" ; +lin narrow_A = mkA "" ; +lin near_A = mkA "" ; +lin neck_N = mkN "" ; +lin new_A = mkA "" ; +lin newspaper_N = mkN "" ; +lin night_N = mkN "" ; +lin nose_N = mkN "" ; +lin now_Adv = mkAdv "" ; +lin number_N = mkN "" ; + +-------- +-- O - P + + +lin oil_N = mkN "" ; +lin old_A = mkA "" ; +lin open_V2 = mkV2 "" ; +lin paint_V2A = mkV2A (mkV "") ; +lin paper_N = mkN "" ; +lin paris_PN = mkPN "Paris" ; +lin peace_N = mkN "" ; +lin pen_N = mkN "" ; +lin person_N = mkN "" ; +lin planet_N = mkN "" ; +lin plastic_N = mkN "" ; +lin play_V = mkV "" ; +lin policeman_N = mkN "" ; +lin priest_N = mkN "" ; +lin pull_V2 = mkV2 "" ; +lin push_V2 = mkV2 "" ; +lin put_V2 = mkV2 "" ; + +-------- +-- Q - R + + +lin queen_N = mkN "" ; +lin question_N = mkN "" ; +lin radio_N = mkN "" ; +lin rain_N = mkN "" ; +lin rain_V0 = mkV "" ; +lin read_V2 = mkV2 "" ; +lin ready_A = mkA "" ; +lin reason_N = mkN "" ; +lin red_A = mkA "" ; +lin religion_N = mkN "" ; +lin restaurant_N = mkN "" ; +lin river_N = mkN "" ; +lin road_N = mkN "" ; +lin rock_N = mkN "" ; +lin roof_N = mkN "" ; +lin root_N = mkN "" ; +lin rope_N = mkN "" ; +lin rotten_A = mkA "" ; +lin round_A = mkA "" ; +lin rub_V2 = mkV2 "" ; +lin rubber_N = mkN "" ; +lin rule_N = mkN "" ; +lin run_V = mkV "" ; + +---- +-- S + +lin salt_N = mkN "" ; +lin sand_N = mkN "" ; +lin say_VS = mkVS (mkV "") ; +lin school_N = mkN "" ; +lin science_N = mkN "" ; +lin scratch_V2 = mkV2 "" ; +lin sea_N = mkN "" ; +lin see_V2 = mkV2 "" ; +lin seed_N = mkN "" ; +lin seek_V2 = mkV2 "" ; +lin sell_V3 = mkV3 (mkV "" Meng) emptyPrep emptyPrep ; -- TODO +lin send_V3 = mkV3 (mkV "") ; +lin sew_V = mkV "" ; +lin sharp_A = mkA "" ; +lin sheep_N = mkN "" fem ; +lin ship_N = mkN "" ; +lin shirt_N = mkN "" ; +lin shoe_N = mkN "" ; +lin shop_N = mkN "" ; +lin short_A = mkA "" ; +lin silver_N = mkN "" ; +lin sing_V = mkV "" ; +lin sister_N = mkN "" ; +lin sit_V = mkV "" ; +lin skin_N = mkN "" ; +lin sky_N = mkN "" ; +lin sleep_V = mkV "" ; +lin small_A = mkA "" ; +lin smell_V = mkV "" ; +lin smoke_N = mkN "" ; +lin smooth_A = mkA "" ; +lin snake_N = mkN "" ; +lin snow_N = mkN "" ; +lin sock_N = mkN "" ; +lin song_N = mkN "" ; +lin speak_V2 = mkV2 "" ; +lin spit_V = mkV "" ; +lin split_V2 = mkV2 "" ; +lin squeeze_V2 = mkV2 "" ; +lin stab_V2 = mkV2 "" ; +lin stand_V = mkV "" ; +lin star_N = mkN "" ; +lin steel_N = mkN "" ; +lin stick_N = mkN "" ; +lin stone_N = mkN "" ; +lin stop_V = mkV "" ; +lin stove_N = mkN "" ; +lin straight_A = mkA "" ; +lin student_N = mkN "" ; +lin stupid_A = mkA "" ; +lin suck_V2 = mkV2 "" ; +lin sun_N = mkN "" ; +lin swell_V = mkV "" ; +lin swim_V = mkV "" ; + +---- +-- T + + +lin table_N = mkN "" ; +lin tail_N = mkN "" ; +lin talk_V3 = mkV3 (mkV "" Ber) (mkPrep "") (mkPrep "") ; +lin teach_V2 = mkV2 "" ; +lin teacher_N = mkN "" ; +lin television_N = mkN "" ; +lin thick_A = mkA "" ; +lin thin_A = mkA "" ; +lin think_V = mkV "" ; +lin throw_V2 = mkV2 "" ; +lin tie_V2 = mkV2 "" ; +lin today_Adv = mkA "" ; +lin tongue_N = mkN "" ; +lin tooth_N = mkN "" ; +lin train_N = mkN "" ; +lin travel_V = mkV "" ; +lin tree_N = mkN "" ; +lin turn_V = mkV "" ; + +-------- +-- U - V + +lin ugly_A = mkA "" ; +lin uncertain_A = mkA "" ; +lin understand_V2 = mkV2 "" ; +lin university_N = mkN "" ; +lin village_N = mkN "" ; +lin vomit_V = mkV2 "" ; + +-------- +-- W - Y + +lin wait_V2 = mkV2 "" ; +lin walk_V = mkV "" ; +lin war_N = mkN "" ; +lin warm_A = mkA "" ; +lin wash_V2 = mkV2 "" ; +lin watch_V2 = mkV2 "" ; +lin water_N = mkNoun "" ; +lin wet_A = mkA "" ; +lin white_A = mkA "" ; +lin wide_A = mkA "" ; +lin wife_N = mkN "" ; +lin win_V2 = mkV2 "" ; +lin wind_N = mkN "" ; +lin window_N = mkN "" ; +lin wine_N = mkN "" ; +lin wing_N = mkN "" ; +lin wipe_V2 = mkV2 "" ; +lin woman_N = mkN "" ; +lin wonder_VQ = mkVQ (mkV "") ; +lin wood_N = mkN "" ; +lin worm_N = mkN "" ; +lin write_V2 = mkV2 "" ; +lin year_N = mkN "" ; +lin yellow_A = mkA "" ; +lin young_A = mkA "" ; +-} +} diff --git a/src/gaelic/MissingGla.gf b/src/gaelic/MissingGla.gf new file mode 100644 index 00000000..12be87d0 --- /dev/null +++ b/src/gaelic/MissingGla.gf @@ -0,0 +1,313 @@ +resource MissingGla = open GrammarGla, Prelude in { +-- temporary definitions to enable the compilation of RGL API +oper AdAP : AdA -> AP -> AP = notYet "AdAP" ; +oper AdAdv : AdA -> Adv -> Adv = notYet "AdAdv" ; +oper AdNum : AdN -> Card -> Card = notYet "AdNum" ; +oper AdVVP : AdV -> VP -> VP = notYet "AdVVP" ; +oper AdVVPSlash : AdV -> VPSlash -> VPSlash = notYet "AdVVPSlash" ; +oper AddAdvQVP : QVP -> IAdv -> QVP = notYet "AddAdvQVP" ; +oper AdjCN : AP -> CN -> CN = notYet "AdjCN" ; +oper AdjDAP : DAP -> AP -> DAP = notYet "AdjDAP" ; +oper AdjOrd : Ord -> AP = notYet "AdjOrd" ; +oper AdnCAdv : CAdv -> AdN = notYet "AdnCAdv" ; +oper AdvAP : AP -> Adv -> AP = notYet "AdvAP" ; +oper AdvCN : CN -> Adv -> CN = notYet "AdvCN" ; +oper AdvIAdv : IAdv -> Adv -> IAdv = notYet "AdvIAdv" ; +oper AdvIP : IP -> Adv -> IP = notYet "AdvIP" ; +oper AdvImp : Adv -> Imp -> Imp = notYet "AdvImp" ; +oper AdvNP : NP -> Adv -> NP = notYet "AdvNP" ; +oper AdvQVP : VP -> IAdv -> QVP = notYet "AdvQVP" ; +oper AdvS : Adv -> S -> S = notYet "AdvS" ; +oper AdvSlash : ClSlash -> Adv -> ClSlash = notYet "AdvSlash" ; +oper AdvVP : VP -> Adv -> VP = notYet "AdvVP" ; +oper AdvVPSlash : VPSlash -> Adv -> VPSlash = notYet "AdvVPSlash" ; +oper ApposCN : CN -> NP -> CN = notYet "ApposCN" ; +oper BaseAP : AP -> AP -> ListAP = notYet "BaseAP" ; +oper BaseAdV : AdV -> AdV -> ListAdV = notYet "BaseAdV" ; +oper BaseAdv : Adv -> Adv -> ListAdv = notYet "BaseAdv" ; +oper BaseCN : CN -> CN -> ListCN = notYet "BaseCN" ; +oper BaseIAdv : IAdv -> IAdv -> ListIAdv = notYet "BaseIAdv" ; +oper BaseNP : NP -> NP -> ListNP = notYet "BaseNP" ; +oper BaseRS : RS -> RS -> ListRS = notYet "BaseRS" ; +oper BaseS : S -> S -> ListS = notYet "BaseS" ; +oper CAdvAP : CAdv -> AP -> NP -> AP = notYet "CAdvAP" ; +oper CleftAdv : Adv -> S -> Cl = notYet "CleftAdv" ; +oper CleftNP : NP -> RS -> Cl = notYet "CleftNP" ; +oper CompAP : AP -> Comp = notYet "CompAP" ; +oper CompAdv : Adv -> Comp = notYet "CompAdv" ; +oper CompCN : CN -> Comp = notYet "CompCN" ; +oper CompIAdv : IAdv -> IComp = notYet "CompIAdv" ; +oper CompIP : IP -> IComp = notYet "CompIP" ; +oper CompNP : NP -> Comp = notYet "CompNP" ; +oper ComparA : A -> NP -> AP = notYet "ComparA" ; +oper ComparAdvAdj : CAdv -> A -> NP -> Adv = notYet "ComparAdvAdj" ; +oper ComparAdvAdjS : CAdv -> A -> S -> Adv = notYet "ComparAdvAdjS" ; +oper ComplA2 : A2 -> NP -> AP = notYet "ComplA2" ; +oper ComplN2 : N2 -> NP -> CN = notYet "ComplN2" ; +oper ComplN3 : N3 -> NP -> N2 = notYet "ComplN3" ; +oper ComplSlash : VPSlash -> NP -> VP = notYet "ComplSlash" ; +oper ComplSlashIP : VPSlash -> IP -> QVP = notYet "ComplSlashIP" ; +oper ComplVA : VA -> AP -> VP = notYet "ComplVA" ; +oper ComplVQ : VQ -> QS -> VP = notYet "ComplVQ" ; +oper ComplVS : VS -> S -> VP = notYet "ComplVS" ; +oper ComplVV : VV -> VP -> VP = notYet "ComplVV" ; +oper ConjAP : Conj -> ListAP -> AP = notYet "ConjAP" ; +oper ConjAdV : Conj -> ListAdV -> AdV = notYet "ConjAdV" ; +oper ConjAdv : Conj -> ListAdv -> Adv = notYet "ConjAdv" ; +oper ConjCN : Conj -> ListCN -> CN = notYet "ConjCN" ; +oper ConjDet : Conj -> ListDAP -> Det = notYet "ConjDet" ; +oper ConjIAdv : Conj -> ListIAdv -> IAdv = notYet "ConjIAdv" ; +oper ConjNP : Conj -> ListNP -> NP = notYet "ConjNP" ; +oper ConjRS : Conj -> ListRS -> RS = notYet "ConjRS" ; +oper ConjS : Conj -> ListS -> S = notYet "ConjS" ; +oper ConsAP : AP -> ListAP -> ListAP = notYet "ConsAP" ; +oper ConsAdV : AdV -> ListAdV -> ListAdV = notYet "ConsAdV" ; +oper ConsAdv : Adv -> ListAdv -> ListAdv = notYet "ConsAdv" ; +oper ConsCN : CN -> ListCN -> ListCN = notYet "ConsCN" ; +oper ConsIAdv : IAdv -> ListIAdv -> ListIAdv = notYet "ConsIAdv" ; +oper ConsNP : NP -> ListNP -> ListNP = notYet "ConsNP" ; +oper ConsRS : RS -> ListRS -> ListRS = notYet "ConsRS" ; +oper ConsS : S -> ListS -> ListS = notYet "ConsS" ; +oper CountNP : Det -> NP -> NP = notYet "CountNP" ; +oper DetCN : Det -> CN -> NP = notYet "DetCN" ; +oper DetDAP : Det -> DAP = notYet "DetDAP" ; +oper DetNP : Det -> NP = notYet "DetNP" ; +oper DetQuantOrd : Quant -> Num -> Ord -> Det = notYet "DetQuantOrd" ; +oper EmbedQS : QS -> SC = notYet "EmbedQS" ; +oper EmbedS : S -> SC = notYet "EmbedS" ; +oper EmbedVP : VP -> SC = notYet "EmbedVP" ; +oper ExistIP : IP -> QCl = notYet "ExistIP" ; +oper ExistIPAdv : IP -> Adv -> QCl = notYet "ExistIPAdv" ; +oper ExistNP : NP -> Cl = notYet "ExistNP" ; +oper ExistNPAdv : NP -> Adv -> Cl = notYet "ExistNPAdv" ; +oper ExtAdvS : Adv -> S -> S = notYet "ExtAdvS" ; +oper ExtAdvVP : VP -> Adv -> VP = notYet "ExtAdvVP" ; +oper FunRP : Prep -> NP -> RP -> RP = notYet "FunRP" ; +oper GenericCl : VP -> Cl = notYet "GenericCl" ; +oper IdRP : RP = notYet "IdRP" ; +oper IdetCN : IDet -> CN -> IP = notYet "IdetCN" ; +oper IdetIP : IDet -> IP = notYet "IdetIP" ; +oper IdetQuant : IQuant -> Num -> IDet = notYet "IdetQuant" ; +oper ImpP3 : NP -> VP -> Utt = notYet "ImpP3" ; +oper ImpPl1 : VP -> Utt = notYet "ImpPl1" ; +oper ImpVP : VP -> Imp = notYet "ImpVP" ; +oper ImpersCl : VP -> Cl = notYet "ImpersCl" ; +oper MassNP : CN -> NP = notYet "MassNP" ; +oper NumCard : Card -> Num = notYet "NumCard" ; +oper NumDigits : Digits -> Card = notYet "NumDigits" ; +oper NumNumeral : Numeral -> Card = notYet "NumNumeral" ; +oper OrdDigits : Digits -> Ord = notYet "OrdDigits" ; +oper OrdNumeral : Numeral -> Ord = notYet "OrdNumeral" ; +oper OrdNumeralSuperl : Numeral -> A -> Ord = notYet "OrdNumeralSuperl" ; +oper OrdSuperl : A -> Ord = notYet "OrdSuperl" ; +oper PConjConj : Conj -> PConj = notYet "PConjConj" ; +oper PPartNP : NP -> V2 -> NP = notYet "PPartNP" ; +oper PartNP : CN -> NP -> CN = notYet "PartNP" ; +oper PassV2 : V2 -> VP = notYet "PassV2" ; +oper PhrUtt : PConj -> Utt -> Voc -> Phr = notYet "PhrUtt" ; +oper PositA : A -> AP = notYet "PositA" ; +oper PositAdAAdj : A -> AdA = notYet "PositAdAAdj" ; +oper PositAdvAdj : A -> Adv = notYet "PositAdvAdj" ; +oper PossNP : CN -> NP -> CN = notYet "PossNP" ; +oper PossPron : Pron -> Quant = notYet "PossPron" ; +oper PredSCVP : SC -> VP -> Cl = notYet "PredSCVP" ; +oper PredVP : NP -> VP -> Cl = notYet "PredVP" ; +oper PredetNP : Predet -> NP -> NP = notYet "PredetNP" ; +oper PrepIP : Prep -> IP -> IAdv = notYet "PrepIP" ; +oper PrepNP : Prep -> NP -> Adv = notYet "PrepNP" ; +oper ProgrVP : VP -> VP = notYet "ProgrVP" ; +oper QuestCl : Cl -> QCl = notYet "QuestCl" ; +oper QuestIAdv : IAdv -> Cl -> QCl = notYet "QuestIAdv" ; +oper QuestIComp : IComp -> NP -> QCl = notYet "QuestIComp" ; +oper QuestQVP : IP -> QVP -> QCl = notYet "QuestQVP" ; +oper QuestSlash : IP -> ClSlash -> QCl = notYet "QuestSlash" ; +oper QuestVP : IP -> VP -> QCl = notYet "QuestVP" ; +oper ReflA2 : A2 -> AP = notYet "ReflA2" ; +oper ReflVP : VPSlash -> VP = notYet "ReflVP" ; +oper RelCN : CN -> RS -> CN = notYet "RelCN" ; +oper RelCl : Cl -> RCl = notYet "RelCl" ; +oper RelNP : NP -> RS -> NP = notYet "RelNP" ; +oper RelS : S -> RS -> S = notYet "RelS" ; +oper RelSlash : RP -> ClSlash -> RCl = notYet "RelSlash" ; +oper RelVP : RP -> VP -> RCl = notYet "RelVP" ; +oper SSubjS : S -> Subj -> S -> S = notYet "SSubjS" ; +oper SelfAdVVP : VP -> VP = notYet "SelfAdVVP" ; +oper SelfAdvVP : VP -> VP = notYet "SelfAdvVP" ; +oper SelfNP : NP -> NP = notYet "SelfNP" ; +oper SentAP : AP -> SC -> AP = notYet "SentAP" ; +oper SentCN : CN -> SC -> CN = notYet "SentCN" ; +oper Slash2V3 : V3 -> NP -> VPSlash = notYet "Slash2V3" ; +oper Slash3V3 : V3 -> NP -> VPSlash = notYet "Slash3V3" ; +oper SlashPrep : Cl -> Prep -> ClSlash = notYet "SlashPrep" ; +oper SlashV2A : V2A -> AP -> VPSlash = notYet "SlashV2A" ; +oper SlashV2Q : V2Q -> QS -> VPSlash = notYet "SlashV2Q" ; +oper SlashV2S : V2S -> S -> VPSlash = notYet "SlashV2S" ; +oper SlashV2V : V2V -> VP -> VPSlash = notYet "SlashV2V" ; +oper SlashV2VNP : V2V -> NP -> VPSlash -> VPSlash = notYet "SlashV2VNP" ; +oper SlashV2a : V2 -> VPSlash = notYet "SlashV2a" ; +oper SlashVP : NP -> VPSlash -> ClSlash = notYet "SlashVP" ; +oper SlashVS : NP -> VS -> SSlash -> ClSlash = notYet "SlashVS" ; +oper SlashVV : VV -> VPSlash -> VPSlash = notYet "SlashVV" ; +oper SubjS : Subj -> S -> Adv = notYet "SubjS" ; +oper TFullStop : Phr -> Text -> Text = notYet "TFullStop" ; +oper Use2N3 : N3 -> N2 = notYet "Use2N3" ; +oper Use3N3 : N3 -> N2 = notYet "Use3N3" ; +oper UseA2 : A2 -> AP = notYet "UseA2" ; +oper UseCl : Temp -> Pol -> Cl -> S = notYet "UseCl" ; +oper UseComp : Comp -> VP = notYet "UseComp" ; +oper UseComparA : A -> AP = notYet "UseComparA" ; +oper UseCopula : VP = notYet "UseCopula" ; +oper UseN : N -> CN = notYet "UseN" ; +oper UseN2 : N2 -> CN = notYet "UseN2" ; +oper UsePN : PN -> NP = notYet "UsePN" ; +oper UsePron : Pron -> NP = notYet "UsePron" ; +oper UseQCl : Temp -> Pol -> QCl -> QS = notYet "UseQCl" ; +oper UseRCl : Temp -> Pol -> RCl -> RS = notYet "UseRCl" ; +oper UseSlash : Temp -> Pol -> ClSlash -> SSlash = notYet "UseSlash" ; +oper UseV : V -> VP = notYet "UseV" ; +oper UttAP : AP -> Utt = notYet "UttAP" ; +oper UttAdv : Adv -> Utt = notYet "UttAdv" ; +oper UttCN : CN -> Utt = notYet "UttCN" ; +oper UttCard : Card -> Utt = notYet "UttCard" ; +oper UttIAdv : IAdv -> Utt = notYet "UttIAdv" ; +oper UttIP : IP -> Utt = notYet "UttIP" ; +oper UttImpPl : Pol -> Imp -> Utt = notYet "UttImpPl" ; +oper UttImpPol : Pol -> Imp -> Utt = notYet "UttImpPol" ; +oper UttImpSg : Pol -> Imp -> Utt = notYet "UttImpSg" ; +oper UttInterj : Interj -> Utt = notYet "UttInterj" ; +oper UttNP : NP -> Utt = notYet "UttNP" ; +oper UttQS : QS -> Utt = notYet "UttQS" ; +oper UttS : S -> Utt = notYet "UttS" ; +oper UttVP : VP -> Utt = notYet "UttVP" ; +oper VPSlashPrep : VP -> Prep -> VPSlash = notYet "VPSlashPrep" ; +oper VocNP : NP -> Voc = notYet "VocNP" ; +oper above_Prep : Prep = notYet "above_Prep" ; +oper active2passive : Cl -> Cl = notYet "active2passive" ; +oper after_Prep : Prep = notYet "after_Prep" ; +oper alas_Interj : Interj = notYet "alas_Interj" ; +oper all_Predet : Predet = notYet "all_Predet" ; +oper almost_AdA : AdA = notYet "almost_AdA" ; +oper almost_AdN : AdN = notYet "almost_AdN" ; +oper already_Adv : Adv = notYet "already_Adv" ; +oper although_Subj : Subj = notYet "although_Subj" ; +oper always_AdV : AdV = notYet "always_AdV" ; +oper as_CAdv : CAdv = notYet "as_CAdv" ; +oper at_least_AdN : AdN = notYet "at_least_AdN" ; +oper at_most_AdN : AdN = notYet "at_most_AdN" ; +oper because_Subj : Subj = notYet "because_Subj" ; +oper before_Prep : Prep = notYet "before_Prep" ; +oper behind_Prep : Prep = notYet "behind_Prep" ; +oper between_Prep : Prep = notYet "between_Prep" ; +oper both7and_DConj : Conj = notYet "both7and_DConj" ; +oper but_PConj : PConj = notYet "but_PConj" ; +oper by8agent_Prep : Prep = notYet "by8agent_Prep" ; +oper by8means_Prep : Prep = notYet "by8means_Prep" ; +oper dconcat : Digits -> Digits -> Digits = notYet "dconcat" ; +oper digits2num : Digits -> Numeral = notYet "digits2num" ; +oper digits2numeral : Card -> Card = notYet "digits2numeral" ; +oper dn : Dig -> Digit = notYet "dn" ; +oper dn10 : Dig -> Sub10 = notYet "dn10" ; +oper dn100 : Dig -> Dig -> Sub100 = notYet "dn100" ; +oper dn1000 : Dig -> Dig -> Dig -> Sub1000 = notYet "dn1000" ; +oper dn1000000a : Dig -> Dig -> Dig -> Dig -> Sub1000000 = notYet "dn1000000a" ; +oper dn1000000b : Dig -> Dig -> Dig -> Dig -> Dig -> Sub1000000 = notYet "dn1000000b" ; +oper dn1000000c : Dig -> Dig -> Dig -> Dig -> Dig -> Dig -> Sub1000000 = notYet "dn1000000c" ; +oper during_Prep : Prep = notYet "during_Prep" ; +oper either7or_DConj : Conj = notYet "either7or_DConj" ; +oper every_Det : Det = notYet "every_Det" ; +oper everybody_NP : NP = notYet "everybody_NP" ; +oper everything_NP : NP = notYet "everything_NP" ; +oper everywhere_Adv : Adv = notYet "everywhere_Adv" ; +oper except_Prep : Prep = notYet "except_Prep" ; +oper few_Det : Det = notYet "few_Det" ; +oper for_Prep : Prep = notYet "for_Prep" ; +oper from_Prep : Prep = notYet "from_Prep" ; +oper he_Pron : Pron = notYet "he_Pron" ; +oper here7from_Adv : Adv = notYet "here7from_Adv" ; +oper here7to_Adv : Adv = notYet "here7to_Adv" ; +oper here_Adv : Adv = notYet "here_Adv" ; +oper how8many_IDet : IDet = notYet "how8many_IDet" ; +oper how8much_IAdv : IAdv = notYet "how8much_IAdv" ; +oper how_IAdv : IAdv = notYet "how_IAdv" ; +oper i_Pron : Pron = notYet "i_Pron" ; +oper if_Subj : Subj = notYet "if_Subj" ; +oper if_then_Conj : Conj = notYet "if_then_Conj" ; +oper in8front_Prep : Prep = notYet "in8front_Prep" ; +oper in_Prep : Prep = notYet "in_Prep" ; +oper it_Pron : Pron = notYet "it_Pron" ; +oper john_PN : PN = notYet "john_PN" ; +oper language_title_Utt : Utt = notYet "language_title_Utt" ; +oper left_Ord : Ord = notYet "left_Ord" ; +oper less_CAdv : CAdv = notYet "less_CAdv" ; +oper many_Det : Det = notYet "many_Det" ; +oper more_CAdv : CAdv = notYet "more_CAdv" ; +oper most_Predet : Predet = notYet "most_Predet" ; +oper much_Det : Det = notYet "much_Det" ; +oper nd : Digit -> Dig = notYet "nd" ; +oper nd10 : Sub10 -> Digits = notYet "nd10" ; +oper nd100 : Sub100 -> Digits = notYet "nd100" ; +oper nd1000 : Sub1000 -> Digits = notYet "nd1000" ; +oper nd1000000 : Sub1000000 -> Digits = notYet "nd1000000" ; +oper no_Quant : Quant = notYet "no_Quant" ; +oper no_Utt : Utt = notYet "no_Utt" ; +oper nobody_NP : NP = notYet "nobody_NP" ; +oper not_Predet : Predet = notYet "not_Predet" ; +oper nothing_NP : NP = notYet "nothing_NP" ; +oper num : Sub1000000 -> Numeral = notYet "num" ; +oper num2digits : Numeral -> Digits = notYet "num2digits" ; +oper on_Prep : Prep = notYet "on_Prep" ; +oper only_Predet : Predet = notYet "only_Predet" ; +oper or_Conj : Conj = notYet "or_Conj" ; +oper otherwise_PConj : PConj = notYet "otherwise_PConj" ; +oper part_Prep : Prep = notYet "part_Prep" ; +oper please_Voc : Voc = notYet "please_Voc" ; +oper possess_Prep : Prep = notYet "possess_Prep" ; +oper pot01 : Sub10 = notYet "pot01" ; +oper pot1 : Digit -> Sub100 = notYet "pot1" ; +oper pot110 : Sub100 = notYet "pot110" ; +oper pot111 : Sub100 = notYet "pot111" ; +oper pot1plus : Digit -> Sub10 -> Sub100 = notYet "pot1plus" ; +oper pot1to19 : Digit -> Sub100 = notYet "pot1to19" ; +oper pot2 : Sub10 -> Sub1000 = notYet "pot2" ; +oper pot2plus : Sub10 -> Sub100 -> Sub1000 = notYet "pot2plus" ; +oper pot3 : Sub1000 -> Sub1000000 = notYet "pot3" ; +oper pot3plus : Sub1000 -> Sub1000 -> Sub1000000 = notYet "pot3plus" ; +oper quite_Adv : AdA = notYet "quite_Adv" ; +oper right_Ord : Ord = notYet "right_Ord" ; +oper she_Pron : Pron = notYet "she_Pron" ; +oper so_AdA : AdA = notYet "so_AdA" ; +oper somePl_Det : Det = notYet "somePl_Det" ; +oper someSg_Det : Det = notYet "someSg_Det" ; +oper somebody_NP : NP = notYet "somebody_NP" ; +oper something_NP : NP = notYet "something_NP" ; +oper somewhere_Adv : Adv = notYet "somewhere_Adv" ; +oper that_Quant : Quant = notYet "that_Quant" ; +oper that_Subj : Subj = notYet "that_Subj" ; +oper there7from_Adv : Adv = notYet "there7from_Adv" ; +oper there7to_Adv : Adv = notYet "there7to_Adv" ; +oper there_Adv : Adv = notYet "there_Adv" ; +oper therefore_PConj : PConj = notYet "therefore_PConj" ; +oper they_Pron : Pron = notYet "they_Pron" ; +oper this_Quant : Quant = notYet "this_Quant" ; +oper through_Prep : Prep = notYet "through_Prep" ; +oper to_Prep : Prep = notYet "to_Prep" ; +oper too_AdA : AdA = notYet "too_AdA" ; +oper under_Prep : Prep = notYet "under_Prep" ; +oper very_AdA : AdA = notYet "very_AdA" ; +oper we_Pron : Pron = notYet "we_Pron" ; +oper whatPl_IP : IP = notYet "whatPl_IP" ; +oper whatSg_IP : IP = notYet "whatSg_IP" ; +oper when_IAdv : IAdv = notYet "when_IAdv" ; +oper when_Subj : Subj = notYet "when_Subj" ; +oper where_IAdv : IAdv = notYet "where_IAdv" ; +oper which_IQuant : IQuant = notYet "which_IQuant" ; +oper whoPl_IP : IP = notYet "whoPl_IP" ; +oper whoSg_IP : IP = notYet "whoSg_IP" ; +oper why_IAdv : IAdv = notYet "why_IAdv" ; +oper with_Prep : Prep = notYet "with_Prep" ; +oper without_Prep : Prep = notYet "without_Prep" ; +oper yes_Utt : Utt = notYet "yes_Utt" ; +oper youPl_Pron : Pron = notYet "youPl_Pron" ; +oper youPol_Pron : Pron = notYet "youPol_Pron" ; +oper youSg_Pron : Pron = notYet "youSg_Pron" ; +} diff --git a/src/gaelic/NamesGla.gf b/src/gaelic/NamesGla.gf new file mode 100644 index 00000000..7283f091 --- /dev/null +++ b/src/gaelic/NamesGla.gf @@ -0,0 +1,36 @@ +concrete NamesGla of Names = CatGla ** open Prelude in { + +-- An API layer to deal with names +-- Not part of the RGL API, but used in the AW project +-- So depends on your goals whether this is high or low priority to implement. +{- + lin + -- : GN -> NP ; + GivenName gn = + + -- : SN -> NP ; + MaleSurname sn = + + -- : SN -> NP ; + FemaleSurname sn = + + -- : SN -> NP ; + PlSurname sn = + + -- : GN -> SN -> NP ; + FullName gn sn = + + lin + -- : LN -> NP ; + UseLN ln = + + -- : LN -> NP ; + PlainLN ln = + + -- : LN -> Adv ; + InLN ln = + + -- : AP -> LN -> LN ; + AdjLN ap ln = +-} +} diff --git a/src/gaelic/NounGla.gf b/src/gaelic/NounGla.gf new file mode 100644 index 00000000..24507a91 --- /dev/null +++ b/src/gaelic/NounGla.gf @@ -0,0 +1,210 @@ +concrete NounGla of Noun = CatGla ** open ResGla, Prelude in { + + flags optimize=all_subs ; + + lin + +--2 Noun phrases + +-- : Det -> CN -> NP + DetCN det cn = emptyNP ** { + s = det.s ++ cn.s ! det.n + } ; +{- + -- : PN -> NP ; + -- Assuming that lincat PN = lincat NP + UsePN pn = pn ; + + -- : Pron -> NP ; + -- Assuming that lincat Pron = lincat NP + UsePron pron = pron ; + + -- : Predet -> NP -> NP ; -- only the man + PredetNP predet np = + +-- A noun phrase can also be postmodified by the past participle of a +-- verb, by an adverb, or by a relative clause + + -- low prio + -- : NP -> V2 -> NP ; -- the man seen + -- PPartNP np v2 = np ** { + -- s = + -- } ; + + -- : NP -> Adv -> NP ; -- Paris today + AdvNP np adv = np ** { + s = np.s ++ "," ++ adv.s + } ; + + -- : NP -> Adv -> NP ; -- boys, such as .. + ExtAdvNP np adv = AdvNP np {s = "," ++ adv.s} ; + + -- : NP -> RS -> NP ; -- Paris, which is here + RelNP np rs = np ** { + + } ; + +-- Determiners can form noun phrases directly. + + -- : Det -> NP ; + DetNP det = emptyNP ** { + s = \\_ => linDet det ; + } ; +-} + -- MassNP : CN -> NP ; + MassNP cn = emptyNP ** { + s = linCN cn + } ; + + +--2 Determiners + +-- The determiner has a fine-grained structure, in which a 'nucleus' +-- quantifier and an optional numeral can be discerned. + + -- : Quant -> Num -> Det ; + DetQuant quant num = quant ** { + s = quant.s ! num.n ++ num.s ; + n = num.n ; + } ; + + -- : Quant -> Num -> Ord -> Det ; + -- DetQuantOrd quant num ord = quant ** { + + -- } ; + +-- Whether the resulting determiner is singular or plural depends on the +-- cardinal. + +-- All parts of the determiner can be empty, except $Quant$, which is +-- the "kernel" of a determiner. It is, however, the $Num$ that determines +-- the inherent number. + + NumSg = {s = [] ; n = Sg} ; + NumPl = {s = [] ; n = Pl} ; + +{- + -- : Card -> Num ; -- two + NumCard card = card ; + + -- : Digits -> Card ; + NumDigits dig = -- probably like OrdDigits, but choose the NCard form + + -- : Numeral -> Card ; + NumNumeral num = { + s = num.s ! NCard ; + n = num.n -- inherits grammatical number (Sg, Pl, …) from the Numeral + } ; + + -- : AdN -> Card -> Card ; + AdNum adn card = card ** { s = adn.s ++ card.s } ; + + -- : Digits -> Ord ; + OrdDigits digs = digs ** { s = digs.s ! NOrd } ; + + -- : Numeral -> Ord ; + OrdNumeral num = { + s = num.s ! NOrd + } ; + + -- : A -> Ord ; + OrdSuperl a = { + s = "most" ++ a.s ! Superl + } ; + +-- One can combine a numeral and a superlative. + + -- : Numeral -> A -> Ord ; -- third largest + OrdNumeralSuperl num a = { + s = num.s ! NOrd ++ a.s ! Superl + } ; +-} + + -- : Quant + DefArt = mkQuant "the" "the" ; + + -- : Quant + IndefArt = mkQuant "a" [] ; + +{- + -- : Pron -> Quant -- my + PossPron pron = mkQuant pron.s ** { + + } ; +-} + +--2 Common nouns + + -- : N -> CN + UseN n = n ; + +{- + -- : N2 -> CN ; + UseN2 n2 = + + -- : N2 -> NP -> CN ; + ComplN2 n2 np = + + -- : N3 -> NP -> N2 ; -- distance from this city (to Paris) + ComplN3 n3 np = + + -- : N3 -> N2 ; -- distance (from this city) + Use2N3 n3 = lin N2 n3 ** { c2 = n3.c3 } ; + + -- : N3 -> N2 ; -- distance (to Paris) + Use3N3 n3 = lin N2 n3 ; + + -- : AP -> CN -> CN + AdjCN ap cn = + + -- : CN -> RS -> CN ; + RelCN cn rs = + + + -- : CN -> Adv -> CN ; + AdvCN cn adv = + +-- Nouns can also be modified by embedded sentences and questions. +-- For some nouns this makes little sense, but we leave this for applications +-- to decide. Sentential complements are defined in VerbGla. + + -- : CN -> SC -> CN ; -- question where she sleeps + SentCN cn sc = + +--2 Apposition + +-- This is certainly overgenerating. + + -- : CN -> NP -> CN ; -- city Paris (, numbers x and y) + ApposCN cn np = cn ** { + s = + } ; + +--2 Possessive and partitive constructs +-- NB. Below this, the functions are not in the API, so lower prio to implement + + -- : PossNP : CN -> NP -> CN ; + -- in English: book of someone; point is that we can add a determiner to the CN, + -- so it can become "a book of someone" or "the book of someone" + PossNP cn np = + + + -- : Det -> NP -> NP ; -- three of them, some of the boys + CountNP det np = -- Nonsense for DefArt or IndefArt, but don't worry about that! RGL can contain weird sentences, as long as it contains the non-weird stuff we want + + + -- : CN -> NP -> CN ; -- glass of wine / two kilos of red apples + PartNP cn np = + +--3 Conjoinable determiners and ones with adjectives + + -- : DAP -> AP -> DAP ; -- the large (one) + AdjDAP dap ap = dap ** { + + } ; + + -- : Det -> DAP ; -- this (or that) + DetDAP det = det ; +-} + +} diff --git a/src/gaelic/NumeralGla.gf b/src/gaelic/NumeralGla.gf new file mode 100644 index 00000000..a7e3af7c --- /dev/null +++ b/src/gaelic/NumeralGla.gf @@ -0,0 +1,115 @@ +concrete NumeralGla of Numeral = CatGla [Numeral,Digits] ** + open Prelude, ResGla in { + + lincat + Digit = LinNumeral ; -- 2..9 + Sub10, -- 1..9 + Sub100, -- 1..99 + Sub1000, -- 1..999 + Sub1000000, -- 1..999999 + Sub1000000000, -- 1..999999999 + Sub1000000000000 -- 1..999999999999 + = LinNumeral ; + +-- param CardOrd defined in ResGla +-- type LinNumeral -""- + + + lin + -- : Sub1000000 -> Numeral ; -- 123456 [coercion to top category] + num x = x ; + + -- : Digit ; + n2 = mkNumeral "two" ; + n3 = mkNumeral "three" ; + n4 = mkNumeral "four" ; + n5 = mkNumeral "five" ; + n6 = mkNumeral "six" ; + n7 = mkNumeral "seven" ; + n8 = mkNumeral "eight" ; + n9 = mkNumeral "nine" ; + + -- : Sub10 ; -- 1 + -- pot01 = + + -- : Digit -> Sub10 ; -- d * 1 + pot0 d = d ; + + -- : Sub100 ; -- 10 + -- pot110 = mkNum "ten" ; + + -- : Sub100 ; -- 11 + -- pot111 = mkNum "eleven" ; + + -- : Digit -> Sub100 ; -- 10 + d + -- pot1to19 d = + + -- : Sub10 -> Sub100 ; -- coercion of 1..9 + pot0as1 n = n ; + + -- : Digit -> Sub100 ; -- d * 10 + -- pot1 d = + + -- : Digit -> Sub10 -> Sub100 ; -- d * 10 + n + -- pot1plus d e = + + -- : Sub100 -> Sub1000 ; -- coercion of 1..99 + pot1as2 n = n ; + + -- : Sub10 -> Sub1000 ; -- m * 100 + -- pot2 d = + + -- : Sub10 -> Sub100 -> Sub1000 ; -- m * 100 + n + -- pot2plus d e = + + -- : Sub1000 -> Sub1000000 ; -- coercion of 1..999 + pot2as3 n = n ; + + -- : Sub1000 -> Sub1000000 ; -- m * 1000 + -- pot3 d = + + -- : Sub1000 -> Sub1000 -> Sub1000000 ; -- m * 1000 + n + -- pot3plus d e = + +-------------------------------------------------------------------------------- +-- Numerals as sequences of digits have a separate, simpler grammar +-- + + lincat + Dig = LinDig ; -- single digit 0..9 + + lin + -- : Dig -> Digits ; -- 8 + IDig d = d ; + + -- : Dig -> Digits -> Digits ; -- 876 + IIDig d e = { + s = table { + NCard => glue (d.s ! NCard) (e.s ! NCard) ; + NOrd => glue (d.s ! NCard) (e.s ! NOrd) + } ; + n = Pl ; + } ; + + -- : Dig ; + D_0 = mkDig "0" ; + D_1 = mkDig "1" ; + D_2 = mkDig "2" ; + D_3 = mkDig "3" ; + D_4 = mkDig "4" ; + D_5 = mkDig "5" ; + D_6 = mkDig "6" ; + D_7 = mkDig "7" ; + D_8 = mkDig "8" ; + D_9 = mkDig "9" ; + + oper + LinDig : Type = {s : CardOrd => Str ; n : Number} ; + mkDig : Str -> LinDig = \s -> { + s = table { + NCard => s ; + NOrd => s + "th" + } ; + n = Pl ; -- TODO: handle number 1 + } ; +} diff --git a/src/gaelic/ParadigmsGla.gf b/src/gaelic/ParadigmsGla.gf new file mode 100644 index 00000000..330df734 --- /dev/null +++ b/src/gaelic/ParadigmsGla.gf @@ -0,0 +1,211 @@ +resource ParadigmsGla = open CatGla, ResGla, NounGla, Prelude in { + +oper + +--2 Parameters +-- +-- To abstract over number, valency and (some) case names, +-- we define the following identifiers. The application programmer +-- should always use these constants instead of the constructors +-- defined in $ResSom$. + + Prep : Type ; + noPrep : Prep ; + + -- Add more overload instances if needed for all categories! + +--2 Nouns + + mkN : overload { + mkN : Str -> N ; -- Predictable nouns + } ; + + mkPN : overload { + mkPN : Str -> PN ; -- Proper nouns + } ; + +--2 Adjectives + + mkA : overload { + mkA : Str -> A ; -- Predictable adjective + } ; + + mkA2 : overload { + mkA2 : Str -> A2 ; -- Predictable A2, no preposition + mkA2 : A -> Prep -> A2 ; -- A2 made from A and Prep + } ; + +--2 Verbs + + -- Verbs + mkV : overload { + mkV : Str -> V ; -- Predictable verb + } ; + + + mkV2 : overload { + mkV2 : Str -> V2 ; -- Predictable transitive verb + mkV2 : V -> Prep -> V2 ; -- V2 made from V and Prep + } ; + + mkV3 : overload { + mkV3 : V -> V3 ; -- No prepositions + mkV3 : V -> Prep -> Prep -> V3 ; -- Prepositions for direct and indirect objects given + } ; + + mkVV : overload { + mkVV : V -> VV ; + } ; + + mkVA : overload { + mkVA : V -> VA ; + } ; + + mkVQ : overload { + mkVQ : V -> VQ ; + } ; + + mkVS : overload { + mkV : V -> VS ; + } ; + + -- Etc. do the same for other V subcats (V2A, V2V, V2S, …) + + + ----- + +--2 Structural categories + + -- If prepositions take case, add that as argument to mkPrep + mkPrep : overload { + mkPrep : Str -> Prep ; + } ; + + mkConj : overload { + mkConj : (and : Str) -> Conj ; -- (coffee) and (tea) + mkConj : (either : Str) -> (or : Str) -> Conj ; -- either (coffee) or (tea) + } ; + + mkSubj : overload { + mkSubj : Str -> Subj ; + } ; + + mkAdv : overload { + mkAdv : Str -> Adv ; + } ; + + mkAdV : overload { + mkAdV : Str -> AdV ; + } ; + + mkAdA : overload { + mkAdA : Str -> AdA ; + } ; + + +--. +------------------------------------------------------------------------------- +-- The definitions should not bother the user of the API. So they are +-- hidden from the document. + + Prep = CatGla.Prep ; + noPrep = mkPrep [] ; + + -- Add more overload instances if needed for all categories! + + -- For explanation of `lin N`, see + -- https://inariksit.github.io/gf/2018/05/25/subtyping-gf.html#lock-fields + + mkN = overload { + mkN : Str -> N = \s -> lin N (ResGla.mkNoun s) ; + -- TODO: more overload instances + } ; + +{- + mkPN = overload { + mkPN : Str -> PN = … + } ; + +--2 Adjectives + + mkA = overload { + mkA : Str -> A = \s -> … + } ; + + mkA2 = overload { + mkA2 : Str -> A2 = \s -> … + mkA2 : A -> Prep -> A2 = \s -> … + } ; + +--2 Verbs +-} + -- Verbs + mkV = overload { + mkV : Str -> V = \s -> lin V (mkVerb s) ; + } ; + +{- + + mkV2 = overload { + mkV2 : Str -> V2 = \s -> … + mkV2 : V -> Prep -> V2 = \s -> … + } ; + + mkV3 = overload { + mkV3 : V -> V3 = \s -> … + mkV3 : V -> Prep -> Prep -> V3 = \s -> … + } ; + + mkVV = overload { + mkVV : V -> VV = \s -> … + } ; + + mkVA = overload { + mkVA : V -> VA = \s -> … + } ; + + mkVQ = overload { + mkVQ : V -> VQ = \s -> … + } ; + + + mkVS = overload { + mkV : V -> VS = \s -> … + } ; + + -- Etc. do the same for other V subcats (V2A, V2V, V2S, …) + + + ----- +-} + + -- If prepositions take case, add that as argument to mkPrep + mkPrep = overload { + mkPrep : Str -> Prep = \s -> lin Prep {s = s} ; + } ; +{- + mkConj = overload { + mkConj : (and : Str) -> Conj = \s -> … + mkConj : (either : Str) -> (or : Str) -> Conj = \s -> … + } ; + + mkSubj = overload { + mkSubj : Str -> Subj = \s -> … + } ; + + mkAdv = overload { + mkAdv : Str -> Adv = \s -> … + } ; + + mkAdV = overload { + mkAdV : Str -> AdV = \s -> … + } ; + + mkAdA = overload { + mkAdA : Str -> AdA = \s -> … + } ; + +-} +-------------------------------------------------------------------------------- + +} diff --git a/src/gaelic/PhraseGla.gf b/src/gaelic/PhraseGla.gf new file mode 100644 index 00000000..a8a5ad3b --- /dev/null +++ b/src/gaelic/PhraseGla.gf @@ -0,0 +1,27 @@ +concrete PhraseGla of Phrase = CatGla ** open Prelude, ResGla in { + + lin + PhrUtt pconj utt voc = {s = pconj.s ++ utt.s ++ voc.s} ; + + UttS s = s ; +{- + UttQS qs = qs ; + UttIAdv iadv = iadv ; + UttNP np = + UttIP ip = + UttImpSg pol imp = { s = pol.s ++ imp.s ! Sg ! pol.p } ; + UttImpPl pol imp = + UttImpPol pol imp = {s = pol.s ++ imp.s ! Sg ! pol.p} ; + UttVP vp = {s = linVP vp} ; + UttAP ap = { s = ap.s } ; + UttAdv adv = {s = } ; + UttCN n = {s = } ; + UttCard n = {s = } ; + UttInterj i = i ; -} + NoPConj = {s = []} ; +-- PConjConj conj = {s = conj.s1 ++ conj.s2 ! …} ; + + NoVoc = {s = []} ; +-- VocNP np = { s = "," ++ np.s ! … } ; + +} diff --git a/src/gaelic/QuestionGla.gf b/src/gaelic/QuestionGla.gf new file mode 100644 index 00000000..d568c3bb --- /dev/null +++ b/src/gaelic/QuestionGla.gf @@ -0,0 +1,105 @@ +concrete QuestionGla of Question = CatGla ** open + Prelude, ResGla, ParadigmsGla, (V=VerbGla), (Noun=NounGla), (S=StructuralGla) in { + +-- A question can be formed from a clause ('yes-no question') or +-- with an interrogative. +-- Interrogative pronouns can be formed with interrogative +-- determiners, with or without a noun. + +{- +lin + -- : IDet -> CN -> IP ; -- which five songs + IdetCN idet cn = Noun.DetCN idet cn ** { + } ; + + -- : IDet -> IP ; -- which five + IdetIP idet = Noun.DetNP idet ** {sp = idet.sp}; + + -- : IQuant -> Num -> IDet ; -- which (five) + IdetQuant iquant num = iquant ** { + } ; + + -- : IP -> ClSlash -> QCl ; -- whom does John love + QuestSlash ip cls = cls ** { + + } ; + + -- : Cl -> QCl ; + QuestCl cl = cl ** { + }; + + + -- : IP -> VP -> QCl ; + QuestVP ip cl = cl ** { + } ; + + -- : IAdv -> Cl -> QCl ; -- why does John walk + QuestIAdv iadv cls = { + } ; + + -- : IP -> IComp ; + CompIP ip = {s = ip.s ! } ; -- who (is it) + + -- : IComp -> NP -> QCl ; -- where is John? + QuestIComp icomp np = { + } ; + + +-- Interrogative pronouns can be formed with interrogative +-- determiners, with or without a noun. + + -- : IDet -> CN -> IP ; -- which five songs + IdetCN idet cn = + + -- : IDet -> IP ; -- which five + IdetIP idet = + +-- They can be modified with adverbs. + + -- : IP -> Adv -> IP ; -- who in Paris + AdvIP = Noun.AdvNP ; + +-- Interrogative quantifiers have number forms and can take number modifiers. + + -- : IQuant -> Num -> IDet ; -- which (five) + IdetQuant = Noun.DetQuant ; + +-- Interrogative adverbs can be formed prepositionally. + -- : Prep -> IP -> IAdv ; -- with whom + PrepIP prep ip = + +-- They can be modified with other adverbs. + + -- : IAdv -> Adv -> IAdv ; -- where in Paris + AdvIAdv iadv adv = + +-- Interrogative complements to copulas can be both adverbs and +-- pronouns. + + -- : IAdv -> IComp ; + CompIAdv iadv = iadv ; -- where (is it) + + +-- More $IP$, $IDet$, and $IAdv$ are defined in $Structural$. + +-- Wh questions with two or more question words require a new, special category. + + lincat + -- buy what where + QVP = + lin + -- : VPSlash -> IP -> QVP ; -- buys what + ComplSlashIP vps ip = + + -- : VP -> IAdv -> QVP ; -- lives where + AdvQVP vp iadv = + + -- : QVP -> IAdv -> QVP ; -- buys what where + AddAdvQVP qvp iadv = + + -- : IP -> QVP -> QCl ; -- who buys what where + QuestQVP ip qvp = +-} + + +} diff --git a/src/gaelic/RelativeGla.gf b/src/gaelic/RelativeGla.gf new file mode 100644 index 00000000..9abc5c36 --- /dev/null +++ b/src/gaelic/RelativeGla.gf @@ -0,0 +1,24 @@ +concrete RelativeGla of Relative = CatGla ** open + ResGla, Prelude in { + +{- +lin + -- : Cl -> RCl ; -- such that John loves her + RelCl cl = cl ** { + } ; + + -- : RP -> VP -> RCl ; + RelVP rp vp = { + } ; + + -- : RP -> ClSlash -> RCl ; -- who I went with + RelSlash rp cls = { + } ; + + -- : RP ; + IdRP = {s = "that"} ; + + -- : Prep -> NP -> RP -> RP ; -- the mother of whom + FunRP prep np rp = +-} +} diff --git a/src/gaelic/ResGla.gf b/src/gaelic/ResGla.gf new file mode 100644 index 00000000..dc277483 --- /dev/null +++ b/src/gaelic/ResGla.gf @@ -0,0 +1,275 @@ +resource ResGla = open Prelude, Predef in { + +-------------------------------------------------------------------------------- +-- General notes + +-- ** Naming ** +{- +I'm using the naming scheme for lincats and opers as explained here: +https://inariksit.github.io/gf/2018/08/28/gf-gotchas.html#my-naming-scheme-for-lincats-and-opers +-} + +-- ** File structure ** +-- The rest of this module is organised as follows: + + ----------------------------- + -- Grammatical categor(y|ies) + + {- + General comments on the cat(s) + + params related to the cat(s) + + opers related to the cat(s) + -} + +-------------------------------------------------------------------------------- +-- Nouns + + +param + Gender = Masc | Fem ; + Case = Nom | Gen | Dat | Voc ; + Number = Sg + | Pl + | Dual -- only after number 2 + ; + Person = P1 | P2 | P3 ; + +oper + LinN : Type = { + s : + Number => + Case => + Str ; + g : Gender ; + } ; + + -- Most often, the lincat for CN is the same as N, with possibly some additional fields. + -- However, sometimes you need more fields than just the s field, e.g. to keep word order flexible, or to add clitics and make sure they attach to the head, not modifiers. + -- If you don't know what the previous line means, you can get started with just a single s field. + -- You'll notice later whether you need such a field or not. + LinCN : Type = LinN + -- ** {postmod/premod/… : Str} -- if needed + ; + + LinPN : Type = { + s : Str ; + n : Number ; -- Proper nouns often have already an inherent number; you don't usually say "a Paris / many Parises" + g : Gender ; -- inherent gender/noun class, if your language has that + } ; + + -- For inflection paradigms, see http://www.grammaticalframework.org/doc/tutorial/gf-tutorial.html#toc56 + mkNoun : Str -> Gender -> LinN = \str,g -> { + s = table { + _ => \\_ => str -- TODO: actual morphology + } ; + g = g ; + -- If your nouns have gender, it should come here as inherent field. + -- Usually you need to give the gender as an argument to mkNoun. + } ; + + linCN : LinCN -> Str = \cn -> cn.s ! Sg ! Nom + -- ++ cn.postmod -- If there is another field, use here + ; + +--------------------------------------------- +-- Numeral + +-- Used in NumeralGla + param + CardOrd = NCard | NOrd ; + + oper + LinNumeral : Type = {s : CardOrd => Str ; n : Number} ; + + mkNumeral : (card, ord : Str) -> LinNumeral = \card,ord -> { + s = table { + NCard => card ; -- aon(a) -- TODO: allomorph of this depends on the following word? + NOrd => ord -- a' chiad + } ; + n = Pl ; -- NB. singular for 1, 2, 20 + multiples of 20 and 100 (Lamb, p. 218) + } ; + +--------------------------------------------- +-- Pronoun + + +oper + LinPron : Type = { + s : Case => Str ; + n : Number ; + p : Person ; + -- g : Gender ; ?? -- we have already he_Pron and she_Pron in abstract syntax, does this affect inflection? + } ; + + mkPron : (_ : Str) -> Person -> Number -> LinPron = \str,per,num -> { + s = \\_ => str ; -- Pronoun inflection is often irregular, so possibly this constructor requires several forms as argument, even if mkNoun is nice and regular + p = per ; + n = num ; + } ; + +--------------------------------------------- +-- NP + +{- +In the RGL, a NP may come from a common noun, proper noun or pronoun. +Pronouns are the only ones that have an inherent person (nouns are almost always 3rd person! please give me counterexamples if you can think of any.) +So we can often say that NP's lincat is the same as Prons. + +NB. for later, when you want to make Pron into possessives, you may need more fields in LinPron than in LinNP. +That's why I'm copying over the definition below, instead of the neater `LinNP : Type = LinPron`. +-} + +param + Definiteness = Definite | Indefinite ; + -- Some prepositions govern different case when definite vs. indefinite + +oper + LinNP : Type = { +-- art : Str ; -- to be replaced with a combo coming from Prep, if argument of PrepNP? see Lamb p. 225 + -- TODO: is that an issue when the allomorph has been chosen by an inherent param in CN? + -- does that param need to be kept in LinNP, and Prep need an inflection table from that param? + -- or do we have an exhaustive list of prepositions that merge, and we can make that into a param and put on a LHS here? + + s : Case => Str ; -- TODO: is lenition a separate dimension from case? + + -- TODO can we make this combo of inherent params leaner? + n : Number ; + p : Person ; + d : Definiteness ; + } ; + + linNP : LinNP -> Str = \np -> np.s ! Nom ; + + emptyNP : LinNP = { + s = \\_ => [] ; + n = Sg ; + p = P3 ; + d = Indefinite ; + } ; + +-------------------------------------------------------------------------------- +-- Det, Quant, Card, Ord + + -- If your language has a number, it is very very very likely that + -- Quant has a variable number and Det has inherent number. + + LinQuant : Type = { + s, -- quantifier in a context, e.g. 'this (cat) (is nice)' + sp -- quantifier as standalone, e.g. 'this (is nice)' + : Number => Str ; + } ; + + LinDet : Type = { + s,s2 : Str ; + n : Number ; + } ; + + -- Can you reuse your mkNoun? Do nouns and quantifiers inflect the same way? + mkQuant : Str -> Str -> LinQuant = \this, these -> { + s, + sp = table { + Sg => this ; + _ => these } ; + }; + + mkDet : (seven, teen : Str) -> Number -> LinDet = \aon, deug, num -> { + s = aon ; + s2 = deug ; + n = num + } ; + +-------------------------------------------------------------------------------- +-- Adpositions + +{- The main use of Prep is in the fun + + PrepNP : Prep -> NP -> Adv + + Despite the name of the RGL category, a 'Prep' can be a preposition, postposition, + or just an instruction to choose a particular case from the NP. + A language may use one, two or all these strategies. + +-} + +-- TODO: prepositions can merge with articles +-- Lamb, page 210: obair _sa_ cheàrdaich 'working _in+the_ forge' + +-- more on preps: Lamb, p.224 + +oper + LinPrep : Type = { + s : Str ; + + c2 : Definiteness => Case ; -- most often dative + + + -- If your language has both pre- and postpositions, you need an inherent parameter in Prep to record which one a given Prep is. + -- position : PreOrPost ; + + -- Some cause lenition—is that separate from case? + } ; + + +-------------------------------------------------------------------------------- +-- Adjectives +-- Lamb p. 220 basic morphology, degree +-- Lamb p. 246: predicative adjectives + + LinA : Type = SS ; + LinA2 : Type = LinA ; + + mkAdj : Str -> LinA = \str -> {s = str} ; + + AdjPhrase : Type = LinA ; -- ** {compar : Str} ; +-------------------------------------------------------------------------------- +-- Verbs + +param + VForm = TODOVF Number Person ; + +oper + LinV : Type = { + s : VForm => Str + } ; + + LinV2 : Type = LinV ** { + c2 : LinPrep ; + } ; + + mkVerb : Str -> LinV = \str -> { + s = table { + _ => str + } + } ; + + copula : LinV = {s = \\_ => "TODO: copula"} ; -- often useful + +------------------ +-- VP +-- Lamb p. 229 +-- "tense, aspect, modality, voice, person and number. There are contrasts to be seen, as above, between inflected and periphrastic forms and, as a whole, periphrasis is more productive." + + LinVP : Type = { + s : VForm => Str ; + } ; + + LinVPSlash : Type = LinVP ** { + c2 : LinPrep ; + } ; + + linVP : LinVP -> Str = \vp -> vp.s ! TODOVF Sg P3 ; + +-------------------------------------------------------------------------------- +-- Cl, S + + -- Operations for clauses, sentences + LinCl : Type = { + subj : Str ; + pred : Str ; -- TODO: depend on Temp and Pol + } ; + + linCl : LinCl -> Str = \cl -> cl.subj ++ cl.pred ; + +} diff --git a/src/gaelic/SentenceGla.gf b/src/gaelic/SentenceGla.gf new file mode 100644 index 00000000..893e105a --- /dev/null +++ b/src/gaelic/SentenceGla.gf @@ -0,0 +1,76 @@ + +concrete SentenceGla of Sentence = CatGla ** open + TenseX, ResGla, (AM=AdverbGla), Prelude in { + +flags optimize=all_subs ; + +lin + +--2 Clauses + + -- : NP -> VP -> Cl + PredVP np vp = { + subj = np.s ; -- ! Nom, if there are cases + pred = + -- table {something with tense+polarity => + vp.s ! TODOVF np.n np.p + -- TODO: all of the VP's tense and polarity should be open here! + -- PredVP only decides the subject. + -- } + } ; + +{- + -- : SC -> VP -> Cl ; -- that she goes is good + PredSCVP sc vp = ; + +--2 Clauses missing object noun phrases + -- : NP -> VPSlash -> ClSlash ; + SlashVP = + + -- : ClSlash -> Adv -> ClSlash ; -- (whom) he sees today + AdvSlash cls adv = + + -- : Cl -> Prep -> ClSlash ; -- (with whom) he walks + SlashPrep cl prep = cl ** {c2 = prep} ; + +-- Imperatives + -- : VP -> Imp ; + ImpVP vp = + +--2 Embedded sentences + + -- : S -> SC ; + EmbedS s = + + -- : QS -> SC ; + EmbedQS qs = + + -- : VP -> SC ; + EmbedVP vp = +-} +--2 Sentences + + -- : Temp -> Pol -> Cl -> S ; + UseCl t p cl = { + s = cl.subj ++ t.s ++ p.s ++ cl.pred -- ! t.t ! p.p -- eventually + } ; +{- + -- : Temp -> Pol -> QCl -> QS ; + UseQCl t p cl = + + -- : Temp -> Pol -> RCl -> RS ; + UseRCl t p cl = + + -- AdvS : Adv -> S -> S ; -- then I will go home + AdvS adv s = + + -- ExtAdvS : Adv -> S -> S ; -- next week, I will go home + ExtAdvS adv s = + + -- : S -> Subj -> S -> S ; + SSubjS s1 subj s2 = + + -- : S -> RS -> S ; -- she sleeps, which is good + RelS sent rs = +-} +} diff --git a/src/gaelic/StructuralGla.gf b/src/gaelic/StructuralGla.gf new file mode 100644 index 00000000..e76d33ca --- /dev/null +++ b/src/gaelic/StructuralGla.gf @@ -0,0 +1,171 @@ +concrete StructuralGla of Structural = CatGla ** + open Prelude, ResGla, (Noun=NounGla), ParadigmsGla in { + +------- +-- Ad* +{- +lin almost_AdA = +lin almost_AdN = +lin at_least_AdN = +lin at_most_AdN = +lin so_AdA = +lin too_AdA = +lin very_AdA = + +lin as_CAdv = +lin less_CAdv = +lin more_CAdv = + +lin how8much_IAdv = +lin when_IAdv = + +lin how_IAdv = +lin where_IAdv = +lin why_IAdv = + +lin always_AdV = ss "" ; + +lin everywhere_Adv = ss "" ; +lin here7from_Adv = ss "" ; +lin here7to_Adv = ss "" ; +lin here_Adv = ss "" ; +lin quite_Adv = ss "" ; +lin somewhere_Adv = ss "" ; +lin there7from_Adv = ss "" ; +lin there7to_Adv = ss "" ; +lin there_Adv = ss "" ; + +-} +------- +-- Conj + +-- The lincat of Conj is Coordination.ConjunctionDistr ** {n:Number} +-- which means that there are two fields for the strings, and +-- n:Number which specifies the number of the resulting NP. + +lin and_Conj = {s1 = [] ; s2 = "and" ; n = Pl} ; +-- lin or_Conj = +-- lin if_then_Conj = +lin both7and_DConj = {s1 = "both" ; s2 = "and" ; n = Pl} ; +-- lin either7or_DConj = + +-- lin but_PConj = +-- lin otherwise_PConj = +-- lin therefore_PConj = + + +----------------- +-- *Det and Quant +{- +lin how8many_IDet = +lin every_Det = + +lin all_Predet = {s = ""} ; +lin not_Predet = { s = "" } ; +lin only_Predet = { s = "" } ; +lin most_Predet = {s = ""} ; + +lin few_Det = R.indefDet "" pl ; +lin many_Det = R.indefDet "" pl ; +lin much_Det = R.indefDet "" sg ; + +lin somePl_Det = +lin someSg_Det = + +lin no_Quant = +lin that_Quant = mkQuant "" ; +lin this_Quant = mkQuant "" ; +lin which_IQuant = mkQuant "" ; + +----- +-- NP + +lin somebody_NP = + + +lin everybody_NP = +lin everything_NP = +lin nobody_NP = +lin nothing_NP = +lin somebody_NP = +lin something_NP = + +------- +-- Prep + +lin above_Prep = mkPrep "" ; +lin after_Prep = mkPrep "" ; +lin before_Prep = mkPrep "" ; +lin behind_Prep = mkPrep "" ; +lin between_Prep = = mkPrep "" ; +lin by8agent_Prep = mkPrep "" ; +lin by8means_Prep = mkPrep "" ; +lin during_Prep = mkPrep "" ; +lin except_Prep = mkPrep "" ; +lin for_Prep = mkPrep "" ; +lin from_Prep = mkPrep "" ; +lin in8front_Prep = mkPrep "" ; +lin in_Prep = mkPrep "" ; +lin on_Prep = mkPrep "" ; +lin part_Prep = mkPrep ; +lin possess_Prep = mkPrep "" ; +lin through_Prep = mkPrep "" ; +lin to_Prep = mkPrep "k" ; +lin under_Prep = mkPrep "" ; +lin with_Prep = mkPrep "" ; +lin without_Prep = mkPrep "" ; + +------- +-- Pron + +-- Pronouns are closed class, no constructor in ParadigmsGla. +lin it_Pron = +lin i_Pron = +lin youPol_Pron = +lin youSg_Pron = +lin he_Pron = +lin she_Pron = +lin we_Pron = +lin youPl_Pron = +lin they_Pron = + +lin whatPl_IP = +lin whatSg_IP = +lin whoPl_IP = +lin whoSg_IP = + +------- +-- Subj + +lin although_Subj = +lin because_Subj = +lin if_Subj = +lin that_Subj = +lin when_Subj = + + +------ +-- Utt + +lin language_title_Utt = ss "" ; +lin no_Utt = ss "" ; +lin yes_Utt = ss "" ; + + +------- +-- Verb + +lin have_V2 = + +lin can8know_VV = -- can (capacity) +lin can_VV = -- can (possibility) +lin must_VV = +lin want_VV = + +------ +-- Voc + +lin please_Voc = ss "" ; +-} + +} diff --git a/src/gaelic/SymbolGla.gf b/src/gaelic/SymbolGla.gf new file mode 100644 index 00000000..0878fe29 --- /dev/null +++ b/src/gaelic/SymbolGla.gf @@ -0,0 +1,73 @@ +--# -path=.:../abstract:../common:../prelude + +concrete SymbolGla of Symbol = CatGla ** + open Prelude, ParadigmsGla, ResGla, (Noun=NounGla) in { + +lin + + -- : Symb -> PN ; -- x + SymbPN i = mkPN_onRuntimeToken i.s ; + + -- : Int -> PN ; -- 27 + IntPN i = mkPN_onRuntimeToken i.s ; + + -- : Float -> PN ; -- 3.14159 + FloatPN i = mkPN_onRuntimeToken i.s ; + + -- : Card -> PN ; -- twelve [as proper name] + NumPN i = mkPN_onRuntimeToken (i.s ! NCard) ; + +lin +-- CNIntNP cn i = {} ; + + -- : Det -> CN -> [Symb] -> NP ; -- (the) (2) numbers x and y + CNSymbNP det cn xs = + let cnSymb : CN = cn ** {postmod = cn.postmod ++ xs.s} + in Noun.DetCN det cnSymb ; + + -- : CN -> Card -> NP ; -- level five ; level 5 + CNNumNP cn i = + let cnSymb : CN = cn ** {postmod = cn.postmod ++ i.s} + in Noun.MassNP cnSymb ; + + -- : Symb -> S ; + SymbS sy = sy ; + + -- : Symb -> Card ; + SymbNum sy = mkNumeral_onRuntimeToken sy.s ; + + -- : Symb -> Ord ; + SymbOrd sy = sy ; ---- TODO: nothing added to it. Lincat of Ord is just SS from the beginning. + + oper + -- To make Card or PN from a runtime argument, cannot use the single + operation. + -- See https://inariksit.github.io/gf/2018/08/28/gf-gotchas.html#unsupported-token-gluing + + mkNumeral_onRuntimeToken : Str -> LinNumeral = \str -> { + s = table { + NCard => str ; + NOrd => str ++ BIND ++ "th" + } ; + n = Pl ; -- NB. probably singular for number 1 + } ; + + mkPN_onRuntimeToken : Str -> LinPN = \str -> { + s = + -- table {_ => -- If lincat of PN changes so that it's an inflection table, uncomment this + str + -- } + ; + n = Sg ; + } ; + +lincat + Symb, [Symb] = SS ; + +lin + MkSymb s = s ; + + BaseSymb = infixSS "and" ; -- this comes between the last two ones + ConsSymb = infixSS "," ; + + +} diff --git a/src/gaelic/VerbGla.gf b/src/gaelic/VerbGla.gf new file mode 100644 index 00000000..b51fcc87 --- /dev/null +++ b/src/gaelic/VerbGla.gf @@ -0,0 +1,114 @@ +concrete VerbGla of Verb = CatGla ** open ResGla, AdverbGla, Prelude in { + + +lin + +----- +-- VP + -- : V -> VP + -- NB. assumes that lincat V = lincat VP + -- This will most likely change when you start working with VPs + UseV v = v ; + +{- + -- : V2 -> VP ; + PassV2 v2 = + + -- : VPSlash -> VP ; + ReflVP vps = + + -- : VV -> VP -> VP ; + ComplVV vv vp = + + -- : VS -> S -> VP ; + ComplVS vs s = + + -- : VQ -> QS -> VP ; + ComplVQ vq qs = + + -- : VA -> AP -> VP ; + ComplVA va ap = + + -- : Comp -> VP ; + UseComp comp = +-} +-------- +-- Slash +{- + -- : V2 -> VPSlash + SlashV2a v2 = + + -- : V3 -> NP -> VPSlash ; -- give it (to her) + Slash2V3 v3 dobj = + + -- : V3 -> NP -> VPSlash ; -- give (it) to her + Slash3V3 v3 iobj = + + SlashV2A v2 adj = + + -- : V2S -> S -> VPSlash ; -- answer (to him) that it is good + SlashV2S v2s s = + + -- : V2V -> VP -> VPSlash ; -- beg (her) to go + SlashV2V v2v vp = ; + + -- : V2Q -> QS -> VPSlash ; -- ask (him) who came + SlashV2Q v2q qs = ; + + -- : V2A -> AP -> VPSlash ; -- paint (it) red + SlashV2A v2a ap = ; + + + -- : VPSlash -> NP -> VP + -- Often VPSlash has a field called c2, which is used to pick right form of np complement + ComplSlash vps np = vps ** { + compl = np.s ! vps.c2 + } ; + + -- : VV -> VPSlash -> VPSlash ; + SlashVV vv vps = ComplVV vv vps ** { + } ; + + -- : V2V -> NP -> VPSlash -> VPSlash ; -- beg me to buy + SlashV2VNP v2v np vps = + + -- : VP -> Adv -> VP ; -- sleep here + AdvVP vp adv = + + -- : AdV -> VP -> VP ; -- always sleep + AdVVP adv vp = + + -- : VPSlash -> Adv -> VPSlash ; -- use (it) here + AdvVPSlash = insertAdv ; + + -- : VP -> Adv -> VP ; -- sleep , even though ... + ExtAdvVP vp adv = ; + + -- : AdV -> VPSlash -> VPSlash ; -- always use (it) + AdVVPSlash adv vps = vps ** { adv = adv.s ++ vps.adv } ; + + -- : VP -> Prep -> VPSlash ; -- live in (it) + VPSlashPrep vp prep = vp ** {c2 = prep} ; + + +--2 Complements to copula + +-- Adjectival phrases, noun phrases, and adverbs can be used. + + -- : AP -> Comp ; + CompAP ap = + + -- : CN -> Comp ; + CompCN cn = + + -- NP -> Comp ; + CompNP np = + + -- : Adv -> Comp ; + CompAdv adv = + + -- : VP -- Copula alone; + UseCopula = +-} + +} From c9c17230902602e669702d42d2ea981c97097614 Mon Sep 17 00:00:00 2001 From: Inari Listenmaa Date: Wed, 20 Aug 2025 15:13:27 +0200 Subject: [PATCH 02/15] some morphology I pulled out of my ass --- src/gaelic/ResGla.gf | 186 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 163 insertions(+), 23 deletions(-) diff --git a/src/gaelic/ResGla.gf b/src/gaelic/ResGla.gf index dc277483..8a47a32c 100644 --- a/src/gaelic/ResGla.gf +++ b/src/gaelic/ResGla.gf @@ -35,23 +35,94 @@ param | Dual -- only after number 2 ; Person = P1 | P2 | P3 ; + Definiteness = Def | Indef ; -- Some prepositions govern different case when definite vs. indefinite + oper LinN : Type = { - s : - Number => - Case => - Str ; - g : Gender ; + base, -- tunnag fuil loch + lenited, -- thunnag fhuil loch + palatalised, -- tunnaig fuil loch + lenited_palatalised, -- thunnaig fhuil loch + suffixE, -- tunnaige fuile loche + lenited_suffixA, -- thunnaga fala locha + suffixAn -- tunnagan nonExist lochan + : Str ; + g : Gender } ; - -- Most often, the lincat for CN is the same as N, with possibly some additional fields. - -- However, sometimes you need more fields than just the s field, e.g. to keep word order flexible, or to add clitics and make sure they attach to the head, not modifiers. - -- If you don't know what the previous line means, you can get started with just a single s field. - -- You'll notice later whether you need such a field or not. - LinCN : Type = LinN - -- ** {postmod/premod/… : Str} -- if needed - ; + +{- + +PL.VOC: lenited + non-palatalized + -a + +class 1 masculine noun + boireannach SG.*.NOM, SG.INDEF.DAT, PL.DEF.GEN + boireannaich SG.INDEF.GEN, PL.*.NOM, PL.*.DAT + bhoireannach PL.INDEF.GEN, SG.DEF.DAT + bhoireannaich SG.DEF.GEN, SG.VOC + bhoireannacha PL.VOC + + indefinite + singular plural + nominative boireannach boireannaich + genitive boireannaich bhoireannach + dative boireannach boireannaich; boireannachaibh✝ + definite + singular plural + nominative (am) boireannach (na) boireannaich + genitive (a') bhoireannaich (nam) boireannach + dative (a') bhoireannach (na) boireannaich; boireannachaibh✝ + vocative bhoireannaich bhoireannacha + + +class 2 feminine noun + not affected by lenition? + làmh SG.*.NOM, PL.*.GEN, SG.VOC + làmh (imagine there was lenition) PL.INDEF.GEN, SG.VOC + làimh SG.*.DAT + làimhe SG.*.GEN + làmhan PL.*.NOM, PL.*.DAT + làmha PL.VOC + + indefinite + singular plural + nominative làmh làmhan + genitive làimhe làmh + dative làimh làmhan + definite + singular plural + nominative (an) làmh (na) làmhan + genitive (na) làimhe (nan) làmh + dative (an) làimh (na) làmhan + vocative làmh làmha + +class 2a feminine noun + tunnag SG.*.NOM, PL.DEF.GEN + thunnag PL.INDEF.GEN, SG.VOC + tunnaig SG.*.DAT, SG.*.GEN (allomorph (secondary?)), + tunnaige SG.*.GEN (allomorph (primary?)) + tunnagan PL.*.NOM, PL.*.DAT + thunnaga PL.VOC + + indefinite + singular plural + nominative tunnag tunnagan + genitive tunnaige, thunnag + tunnaig + dative tunnaig tunnagan + definite + singular plural + nominative (an) tunnag (na) tunnagan + genitive (na) tunnaige, (nan) tunnag + tunnaig + dative (an) tunnaig (na) tunnagan + vocative thunnag thunnaga + +class 3 + + +-} LinPN : Type = { s : Str ; @@ -60,19 +131,91 @@ oper } ; -- For inflection paradigms, see http://www.grammaticalframework.org/doc/tutorial/gf-tutorial.html#toc56 - mkNoun : Str -> Gender -> LinN = \str,g -> { - s = table { - _ => \\_ => str -- TODO: actual morphology - } ; + mkNoun : (b,l,p,lp,se,sa,lsa,san : Str) -> Gender -> LinN = \b,l,p,lp,se,sa,lsa,san,g -> { + base = b ; -- tunnag fuil loch + lenited = l ; -- thunnag fhuil loch + palatalised = p ; -- tunnaig fuil loch + lenited_palatalised = lp ; -- thunnaig fhuil loch + suffixE = se ; -- tunnaige fuile loch + suffixA = sa ; -- tunnaga fala locha + lenited_suffixA = lsa ; -- thunnaga fala locha + suffixAn = san ; -- tunnagan g = g ; - -- If your nouns have gender, it should come here as inherent field. - -- Usually you need to give the gender as an argument to mkNoun. } ; - linCN : LinCN -> Str = \cn -> cn.s ! Sg ! Nom + -- TODO: no idea if this is even remotely correct + -- can always replace morphology with Katya's automated tool + useN : LinN -> LinCN = \n -> n ** { + s = table { + Pl => table { + Indef => table { + Nom|Dat => fm n.suffixAn n.palatalised ; + Gen => n.lenited ; + Voc => n.lenited_suffixA } ; + Def => table { + Nom|Dat => fm n.suffixAn n.palatalised ; + Gen => n.base ; + Voc => fm n.lenited n.lenited_palatalised } + } ; + _ => table { -- Sg and Dl + Indef => table { + Nom => n.base ; + Gen => fm n.suffixE n.palatalised ; + Dat => fm n.palatalised n.base ; + Voc => fm n.lenited n.lenited_palatalised } ; + Def => table { + Nom => n.base ; + Gen => fm n.suffixE n.lenited_palatalised ; + Dat => fm n.palatalised n.lenited ; + Voc => fm n.lenited n.lenited_palatalised } + } + } + } where { + fm : Str -> Str -> Str = \fem,masc -> case n.g of { + Fem => fem ; + Masc => masc + } + }; + + LinCN : Type = { + s : Number => + Definiteness => -- ???? is this needed ?????? + Case => + Str ; + g : Gender ; + -- ** postmod/premod/… : Str -- if needed? determiners can put stuff after head but it only comes at NP + } ; + + linCN : LinCN -> Str = \cn -> cn.s ! Sg ! Indef ! Nom -- ++ cn.postmod -- If there is another field, use here ; + +-- some test nouns — TODO: do smart paradigms +tunnag_N : LinN = { + base = "tunnag" ; + lenited = "thunnag" ; + palatalised = "tunnaig" ; + lenited_palatalised = "thunnaig" ; + suffixE = "tunnaige" ; + suffixA = "tunnaga" ; + lenited_suffixA = "thunnaga" ; + suffixAn = "tunnagan" ; + g = Fem ; + } ; + +boireannach_N : LinN = { + base = "boireannach" ; + lenited = "bhoireannach" ; + palatalised = "boireannaich" ; + lenited_palatalised = "bhoireannaich" ; + suffixE = "bhoireannaiche" ; + suffixA = "boireannacha" ; + lenited_suffixA = "bhoireannacha" ; + suffixAn = "boireannachan" ; + g = Masc ; + } ; + --------------------------------------------- -- Numeral @@ -121,9 +264,6 @@ NB. for later, when you want to make Pron into possessives, you may need more fi That's why I'm copying over the definition below, instead of the neater `LinNP : Type = LinPron`. -} -param - Definiteness = Definite | Indefinite ; - -- Some prepositions govern different case when definite vs. indefinite oper LinNP : Type = { @@ -146,7 +286,7 @@ oper s = \\_ => [] ; n = Sg ; p = P3 ; - d = Indefinite ; + d = Indef ; } ; -------------------------------------------------------------------------------- From 4b78bd6c6735a20cc0755b73b68fd6df65d059bc Mon Sep 17 00:00:00 2001 From: Inari Listenmaa Date: Wed, 20 Aug 2025 15:35:56 +0200 Subject: [PATCH 03/15] yep the morpho sucks, but let's fix it in next commits --- src/gaelic/CatGla.gf | 4 ++-- src/gaelic/LexiconGla.gf | 11 ++++++----- src/gaelic/NounGla.gf | 12 +++++++----- src/gaelic/NumeralGla.gf | 4 +++- src/gaelic/ParadigmsGla.gf | 2 +- src/gaelic/ResGla.gf | 30 +++++++++++++++++++++++++++--- src/gaelic/SentenceGla.gf | 2 +- 7 files changed, 47 insertions(+), 18 deletions(-) diff --git a/src/gaelic/CatGla.gf b/src/gaelic/CatGla.gf index a8032fe9..815d006f 100644 --- a/src/gaelic/CatGla.gf +++ b/src/gaelic/CatGla.gf @@ -55,8 +55,8 @@ concrete CatGla of Cat = CommonX ** open ResGla, Coordination, Prelude in { Det = ResGla.LinDet ; -- s : Str , n : Number Predet = SS ; Quant = ResGla.LinQuant ; -- s : Number => Str - Num = ResGla.LinDet ; - Card = ResGla.LinDet ; + Num = ResGla.LinNum ; + Card = ResGla.LinNum ; ACard = SS ; Ord = SS ; DAP = SS ; diff --git a/src/gaelic/LexiconGla.gf b/src/gaelic/LexiconGla.gf index 96142b55..b1409c01 100644 --- a/src/gaelic/LexiconGla.gf +++ b/src/gaelic/LexiconGla.gf @@ -33,9 +33,9 @@ lin big_A = mkA "" ; lin bike_N = mkN "" ; lin bird_N = mkN "" ; lin bite_V2 = mkV2 "" ; -lin black_A = mkA "" ; -} -lin blood_N = mkN "blood" ; -{-lin blow_V = mkV "" ; +lin black_A = mkA "" ; +lin blood_N = mkN "" ; +lin blow_V = mkV "" ; lin blue_A = mkA "" ; lin boat_N = mkN "" ; lin bone_N = mkN "" ; @@ -195,11 +195,12 @@ lin know_V2 = mkV2 "" ; lin know_VQ = mkVQ (mkV "") ; lin know_VS = mkV "" ; - +-} ---- -- L -lin lake_N = mkN "" ; +lin lake_N = smartN "loch" "locha" "lochan" Masc ; +{- lin lamp_N = mkN "" ; lin language_N = mkN "" ; lin laugh_V = mkV "" ; diff --git a/src/gaelic/NounGla.gf b/src/gaelic/NounGla.gf index 24507a91..2987be64 100644 --- a/src/gaelic/NounGla.gf +++ b/src/gaelic/NounGla.gf @@ -8,7 +8,8 @@ concrete NounGla of Noun = CatGla ** open ResGla, Prelude in { -- : Det -> CN -> NP DetCN det cn = emptyNP ** { - s = det.s ++ cn.s ! det.n + s = \\c => det.s ++ cn.s ! det.n ! det.d ! c ; + d = det.d } ; {- -- : PN -> NP ; @@ -53,7 +54,7 @@ concrete NounGla of Noun = CatGla ** open ResGla, Prelude in { -} -- MassNP : CN -> NP ; MassNP cn = emptyNP ** { - s = linCN cn + s = cn.s ! Sg ! Indef } ; @@ -65,6 +66,7 @@ concrete NounGla of Noun = CatGla ** open ResGla, Prelude in { -- : Quant -> Num -> Det ; DetQuant quant num = quant ** { s = quant.s ! num.n ++ num.s ; + s2 = "DUMMY" ; -- "teen" from numbers like seventeen n = num.n ; } ; @@ -121,10 +123,10 @@ concrete NounGla of Noun = CatGla ** open ResGla, Prelude in { -} -- : Quant - DefArt = mkQuant "the" "the" ; + DefArt = mkQuant "an" "nan" Def ; -- : Quant - IndefArt = mkQuant "a" [] ; + IndefArt = mkQuant [] [] Indef ; {- -- : Pron -> Quant -- my @@ -136,7 +138,7 @@ concrete NounGla of Noun = CatGla ** open ResGla, Prelude in { --2 Common nouns -- : N -> CN - UseN n = n ; + UseN = useN ; {- -- : N2 -> CN ; diff --git a/src/gaelic/NumeralGla.gf b/src/gaelic/NumeralGla.gf index a7e3af7c..e56c4ea2 100644 --- a/src/gaelic/NumeralGla.gf +++ b/src/gaelic/NumeralGla.gf @@ -1,6 +1,6 @@ concrete NumeralGla of Numeral = CatGla [Numeral,Digits] ** open Prelude, ResGla in { - +{- lincat Digit = LinNumeral ; -- 2..9 Sub10, -- 1..9 @@ -112,4 +112,6 @@ concrete NumeralGla of Numeral = CatGla [Numeral,Digits] ** } ; n = Pl ; -- TODO: handle number 1 } ; + + -} } diff --git a/src/gaelic/ParadigmsGla.gf b/src/gaelic/ParadigmsGla.gf index 330df734..68984f3f 100644 --- a/src/gaelic/ParadigmsGla.gf +++ b/src/gaelic/ParadigmsGla.gf @@ -117,7 +117,7 @@ oper -- https://inariksit.github.io/gf/2018/05/25/subtyping-gf.html#lock-fields mkN = overload { - mkN : Str -> N = \s -> lin N (ResGla.mkNoun s) ; + mkN : Str -> N = \s -> lin N (ResGla.smartN s (s+"a") (s+"an") Masc) ; -- TODO: more overload instances } ; diff --git a/src/gaelic/ResGla.gf b/src/gaelic/ResGla.gf index 8a47a32c..d892a148 100644 --- a/src/gaelic/ResGla.gf +++ b/src/gaelic/ResGla.gf @@ -51,6 +51,21 @@ oper g : Gender } ; + smartN = overload { + smartN : (nom,gen,pl : Str) -> Gender -> LinN = \loch,locha,lochan,g -> { + base, + lenited, + palatalised, + lenited_palatalised, + suffixE = loch ; + lenited_suffixA = lochan ; + suffixAn = lochan ; + g = g + } +-- ; +-- smartN : (…,…,…,… : Str) + } ; + {- @@ -123,7 +138,7 @@ class 3 -} - +oper LinPN : Type = { s : Str ; n : Number ; -- Proper nouns often have already an inherent number; you don't usually say "a Paris / many Parises" @@ -299,25 +314,34 @@ oper s, -- quantifier in a context, e.g. 'this (cat) (is nice)' sp -- quantifier as standalone, e.g. 'this (is nice)' : Number => Str ; + d : Definiteness ; } ; LinDet : Type = { s,s2 : Str ; n : Number ; + d : Definiteness ; + } ; + + LinNum : Type = { + s : Str ; + n : Number ; } ; -- Can you reuse your mkNoun? Do nouns and quantifiers inflect the same way? - mkQuant : Str -> Str -> LinQuant = \this, these -> { + mkQuant : Str -> Str -> Definiteness -> LinQuant = \this,these,d -> { s, sp = table { Sg => this ; _ => these } ; + d = d ; }; mkDet : (seven, teen : Str) -> Number -> LinDet = \aon, deug, num -> { s = aon ; s2 = deug ; - n = num + n = num ; + d = Indef ---- } ; -------------------------------------------------------------------------------- diff --git a/src/gaelic/SentenceGla.gf b/src/gaelic/SentenceGla.gf index 893e105a..5fe17d4b 100644 --- a/src/gaelic/SentenceGla.gf +++ b/src/gaelic/SentenceGla.gf @@ -10,7 +10,7 @@ lin -- : NP -> VP -> Cl PredVP np vp = { - subj = np.s ; -- ! Nom, if there are cases + subj = np.s ! Nom ; pred = -- table {something with tense+polarity => vp.s ! TODOVF np.n np.p From cabf56aea90feb2362b634633001a2a034aa4807 Mon Sep 17 00:00:00 2001 From: Inari Listenmaa Date: Wed, 20 Aug 2025 16:21:45 +0200 Subject: [PATCH 04/15] still broken but in a different way --- src/gaelic/ResGla.gf | 61 ++++++++++++++++++++------------------------ 1 file changed, 27 insertions(+), 34 deletions(-) diff --git a/src/gaelic/ResGla.gf b/src/gaelic/ResGla.gf index d892a148..a5c33eab 100644 --- a/src/gaelic/ResGla.gf +++ b/src/gaelic/ResGla.gf @@ -40,26 +40,25 @@ param oper LinN : Type = { - base, -- tunnag fuil loch - lenited, -- thunnag fhuil loch - palatalised, -- tunnaig fuil loch - lenited_palatalised, -- thunnaig fhuil loch - suffixE, -- tunnaige fuile loche - lenited_suffixA, -- thunnaga fala locha - suffixAn -- tunnagan nonExist lochan + base, -- tunnag fuil loch fear litir + gen, -- tunnaige fala locha fir litreach ("de-palatalised") + pl, -- tunnagan lochan fir litrichean + -- TODO: for nouns that only use suffixes, should these just show theoretical forms? + lenited, -- thunnag fhuil loch fhear + palatalised, -- tunnaig fuil loch fir + lenited_palatalised -- thunnaig fhuil loch fhir : Str ; g : Gender } ; smartN = overload { smartN : (nom,gen,pl : Str) -> Gender -> LinN = \loch,locha,lochan,g -> { + gen = locha ; + pl = lochan ; base, lenited, palatalised, - lenited_palatalised, - suffixE = loch ; - lenited_suffixA = lochan ; - suffixAn = lochan ; + lenited_palatalised = loch ; g = g } -- ; @@ -146,15 +145,13 @@ oper } ; -- For inflection paradigms, see http://www.grammaticalframework.org/doc/tutorial/gf-tutorial.html#toc56 - mkNoun : (b,l,p,lp,se,sa,lsa,san : Str) -> Gender -> LinN = \b,l,p,lp,se,sa,lsa,san,g -> { - base = b ; -- tunnag fuil loch - lenited = l ; -- thunnag fhuil loch - palatalised = p ; -- tunnaig fuil loch - lenited_palatalised = lp ; -- thunnaig fhuil loch - suffixE = se ; -- tunnaige fuile loch - suffixA = sa ; -- tunnaga fala locha - lenited_suffixA = lsa ; -- thunnaga fala locha - suffixAn = san ; -- tunnagan + mkNoun : (b,g,pl,l,p,lp : Str) -> Gender -> LinN = \b,gen,pl,l,p,lp,g -> { + base = b ; -- tunnag fuil loch fear litir + gen = gen ; -- tunnaige fala locha fir litreach + pl = pl ; -- tunnagan lochan fir litrichean + lenited = l ; -- thunnag fhuil loch fhear litir ? + palatalised = p ; -- tunnaig fuil loch fir litir ? + lenited_palatalised = lp ; -- thunnaig fhuil loch fhir litir ? g = g ; } ; @@ -164,23 +161,23 @@ oper s = table { Pl => table { Indef => table { - Nom|Dat => fm n.suffixAn n.palatalised ; - Gen => n.lenited ; - Voc => n.lenited_suffixA } ; + Nom|Dat => n.pl ; + Gen => n.gen ; + Voc => glue n.lenited "a" } ; Def => table { - Nom|Dat => fm n.suffixAn n.palatalised ; + Nom|Dat => n.pl ; Gen => n.base ; Voc => fm n.lenited n.lenited_palatalised } } ; _ => table { -- Sg and Dl Indef => table { Nom => n.base ; - Gen => fm n.suffixE n.palatalised ; + Gen => n.gen ; Dat => fm n.palatalised n.base ; Voc => fm n.lenited n.lenited_palatalised } ; Def => table { Nom => n.base ; - Gen => fm n.suffixE n.lenited_palatalised ; + Gen => n.gen ; Dat => fm n.palatalised n.lenited ; Voc => fm n.lenited n.lenited_palatalised } } @@ -209,25 +206,21 @@ oper -- some test nouns — TODO: do smart paradigms tunnag_N : LinN = { base = "tunnag" ; + gen = "tunnaige" ; + pl = "tunnagan" ; lenited = "thunnag" ; palatalised = "tunnaig" ; lenited_palatalised = "thunnaig" ; - suffixE = "tunnaige" ; - suffixA = "tunnaga" ; - lenited_suffixA = "thunnaga" ; - suffixAn = "tunnagan" ; + g = Fem ; } ; boireannach_N : LinN = { base = "boireannach" ; + pl,gen = "boireannaich" ; lenited = "bhoireannach" ; palatalised = "boireannaich" ; lenited_palatalised = "bhoireannaich" ; - suffixE = "bhoireannaiche" ; - suffixA = "boireannacha" ; - lenited_suffixA = "bhoireannacha" ; - suffixAn = "boireannachan" ; g = Masc ; } ; From 4f5e67a5811c758ed3a4b5198d7385d2904fda7c Mon Sep 17 00:00:00 2001 From: Inari Listenmaa Date: Wed, 20 Aug 2025 16:42:24 +0200 Subject: [PATCH 05/15] make leaner param for CN (morpho still as wrong as always) --- src/gaelic/NounGla.gf | 8 +- src/gaelic/ResGla.gf | 157 +++++++++++--------------------------- src/gaelic/SentenceGla.gf | 2 +- 3 files changed, 50 insertions(+), 117 deletions(-) diff --git a/src/gaelic/NounGla.gf b/src/gaelic/NounGla.gf index 2987be64..ac0cbb39 100644 --- a/src/gaelic/NounGla.gf +++ b/src/gaelic/NounGla.gf @@ -8,7 +8,7 @@ concrete NounGla of Noun = CatGla ** open ResGla, Prelude in { -- : Det -> CN -> NP DetCN det cn = emptyNP ** { - s = \\c => det.s ++ cn.s ! det.n ! det.d ! c ; + s = \\c => det.s ++ cn.s ! getNForm det.n det.d c ; d = det.d } ; {- @@ -54,7 +54,7 @@ concrete NounGla of Noun = CatGla ** open ResGla, Prelude in { -} -- MassNP : CN -> NP ; MassNP cn = emptyNP ** { - s = cn.s ! Sg ! Indef + s = \\c => cn.s ! getNForm Sg Indefinite c } ; @@ -123,10 +123,10 @@ concrete NounGla of Noun = CatGla ** open ResGla, Prelude in { -} -- : Quant - DefArt = mkQuant "an" "nan" Def ; + DefArt = mkQuant "an" "nan" Definite ; -- : Quant - IndefArt = mkQuant [] [] Indef ; + IndefArt = mkQuant [] [] Indefinite ; {- -- : Pron -> Quant -- my diff --git a/src/gaelic/ResGla.gf b/src/gaelic/ResGla.gf index a5c33eab..e0d38a55 100644 --- a/src/gaelic/ResGla.gf +++ b/src/gaelic/ResGla.gf @@ -29,16 +29,28 @@ https://inariksit.github.io/gf/2018/08/28/gf-gotchas.html#my-naming-scheme-for-l param Gender = Masc | Fem ; - Case = Nom | Gen | Dat | Voc ; + CoreCase = Nom | Gen | Dat ; + Case = CC CoreCase | Voc ; Number = Sg | Pl - | Dual -- only after number 2 ; Person = P1 | P2 | P3 ; - Definiteness = Def | Indef ; -- Some prepositions govern different case when definite vs. indefinite + Definiteness = Definite | Indefinite ; -- Some prepositions govern different case when definite vs. indefinite + NForm = + Indef Number CoreCase + | Def Number Case + | Dual -- only after number 2, only for a handful of nouns. TODO: does it have different cases? + ; oper + getNForm : Number -> Definiteness -> Case -> NForm = \n,d,c -> + case of { + => Indef n Nom ; ---- ??? + => Indef n c ; + => Def n c + } ; + LinN : Type = { base, -- tunnag fuil loch fear litir gen, -- tunnaige fala locha fir litreach ("de-palatalised") @@ -65,85 +77,6 @@ oper -- smartN : (…,…,…,… : Str) } ; - -{- - -PL.VOC: lenited + non-palatalized + -a - -class 1 masculine noun - boireannach SG.*.NOM, SG.INDEF.DAT, PL.DEF.GEN - boireannaich SG.INDEF.GEN, PL.*.NOM, PL.*.DAT - bhoireannach PL.INDEF.GEN, SG.DEF.DAT - bhoireannaich SG.DEF.GEN, SG.VOC - bhoireannacha PL.VOC - - indefinite - singular plural - nominative boireannach boireannaich - genitive boireannaich bhoireannach - dative boireannach boireannaich; boireannachaibh✝ - definite - singular plural - nominative (am) boireannach (na) boireannaich - genitive (a') bhoireannaich (nam) boireannach - dative (a') bhoireannach (na) boireannaich; boireannachaibh✝ - vocative bhoireannaich bhoireannacha - - -class 2 feminine noun - not affected by lenition? - làmh SG.*.NOM, PL.*.GEN, SG.VOC - làmh (imagine there was lenition) PL.INDEF.GEN, SG.VOC - làimh SG.*.DAT - làimhe SG.*.GEN - làmhan PL.*.NOM, PL.*.DAT - làmha PL.VOC - - indefinite - singular plural - nominative làmh làmhan - genitive làimhe làmh - dative làimh làmhan - definite - singular plural - nominative (an) làmh (na) làmhan - genitive (na) làimhe (nan) làmh - dative (an) làimh (na) làmhan - vocative làmh làmha - -class 2a feminine noun - tunnag SG.*.NOM, PL.DEF.GEN - thunnag PL.INDEF.GEN, SG.VOC - tunnaig SG.*.DAT, SG.*.GEN (allomorph (secondary?)), - tunnaige SG.*.GEN (allomorph (primary?)) - tunnagan PL.*.NOM, PL.*.DAT - thunnaga PL.VOC - - indefinite - singular plural - nominative tunnag tunnagan - genitive tunnaige, thunnag - tunnaig - dative tunnaig tunnagan - definite - singular plural - nominative (an) tunnag (na) tunnagan - genitive (na) tunnaige, (nan) tunnag - tunnaig - dative (an) tunnaig (na) tunnagan - vocative thunnag thunnaga - -class 3 - - --} -oper - LinPN : Type = { - s : Str ; - n : Number ; -- Proper nouns often have already an inherent number; you don't usually say "a Paris / many Parises" - g : Gender ; -- inherent gender/noun class, if your language has that - } ; - -- For inflection paradigms, see http://www.grammaticalframework.org/doc/tutorial/gf-tutorial.html#toc56 mkNoun : (b,g,pl,l,p,lp : Str) -> Gender -> LinN = \b,gen,pl,l,p,lp,g -> { base = b ; -- tunnag fuil loch fear litir @@ -159,29 +92,21 @@ oper -- can always replace morphology with Katya's automated tool useN : LinN -> LinCN = \n -> n ** { s = table { - Pl => table { - Indef => table { - Nom|Dat => n.pl ; - Gen => n.gen ; - Voc => glue n.lenited "a" } ; - Def => table { - Nom|Dat => n.pl ; - Gen => n.base ; - Voc => fm n.lenited n.lenited_palatalised } - } ; - _ => table { -- Sg and Dl - Indef => table { - Nom => n.base ; - Gen => n.gen ; - Dat => fm n.palatalised n.base ; - Voc => fm n.lenited n.lenited_palatalised } ; - Def => table { - Nom => n.base ; - Gen => n.gen ; - Dat => fm n.palatalised n.lenited ; - Voc => fm n.lenited n.lenited_palatalised } - } - } + Indef Sg Nom => n.base ; + Indef Sg Gen => n.gen ; + Indef Sg Dat => fm n.palatalised n.base ; + Def Sg (CC Nom) => n.base ; + Def Sg (CC Gen) => fm n.gen n.lenited_palatalised ; + Def Sg (CC Dat) => fm n.palatalised n.lenited ; + Def Sg Voc => n.lenited ; + Indef Pl Nom => n.pl ; + Indef Pl Gen => n.base ; + Indef Pl Dat => n.palatalised ; + Def Pl (CC Nom) => n.pl ; + Def Pl (CC Gen) => n.base ; + Def Pl (CC Dat) => n.pl ; + Def Pl Voc => glue n.lenited "a" ; + Dual => "TODO FIXME I AM DUAL"} } where { fm : Str -> Str -> Str = \fem,masc -> case n.g of { Fem => fem ; @@ -190,15 +115,13 @@ oper }; LinCN : Type = { - s : Number => - Definiteness => -- ???? is this needed ?????? - Case => + s : NForm => Str ; g : Gender ; -- ** postmod/premod/… : Str -- if needed? determiners can put stuff after head but it only comes at NP } ; - linCN : LinCN -> Str = \cn -> cn.s ! Sg ! Indef ! Nom + linCN : LinCN -> Str = \cn -> cn.s ! Indef Sg Nom -- ++ cn.postmod -- If there is another field, use here ; @@ -224,6 +147,16 @@ boireannach_N : LinN = { g = Masc ; } ; +--------------------------------------------- +-- Proper noun + +oper + LinPN : Type = { + s : Str ; + n : Number ; -- Proper nouns often have already an inherent number; you don't usually say "a Paris / many Parises" + g : Gender ; -- inherent gender/noun class, if your language has that + } ; + --------------------------------------------- -- Numeral @@ -288,13 +221,13 @@ oper d : Definiteness ; } ; - linNP : LinNP -> Str = \np -> np.s ! Nom ; + linNP : LinNP -> Str = \np -> np.s ! (CC Nom) ; emptyNP : LinNP = { s = \\_ => [] ; n = Sg ; p = P3 ; - d = Indef ; + d = Indefinite ; } ; -------------------------------------------------------------------------------- @@ -334,7 +267,7 @@ oper s = aon ; s2 = deug ; n = num ; - d = Indef ---- + d = Indefinite -- TODO fix } ; -------------------------------------------------------------------------------- diff --git a/src/gaelic/SentenceGla.gf b/src/gaelic/SentenceGla.gf index 5fe17d4b..dd86a7dd 100644 --- a/src/gaelic/SentenceGla.gf +++ b/src/gaelic/SentenceGla.gf @@ -10,7 +10,7 @@ lin -- : NP -> VP -> Cl PredVP np vp = { - subj = np.s ! Nom ; + subj = np.s ! CC Nom ; pred = -- table {something with tense+polarity => vp.s ! TODOVF np.n np.p From 1c87e5ac78d42833e8afea214bab44a133dddf7f Mon Sep 17 00:00:00 2001 From: Inari Listenmaa Date: Thu, 21 Aug 2025 15:43:47 +0200 Subject: [PATCH 06/15] misc fixes in morpho (works for 4 nouns!) --- src/gaelic/ResGla.gf | 52 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 43 insertions(+), 9 deletions(-) diff --git a/src/gaelic/ResGla.gf b/src/gaelic/ResGla.gf index e0d38a55..4e120ff8 100644 --- a/src/gaelic/ResGla.gf +++ b/src/gaelic/ResGla.gf @@ -46,7 +46,7 @@ param oper getNForm : Number -> Definiteness -> Case -> NForm = \n,d,c -> case of { - => Indef n Nom ; ---- ??? + => Def n Voc ; => Indef n c ; => Def n c } ; @@ -72,11 +72,44 @@ oper palatalised, lenited_palatalised = loch ; g = g - } --- ; --- smartN : (…,…,…,… : Str) + } ; + smartN : (base : Str) -> Gender -> LinN = \tunnag,g -> { + base = tunnag ; + gen = fm (tunnaig + "e") tunnaig ; + pl = fm (tunnag + "an") tunnaig ; -- for other allomorphs, use 4-argument paradigm + lenited = thunnag ; + palatalised = tunnaig ; + lenited_palatalised = thunnaig ; + g = g + } where { + tunnaig : Str = palatalise tunnag ; + thunnag : Str = lenite tunnag ; + thunnaig : Str = lenite tunnaig ; + fm : Str -> Str -> Str = \fem,masc -> case g of { + Fem => fem ; Masc => masc } + } } ; + vowel : pattern Str = #("a"|"à"|"e"|"i"|"ì"|"o"|"u") ; -- more accents? + diphthong : pattern Str = #("ea"|"oi") ; + lenitable : pattern Str = #("b"|"c"|"f"|"g"|"m"|"p"|"d"|"t"|"s") ; + + palatalise : Str -> Str = \lamh -> case lamh of { + -- f + "ea" + r => f + "i" + r ; -- TODO is this irregular? + boireann@(_ + (#vowel|#diphthong) + ? + _ + (#vowel|#diphthong) + ? + _) + + a@#vowel + ch => boireann + a + "i" + ch ; + tunn@(_ + (#vowel|#diphthong) + ? + _) + + a@#vowel + g => tunn + a + "i" + g ; + l + a@#vowel + mh => l + a + "i" + mh ; + _ => lamh } ; + + lenite : Str -> Str = \tunnag -> case tunnag of { + "s" + ("p"|"g"|"m"|"t") + _ => tunnag ; -- sp, sg, sm, st don't lenite + t@#lenitable + "h" + _ => tunnag ; -- don't lenite twice + t@#lenitable + unnag => t + "h" + unnag ; + _ => tunnag } ; + + -- For inflection paradigms, see http://www.grammaticalframework.org/doc/tutorial/gf-tutorial.html#toc56 mkNoun : (b,g,pl,l,p,lp : Str) -> Gender -> LinN = \b,gen,pl,l,p,lp,g -> { base = b ; -- tunnag fuil loch fear litir @@ -98,15 +131,16 @@ oper Def Sg (CC Nom) => n.base ; Def Sg (CC Gen) => fm n.gen n.lenited_palatalised ; Def Sg (CC Dat) => fm n.palatalised n.lenited ; - Def Sg Voc => n.lenited ; - Indef Pl Nom => n.pl ; - Indef Pl Gen => n.base ; - Indef Pl Dat => n.palatalised ; + Def Sg Voc => fm n.lenited n.lenited_palatalised ; + Indef Pl Nom => fm n.pl n.palatalised ; + Indef Pl Gen => n.lenited ; + Indef Pl Dat => fm n.pl n.palatalised ; -- TODO: is this correct? Def Pl (CC Nom) => n.pl ; Def Pl (CC Gen) => n.base ; Def Pl (CC Dat) => n.pl ; Def Pl Voc => glue n.lenited "a" ; - Dual => "TODO FIXME I AM DUAL"} + Dual => fm n.palatalised n.base -- TODO: is this correct? only for 1-syllable feminine nouns? + } } where { fm : Str -> Str -> Str = \fem,masc -> case n.g of { Fem => fem ; From b8d9098aaa613687d9275a01e613ac96354dd58d Mon Sep 17 00:00:00 2001 From: Inari Listenmaa Date: Thu, 21 Aug 2025 15:43:53 +0200 Subject: [PATCH 07/15] add more words --- src/gaelic/LexiconGla.gf | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/gaelic/LexiconGla.gf b/src/gaelic/LexiconGla.gf index b1409c01..bd5e1e36 100644 --- a/src/gaelic/LexiconGla.gf +++ b/src/gaelic/LexiconGla.gf @@ -30,8 +30,8 @@ lin beer_N = mkN "" ; lin beg_V2V = mkV2V (mkV "") ; lin belly_N = mkN "" ; lin big_A = mkA "" ; -lin bike_N = mkN "" ; -lin bird_N = mkN "" ; +lin bike_N = mkN "" ;-} +lin bird_N = smartN "tunnag" Fem ;{- lin bite_V2 = mkV2 "" ; lin black_A = mkA "" ; lin blood_N = mkN "" ; @@ -160,8 +160,8 @@ lin green_A = mkA "" ; ---- -- H -lin hair_N = mkN "" ; -lin hand_N = mkN "" ; +lin hair_N = mkN "" ;-} +lin hand_N = smartN "làmh" Fem ;{- lin harbour_N = mkN "" ; lin hat_N = mkN "" ; lin hate_V2 = mkV2 "" ; @@ -223,7 +223,7 @@ lin love_V2 = mkV2 "" ; ---- -- M -lin man_N = mkN "" ; +-}lin man_N = smartN "fear" Masc ;{- lin married_A2 = mkA2 (mkA "") ; lin meat_N = mkN "" ; lin milk_N = mkN "" ; @@ -407,8 +407,8 @@ lin wind_N = mkN "" ; lin window_N = mkN "" ; lin wine_N = mkN "" ; lin wing_N = mkN "" ; -lin wipe_V2 = mkV2 "" ; -lin woman_N = mkN "" ; +lin wipe_V2 = mkV2 "" ;-} +lin woman_N = smartN "boireannach" Masc ;{- lin wonder_VQ = mkVQ (mkV "") ; lin wood_N = mkN "" ; lin worm_N = mkN "" ; From a539db3d552f6761589d49b827168d2135c48807 Mon Sep 17 00:00:00 2001 From: Inari Listenmaa Date: Thu, 21 Aug 2025 16:42:20 +0200 Subject: [PATCH 08/15] allomorphs for definite article --- src/gaelic/NounGla.gf | 10 +++--- src/gaelic/ResGla.gf | 83 ++++++++++++++++++++++++++++++++++--------- 2 files changed, 71 insertions(+), 22 deletions(-) diff --git a/src/gaelic/NounGla.gf b/src/gaelic/NounGla.gf index ac0cbb39..de0e57c6 100644 --- a/src/gaelic/NounGla.gf +++ b/src/gaelic/NounGla.gf @@ -8,7 +8,7 @@ concrete NounGla of Noun = CatGla ** open ResGla, Prelude in { -- : Det -> CN -> NP DetCN det cn = emptyNP ** { - s = \\c => det.s ++ cn.s ! getNForm det.n det.d c ; + s = \\c => det.s ! cn.g ! c ++ cn.s ! getNForm det.n det.d c ; d = det.d } ; {- @@ -65,8 +65,8 @@ concrete NounGla of Noun = CatGla ** open ResGla, Prelude in { -- : Quant -> Num -> Det ; DetQuant quant num = quant ** { - s = quant.s ! num.n ++ num.s ; - s2 = "DUMMY" ; -- "teen" from numbers like seventeen + s = \\g,c => getArt quant num.n g c ++ num.s ; + s2 = \\g,c => "DUMMY" ; -- "teen" from numbers like seventeen n = num.n ; } ; @@ -123,10 +123,10 @@ concrete NounGla of Noun = CatGla ** open ResGla, Prelude in { -} -- : Quant - DefArt = mkQuant "an" "nan" Definite ; + DefArt = ResGla.defArt ; -- : Quant - IndefArt = mkQuant [] [] Indefinite ; + IndefArt = mkQuant [] Indefinite ; {- -- : Pron -> Quant -- my diff --git a/src/gaelic/ResGla.gf b/src/gaelic/ResGla.gf index 4e120ff8..aaf19a71 100644 --- a/src/gaelic/ResGla.gf +++ b/src/gaelic/ResGla.gf @@ -93,9 +93,10 @@ oper vowel : pattern Str = #("a"|"à"|"e"|"i"|"ì"|"o"|"u") ; -- more accents? diphthong : pattern Str = #("ea"|"oi") ; lenitable : pattern Str = #("b"|"c"|"f"|"g"|"m"|"p"|"d"|"t"|"s") ; + labial : pattern Str = #("b"|"f"|"m"|"p") ; palatalise : Str -> Str = \lamh -> case lamh of { - -- f + "ea" + r => f + "i" + r ; -- TODO is this irregular? + f@? + "ea" + r => f + "i" + r ; -- TODO is this irregular? boireann@(_ + (#vowel|#diphthong) + ? + _ + (#vowel|#diphthong) + ? + _) + a@#vowel + ch => boireann + a + "i" + ch ; tunn@(_ + (#vowel|#diphthong) + ? + _) @@ -113,7 +114,7 @@ oper -- For inflection paradigms, see http://www.grammaticalframework.org/doc/tutorial/gf-tutorial.html#toc56 mkNoun : (b,g,pl,l,p,lp : Str) -> Gender -> LinN = \b,gen,pl,l,p,lp,g -> { base = b ; -- tunnag fuil loch fear litir - gen = gen ; -- tunnaige fala locha fir litreach + gen = gen ; -- tunnaige fala locha fir litreach pl = pl ; -- tunnagan lochan fir litrichean lenited = l ; -- thunnag fhuil loch fhear litir ? palatalised = p ; -- tunnaig fuil loch fir litir ? @@ -267,18 +268,32 @@ oper -------------------------------------------------------------------------------- -- Det, Quant, Card, Ord - -- If your language has a number, it is very very very likely that - -- Quant has a variable number and Det has inherent number. +param + QForm = QSg Gender CoreCase | QPl CoreCase ; + +oper + getQForm : Number -> Gender -> Case -> QForm = \n,g,c -> case of { + => QSg g c ; + => QSg g Nom ; --- ?????? + => QPl c ; + => QPl Nom --- ?????? + } ; + + getArt : LinQuant -> Number -> Gender -> Case -> Str = \quant,n,g,c -> case c of { + Voc => "" ; -- TODO: add empty field to article to not get metavariables + _ => quant.s ! getQForm n g c + } ; LinQuant : Type = { - s, -- quantifier in a context, e.g. 'this (cat) (is nice)' - sp -- quantifier as standalone, e.g. 'this (is nice)' - : Number => Str ; + s -- quantifier in a context, e.g. 'this (cat) (is nice)' + : QForm => Str ; + sp : Str ; -- quantifier as standalone, e.g. 'this (is nice)' d : Definiteness ; } ; LinDet : Type = { - s,s2 : Str ; + s,s2 : Gender => Case => Str ; + sp : Str ; n : Number ; d : Definiteness ; } ; @@ -289,21 +304,55 @@ oper } ; -- Can you reuse your mkNoun? Do nouns and quantifiers inflect the same way? - mkQuant : Str -> Str -> Definiteness -> LinQuant = \this,these,d -> { - s, - sp = table { - Sg => this ; - _ => these } ; + mkQuant : Str -> Definiteness -> LinQuant = \this,d -> { + s = \\_ => this ; + sp = this ; d = d ; - }; + } ; mkDet : (seven, teen : Str) -> Number -> LinDet = \aon, deug, num -> { - s = aon ; - s2 = deug ; + s = \\_,_ => aon ; + s2 = \\_,_ => deug ; + sp = aon ; n = num ; - d = Indefinite -- TODO fix + d = Indefinite -- TODO add as param } ; +-- Allomorphs of the definite article + + AN, AN_L, NA, NAN : Str ; + AN = pre { + #vowel => "an t-" ++ BIND ; + #labial => "am" ; + _ => "an" } ; + + -- N.B. lenition comes from a different param, this is just a shorthand + AN_L = pre { + "b"|"m"|"p"|"c"|"g" => "a'" ; + "f" => "an" ; + "sl"|"sn"|"sr"| + "sa"|"sà"|"si"|"sì"| + "se"|"so"|"su" => "an t-" ++ BIND ; + _ => "an" } ; + NA = pre { + #vowel => "na h-" ++ BIND ; + _ => "na" } ; + NAN = pre { + #labial => "nam" ; + _ => "nan" } ; + + defArt : LinQuant = { + s = table { + QSg Masc Nom => AN ; + QSg Masc _ => AN_L ; + QSg Fem Gen => NA ; + QSg Fem _ => AN_L ; + QPl Gen => NAN ; + QPl _ => NA + } ; + sp = "an" ; --- meaningless for DefArt + d = Definite ; + } ; -------------------------------------------------------------------------------- -- Adpositions From c85e7a514b51cf035c298710c1c219fda03ac008 Mon Sep 17 00:00:00 2001 From: Inari Listenmaa Date: Fri, 22 Aug 2025 16:30:30 +0200 Subject: [PATCH 09/15] Add some prepositions, merge with pronouns (TODO: merge with articles too) --- src/gaelic/AdverbGla.gf | 15 +++++++--- src/gaelic/CatGla.gf | 2 +- src/gaelic/NounGla.gf | 1 + src/gaelic/ParadigmsGla.gf | 6 ++-- src/gaelic/ResGla.gf | 57 ++++++++++++++++++++++++++++++------- src/gaelic/SentenceGla.gf | 2 +- src/gaelic/StructuralGla.gf | 46 +++++++++++++++--------------- 7 files changed, 87 insertions(+), 42 deletions(-) diff --git a/src/gaelic/AdverbGla.gf b/src/gaelic/AdverbGla.gf index dd89e853..848ad644 100644 --- a/src/gaelic/AdverbGla.gf +++ b/src/gaelic/AdverbGla.gf @@ -1,6 +1,6 @@ concrete AdverbGla of Adverb = CatGla ** open ResGla, ParadigmsGla, Prelude in { -{- lin +{- -- : A -> Adv ; PositAdvAdj adj = @@ -10,10 +10,17 @@ lin -- : CAdv -> A -> S -> Adv ; -- more warmly than he runs ComparAdvAdjS cadv a s = - +-} -- : Prep -> NP -> Adv ; - PrepNP prep np = ; - + PrepNP prep np = { + s = prep.s ! np.a ++ + case of { + <_, NotPron _> | + => np.s ! CC (prep.c2 ! np.d) ; + _ => np.empty -- empty string to avoid metavariables + } + } ; +{- -- Adverbs can be modified by 'adadjectives', just like adjectives. -- : AdA -> Adv -> Adv ; -- very quickly diff --git a/src/gaelic/CatGla.gf b/src/gaelic/CatGla.gf index 815d006f..ecb85c9f 100644 --- a/src/gaelic/CatGla.gf +++ b/src/gaelic/CatGla.gf @@ -77,7 +77,7 @@ concrete CatGla of Cat = CommonX ** open ResGla, Coordination, Prelude in { -- coordinating a list of NPs with that Conj. } ; -- "[Ann and Bob] are children" → and_Conj.n = Pl Subj = SS ; - Prep = SS ; + Prep = ResGla.LinPrep ; diff --git a/src/gaelic/NounGla.gf b/src/gaelic/NounGla.gf index de0e57c6..8021bc64 100644 --- a/src/gaelic/NounGla.gf +++ b/src/gaelic/NounGla.gf @@ -9,6 +9,7 @@ concrete NounGla of Noun = CatGla ** open ResGla, Prelude in { -- : Det -> CN -> NP DetCN det cn = emptyNP ** { s = \\c => det.s ! cn.g ! c ++ cn.s ! getNForm det.n det.d c ; + a = NotPron det.n ; d = det.d } ; {- diff --git a/src/gaelic/ParadigmsGla.gf b/src/gaelic/ParadigmsGla.gf index 68984f3f..fe9ab02c 100644 --- a/src/gaelic/ParadigmsGla.gf +++ b/src/gaelic/ParadigmsGla.gf @@ -109,7 +109,7 @@ oper -- hidden from the document. Prep = CatGla.Prep ; - noPrep = mkPrep [] ; + noPrep = lin Prep ResGla.emptyPrep ; -- Add more overload instances if needed for all categories! @@ -178,12 +178,12 @@ oper ----- -} - +{- -- If prepositions take case, add that as argument to mkPrep mkPrep = overload { mkPrep : Str -> Prep = \s -> lin Prep {s = s} ; } ; -{- + mkConj = overload { mkConj : (and : Str) -> Conj = \s -> … mkConj : (either : Str) -> (or : Str) -> Conj = \s -> … diff --git a/src/gaelic/ResGla.gf b/src/gaelic/ResGla.gf index aaf19a71..61ae9d89 100644 --- a/src/gaelic/ResGla.gf +++ b/src/gaelic/ResGla.gf @@ -249,10 +249,11 @@ oper -- or do we have an exhaustive list of prepositions that merge, and we can make that into a param and put on a LHS here? s : Case => Str ; -- TODO: is lenition a separate dimension from case? - + empty : Str ; -- to avoid metavariables -- TODO can we make this combo of inherent params leaner? - n : Number ; - p : Person ; + a : Agr ; + -- n : Number ; + -- p : Person ; d : Definiteness ; } ; @@ -260,8 +261,10 @@ oper emptyNP : LinNP = { s = \\_ => [] ; - n = Sg ; - p = P3 ; + a = NotPron Sg ; + empty = [] ; + -- n = Sg ; + -- p = P3 ; d = Indefinite ; } ; @@ -371,12 +374,15 @@ oper -- more on preps: Lamb, p.224 +param + Agr = Sg1 | Sg2 | Sg3 Gender | Pl1 | Pl2 | Pl3 | NotPron Number ; + oper LinPrep : Type = { - s : Str ; - - c2 : Definiteness => Case ; -- most often dative + s : Agr => Str ; -- bare: aig 'on', inflected: agam 'on me', agad 'on you', … + c2 : Definiteness => CoreCase ; -- most often dative + replacesPron : Bool ; -- NP has to keep track of if it comes from a Pron -- If your language has both pre- and postpositions, you need an inherent parameter in Prep to record which one a given Prep is. -- position : PreOrPost ; @@ -384,7 +390,38 @@ oper -- Some cause lenition—is that separate from case? } ; + mkPrep : (replacesPron : Bool) + -> (indef,defi : CoreCase) + -> (aig,agam,agad,aige,aice,againn,agaibh,aca : Str) + -> LinPrep = + \replaces,casIndef,casDef,aig,agam,agad,aige,aice,againn,agaibh,aca -> { + s = table { + NotPron _ => aig ; Sg1 => agam ; Sg2 => agad ; + Sg3 Masc => aige ; Sg3 Fem => aice ; + Pl1 => againn ; Pl2 => agaibh ; Pl3 => aca } ; + c2 = table {Indefinite => casIndef ; Definite => casDef} ; + replacesPron = replaces + } ; + smartPrep : (aig,agam,agad,aige,aice,againn,agaibh,aca : Str) -> LinPrep = + mkPrep True Dat Dat ; + + emptyPrep : LinPrep = { + s = \\_ => [] ; + c2 = \\_ => Dat ; + replacesPron = False + } ; + + aigPrep : LinPrep = smartPrep "aig" "agam" "agad" "aige" "aice" "againn" "agaibh" "aca" ; + airPrep : LinPrep = smartPrep "air" "orm" "ort" "air" "oirre" "oirrn" "oirbh" "orra" ; + annPrep : LinPrep = smartPrep "ann" "annam" "annad" "ann" "innte" "annainn" "annaibh" "annta" ; + àsPrep : LinPrep = smartPrep "às" "asam" "asad" "às" "aiste" "asainn" "asaibh" "asda" ; + bhoPrep : LinPrep = smartPrep "bho" "bhuam" "bhuat" "bhuaithe" "bhuaipe" "bhuainn" "buaibh" "bhuapa" ; +{- dePrep : LinPrep = …-} + doPrep : LinPrep = smartPrep "do" "dhomh" "dhut" "dha" "dhi" "dhuinn" "dhuibh" "dhiubh" ; +{- eadarPrep : LinPrep = …-} +{- foPrep : LinPrep = …-} + guPrep : LinPrep = smartPrep "gu" "ugam" "ugad" "uige" "uice" "ugainn" "ugaibh" "uca" ; -------------------------------------------------------------------------------- -- Adjectives -- Lamb p. 220 basic morphology, degree @@ -400,7 +437,7 @@ oper -- Verbs param - VForm = TODOVF Number Person ; + VForm = TODOVF Agr; oper LinV : Type = { @@ -432,7 +469,7 @@ oper c2 : LinPrep ; } ; - linVP : LinVP -> Str = \vp -> vp.s ! TODOVF Sg P3 ; + linVP : LinVP -> Str = \vp -> vp.s ! TODOVF (NotPron Sg) ; -------------------------------------------------------------------------------- -- Cl, S diff --git a/src/gaelic/SentenceGla.gf b/src/gaelic/SentenceGla.gf index dd86a7dd..9483fe6a 100644 --- a/src/gaelic/SentenceGla.gf +++ b/src/gaelic/SentenceGla.gf @@ -13,7 +13,7 @@ lin subj = np.s ! CC Nom ; pred = -- table {something with tense+polarity => - vp.s ! TODOVF np.n np.p + vp.s ! TODOVF np.a -- TODO: all of the VP's tense and polarity should be open here! -- PredVP only decides the subject. -- } diff --git a/src/gaelic/StructuralGla.gf b/src/gaelic/StructuralGla.gf index e76d33ca..800be0d6 100644 --- a/src/gaelic/StructuralGla.gf +++ b/src/gaelic/StructuralGla.gf @@ -90,35 +90,35 @@ lin nothing_NP = lin somebody_NP = lin something_NP = -------- +-------} -- Prep -lin above_Prep = mkPrep "" ; -lin after_Prep = mkPrep "" ; -lin before_Prep = mkPrep "" ; -lin behind_Prep = mkPrep "" ; -lin between_Prep = = mkPrep "" ; -lin by8agent_Prep = mkPrep "" ; -lin by8means_Prep = mkPrep "" ; -lin during_Prep = mkPrep "" ; -lin except_Prep = mkPrep "" ; -lin for_Prep = mkPrep "" ; -lin from_Prep = mkPrep "" ; -lin in8front_Prep = mkPrep "" ; -lin in_Prep = mkPrep "" ; -lin on_Prep = mkPrep "" ; -lin part_Prep = mkPrep ; -lin possess_Prep = mkPrep "" ; -lin through_Prep = mkPrep "" ; -lin to_Prep = mkPrep "k" ; -lin under_Prep = mkPrep "" ; -lin with_Prep = mkPrep "" ; -lin without_Prep = mkPrep "" ; +-- lin above_Prep = mkPrep "" ; +-- lin after_Prep = mkPrep "" ; +-- lin before_Prep = mkPrep "" ; +-- lin behind_Prep = mkPrep "" ; +-- lin between_Prep = = mkPrep "" ; +-- lin by8agent_Prep = mkPrep "" ; +-- lin by8means_Prep = mkPrep "" ; +-- lin during_Prep = mkPrep "" ; +-- lin except_Prep = mkPrep "" ; +lin for_Prep = ResGla.doPrep ; +lin from_Prep = ResGla.bhoPrep ; +-- lin in8front_Prep = mkPrep "" ; +lin in_Prep = ResGla.annPrep ; +lin on_Prep = ResGla.airPrep ; +-- lin part_Prep = mkPrep "" ; +-- lin possess_Prep = mkPrep "" ; +-- lin through_Prep = mkPrep "" ; +lin to_Prep = ResGla.guPrep ; +-- lin under_Prep = mkPrep "" ; +-- lin with_Prep = mkPrep "" ; +-- lin without_Prep = mkPrep "" ; ------- -- Pron --- Pronouns are closed class, no constructor in ParadigmsGla. +{-- Pronouns are closed class, no constructor in ParadigmsGla. lin it_Pron = lin i_Pron = lin youPol_Pron = From d4056e7db3e6c7962ef902cdc08c3a1ef4c4d742 Mon Sep 17 00:00:00 2001 From: Inari Listenmaa Date: Fri, 22 Aug 2025 16:47:03 +0200 Subject: [PATCH 10/15] add pronouns, very much WIP (no object forms, possessives) --- src/gaelic/CatGla.gf | 2 +- src/gaelic/NounGla.gf | 8 ++++---- src/gaelic/ResGla.gf | 24 +++++++++++++++--------- src/gaelic/StructuralGla.gf | 22 +++++++++++----------- 4 files changed, 31 insertions(+), 25 deletions(-) diff --git a/src/gaelic/CatGla.gf b/src/gaelic/CatGla.gf index ecb85c9f..4f589838 100644 --- a/src/gaelic/CatGla.gf +++ b/src/gaelic/CatGla.gf @@ -51,7 +51,7 @@ concrete CatGla of Cat = CommonX ** open ResGla, Coordination, Prelude in { CN = ResGla.LinCN ; NP = ResGla.LinNP ; - Pron = SS ; -- NB. Pronouns need enough info to become NP or Quant. + Pron = LinPron ; Det = ResGla.LinDet ; -- s : Str , n : Number Predet = SS ; Quant = ResGla.LinQuant ; -- s : Number => Str diff --git a/src/gaelic/NounGla.gf b/src/gaelic/NounGla.gf index 8021bc64..456c131e 100644 --- a/src/gaelic/NounGla.gf +++ b/src/gaelic/NounGla.gf @@ -12,15 +12,15 @@ concrete NounGla of Noun = CatGla ** open ResGla, Prelude in { a = NotPron det.n ; d = det.d } ; -{- + -- : PN -> NP ; -- Assuming that lincat PN = lincat NP - UsePN pn = pn ; + -- UsePN pn = pn ; -- : Pron -> NP ; -- Assuming that lincat Pron = lincat NP - UsePron pron = pron ; - + UsePron pron = emptyNP ** pron ; +{- -- : Predet -> NP -> NP ; -- only the man PredetNP predet np = diff --git a/src/gaelic/ResGla.gf b/src/gaelic/ResGla.gf index 61ae9d89..cb2acfa0 100644 --- a/src/gaelic/ResGla.gf +++ b/src/gaelic/ResGla.gf @@ -215,17 +215,22 @@ oper oper +-- TODO: possessive ?????? LinPron : Type = { s : Case => Str ; - n : Number ; - p : Person ; - -- g : Gender ; ?? -- we have already he_Pron and she_Pron in abstract syntax, does this affect inflection? + a : Agr ; + empty : Str ; -- to prevent metavariables } ; - mkPron : (_ : Str) -> Person -> Number -> LinPron = \str,per,num -> { - s = \\_ => str ; -- Pronoun inflection is often irregular, so possibly this constructor requires several forms as argument, even if mkNoun is nice and regular - p = per ; - n = num ; + -- TODO: nicer API where you can give Person, Number, Gender etc. + -- not this weird unintuitive Agr param + mkPron : (_ : Str) -> Agr -> LinPron = \str,agr -> { + s = table { + CC Nom => str ; + _ => "gam" -- TODO fix this + } ; + a = agr ; + empty = [] } ; --------------------------------------------- @@ -265,7 +270,7 @@ oper empty = [] ; -- n = Sg ; -- p = P3 ; - d = Indefinite ; + d = Definite ; } ; -------------------------------------------------------------------------------- @@ -378,9 +383,10 @@ param Agr = Sg1 | Sg2 | Sg3 Gender | Pl1 | Pl2 | Pl3 | NotPron Number ; oper + LinPrep : Type = { s : Agr => Str ; -- bare: aig 'on', inflected: agam 'on me', agad 'on you', … - + -- TODO: possessive forms c2 : Definiteness => CoreCase ; -- most often dative replacesPron : Bool ; -- NP has to keep track of if it comes from a Pron diff --git a/src/gaelic/StructuralGla.gf b/src/gaelic/StructuralGla.gf index 800be0d6..28823c35 100644 --- a/src/gaelic/StructuralGla.gf +++ b/src/gaelic/StructuralGla.gf @@ -118,17 +118,17 @@ lin to_Prep = ResGla.guPrep ; ------- -- Pron -{-- Pronouns are closed class, no constructor in ParadigmsGla. -lin it_Pron = -lin i_Pron = -lin youPol_Pron = -lin youSg_Pron = -lin he_Pron = -lin she_Pron = -lin we_Pron = -lin youPl_Pron = -lin they_Pron = - +-- Pronouns are closed class, no constructor in ParadigmsGla. +--lin it_Pron = +lin i_Pron = mkPron "mi" Sg1 ; +lin youPol_Pron = mkPron"sibh" Pl2 ; +lin youSg_Pron = mkPron "tu" Sg2 ; +lin he_Pron = mkPron "e" (Sg3 Masc) ; +lin she_Pron = mkPron "i" (Sg3 Fem) ; +lin we_Pron = mkPron "sinn" Pl1 ; +lin youPl_Pron = mkPron "sibh" Pl2 ; +lin they_Pron = mkPron "iad" Pl3 ; +{- lin whatPl_IP = lin whatSg_IP = lin whoPl_IP = From ed745708b25ea7bf84326b8a2a0c5b56683e0ca0 Mon Sep 17 00:00:00 2001 From: Inari Listenmaa Date: Tue, 26 Aug 2025 17:07:07 +0200 Subject: [PATCH 11/15] massive restructure, very broken, will fix later --- src/gaelic/AdverbGla.gf | 21 ++-- src/gaelic/NounGla.gf | 23 ++--- src/gaelic/ResGla.gf | 194 ++++++++++++++++++++++++++---------- src/gaelic/SentenceGla.gf | 2 +- src/gaelic/StructuralGla.gf | 16 +-- 5 files changed, 173 insertions(+), 83 deletions(-) diff --git a/src/gaelic/AdverbGla.gf b/src/gaelic/AdverbGla.gf index 848ad644..f550ecc8 100644 --- a/src/gaelic/AdverbGla.gf +++ b/src/gaelic/AdverbGla.gf @@ -13,13 +13,20 @@ lin -} -- : Prep -> NP -> Adv ; PrepNP prep np = { - s = prep.s ! np.a ++ - case of { - <_, NotPron _> | - => np.s ! CC (prep.c2 ! np.d) ; - _ => np.empty -- empty string to avoid metavariables - } - } ; + s = prepAndArt ++ noun + } where { + complCase : Case = CC (prep.c2 ! getDefi np.a) ; + prepStr : Str = prep.s ! agr2pagr np.a ; -- can be Prep or Prep+Pron merged + artStr : Str = np.art ! complCase ; + prepAndArt : Str = case np.a of { + NotPron (DDef _ Indefinite) => prepStr ++ artStr ; + _ => prepStr } ; + noun : Str = case of { + <_, NotPron _> | + => np.s ! complCase ; + _ => np.empty -- empty string to avoid metavariables + } + }; {- -- Adverbs can be modified by 'adadjectives', just like adjectives. diff --git a/src/gaelic/NounGla.gf b/src/gaelic/NounGla.gf index 456c131e..fb882653 100644 --- a/src/gaelic/NounGla.gf +++ b/src/gaelic/NounGla.gf @@ -8,9 +8,9 @@ concrete NounGla of Noun = CatGla ** open ResGla, Prelude in { -- : Det -> CN -> NP DetCN det cn = emptyNP ** { - s = \\c => det.s ! cn.g ! c ++ cn.s ! getNForm det.n det.d c ; - a = NotPron det.n ; - d = det.d + art = \\c => det.s ! cn.g ! c ; + s = \\c => cn.s ! getNForm det.dt c ; + a = NotPron det.dt ; } ; -- : PN -> NP ; @@ -19,7 +19,7 @@ concrete NounGla of Noun = CatGla ** open ResGla, Prelude in { -- : Pron -> NP ; -- Assuming that lincat Pron = lincat NP - UsePron pron = emptyNP ** pron ; + UsePron pron = emptyNP ** pron ** {a = IsPron pron.a} ; {- -- : Predet -> NP -> NP ; -- only the man PredetNP predet np = @@ -55,7 +55,7 @@ concrete NounGla of Noun = CatGla ** open ResGla, Prelude in { -} -- MassNP : CN -> NP ; MassNP cn = emptyNP ** { - s = \\c => cn.s ! getNForm Sg Indefinite c + s = \\c => cn.s ! getNForm (DDef Sg Indefinite) c ---- ?????? } ; @@ -68,7 +68,9 @@ concrete NounGla of Noun = CatGla ** open ResGla, Prelude in { DetQuant quant num = quant ** { s = \\g,c => getArt quant num.n g c ++ num.s ; s2 = \\g,c => "DUMMY" ; -- "teen" from numbers like seventeen - n = num.n ; + dt = case quant.qt of { + QDef defi => DDef num.n defi ; + QPoss agr => DPoss num.n agr } ; } ; -- : Quant -> Num -> Ord -> Det ; @@ -127,14 +129,11 @@ concrete NounGla of Noun = CatGla ** open ResGla, Prelude in { DefArt = ResGla.defArt ; -- : Quant - IndefArt = mkQuant [] Indefinite ; + IndefArt = mkQuant [] (QDef Indefinite) ; + -{- -- : Pron -> Quant -- my - PossPron pron = mkQuant pron.s ** { - - } ; --} + PossPron pron = mkQuant pron.poss (QPoss pron.a) ; --2 Common nouns diff --git a/src/gaelic/ResGla.gf b/src/gaelic/ResGla.gf index cb2acfa0..bae20ef2 100644 --- a/src/gaelic/ResGla.gf +++ b/src/gaelic/ResGla.gf @@ -44,11 +44,13 @@ param ; oper - getNForm : Number -> Definiteness -> Case -> NForm = \n,d,c -> + getNForm : DType -> Case -> NForm = \d,c -> case of { - => Def n Voc ; - => Indef n c ; - => Def n c + => Def n Voc ; + => Indef n c ; + => Def n c ; + => Indef n Nom ; -- as per Michal on Discord https://discord.com/channels/865093807343140874/865094084683366400/1409838154550087711 . TODO: Def or Indef nom ???? + => Def n c -- ???????????????? } ; LinN : Type = { @@ -215,20 +217,21 @@ oper oper --- TODO: possessive ?????? LinPron : Type = { s : Case => Str ; - a : Agr ; + a : PronAgr ; + poss : Str ; -- if a case is needed, it comes from the Prep! TODO verify this (do we ever need a dative for poss pron without a prep present? some preps merge, others not, but the pronoun is present in all the preps. why this way—I counted on there being fewer pronouns than prepositions.) empty : Str ; -- to prevent metavariables } ; -- TODO: nicer API where you can give Person, Number, Gender etc. -- not this weird unintuitive Agr param - mkPron : (_ : Str) -> Agr -> LinPron = \str,agr -> { + mkPron : (subj,poss : Str) -> PronAgr -> LinPron = \subj,poss,agr -> { s = table { - CC Nom => str ; + CC Nom => subj ; _ => "gam" -- TODO fix this } ; + poss = poss ; a = agr ; empty = [] } ; @@ -248,39 +251,44 @@ That's why I'm copying over the definition below, instead of the neater `LinNP : oper LinNP : Type = { --- art : Str ; -- to be replaced with a combo coming from Prep, if argument of PrepNP? see Lamb p. 225 + art, -- to be replaced with a combo coming from Prep, if argument of PrepNP? see Lamb p. 225 -- TODO: is that an issue when the allomorph has been chosen by an inherent param in CN? -- does that param need to be kept in LinNP, and Prep need an inflection table from that param? -- or do we have an exhaustive list of prepositions that merge, and we can make that into a param and put on a LHS here? s : Case => Str ; -- TODO: is lenition a separate dimension from case? empty : Str ; -- to avoid metavariables - -- TODO can we make this combo of inherent params leaner? - a : Agr ; - -- n : Number ; - -- p : Person ; - d : Definiteness ; + a : Agr ; -- includes whether it's pron and whether it's definite. TODO: probably can make even leaner (wasn't a prio so far). } ; - linNP : LinNP -> Str = \np -> np.s ! (CC Nom) ; + linNP : LinNP -> Str = \np -> np.art ! (CC Nom) ++ np.s ! (CC Nom) ; emptyNP : LinNP = { - s = \\_ => [] ; - a = NotPron Sg ; + s,art = \\_ => [] ; + a = NotPron (DDef Sg Indefinite) ; -- we assume pronouns are definite by default. also it just matters for PrepNP. empty = [] ; - -- n = Sg ; - -- p = P3 ; - d = Definite ; } ; -------------------------------------------------------------------------------- -- Det, Quant, Card, Ord param - QForm = QSg Gender CoreCase | QPl CoreCase ; + QuantForm = QSg Gender CoreCase | QPl CoreCase ; + QType = QDef Definiteness | QPoss PronAgr ; + DType = DDef Number Definiteness | DPoss Number PronAgr ; + + -- The minimum forms that preposition merges with + PrepAgr = PrepBase | PrepDefiniteArticle Number | PrepObjectPron PronAgr | PrepPossPron PronAgr ; oper - getQForm : Number -> Gender -> Case -> QForm = \n,g,c -> case of { + agr2pagr : Agr -> PrepAgr = \a -> case a of { + NotPron (DDef n Definite) => PrepDefiniteArticle n ; + NotPron (DPoss n agr) => PrepPossPron agr ; + IsPron agr => PrepObjectPron agr ; + NotPron _ => PrepBase + } ; + + getQuantForm : Number -> Gender -> Case -> QuantForm = \n,g,c -> case of { => QSg g c ; => QSg g Nom ; --- ?????? => QPl c ; @@ -289,21 +297,20 @@ oper getArt : LinQuant -> Number -> Gender -> Case -> Str = \quant,n,g,c -> case c of { Voc => "" ; -- TODO: add empty field to article to not get metavariables - _ => quant.s ! getQForm n g c + _ => quant.s ! getQuantForm n g c } ; LinQuant : Type = { s -- quantifier in a context, e.g. 'this (cat) (is nice)' - : QForm => Str ; + : QuantForm => Str ; sp : Str ; -- quantifier as standalone, e.g. 'this (is nice)' - d : Definiteness ; + qt : QType ; -- Definite, Indefinite or Possessive } ; LinDet : Type = { s,s2 : Gender => Case => Str ; sp : Str ; - n : Number ; - d : Definiteness ; + dt : DType ; -- includes number } ; LinNum : Type = { @@ -312,18 +319,17 @@ oper } ; -- Can you reuse your mkNoun? Do nouns and quantifiers inflect the same way? - mkQuant : Str -> Definiteness -> LinQuant = \this,d -> { + mkQuant : Str -> QType -> LinQuant = \this,qt -> { s = \\_ => this ; sp = this ; - d = d ; + qt = qt ; } ; - mkDet : (seven, teen : Str) -> Number -> LinDet = \aon, deug, num -> { + mkDet : (seven, teen : Str) -> Definiteness -> Number -> LinDet = \aon, deug, defi, num -> { s = \\_,_ => aon ; s2 = \\_,_ => deug ; sp = aon ; - n = num ; - d = Indefinite -- TODO add as param + dt = DDef num defi } ; -- Allomorphs of the definite article @@ -359,7 +365,7 @@ oper QPl _ => NA } ; sp = "an" ; --- meaningless for DefArt - d = Definite ; + qt = QDef Definite ; } ; -------------------------------------------------------------------------------- -- Adpositions @@ -380,15 +386,20 @@ oper -- more on preps: Lamb, p.224 param - Agr = Sg1 | Sg2 | Sg3 Gender | Pl1 | Pl2 | Pl3 | NotPron Number ; + PronAgr = Sg1 | Sg2 | Sg3 Gender | Pl1 | Pl2 | Pl3 ; + -- PronType = Object | Possessive ; + Agr = NotPron DType | IsPron PronAgr ; oper + getDefi : Agr -> Definiteness = \a -> case a of { + NotPron (DDef n d) => d ; + _ => Definite + } ; LinPrep : Type = { - s : Agr => Str ; -- bare: aig 'on', inflected: agam 'on me', agad 'on you', … - -- TODO: possessive forms + s : PrepAgr => Str ; -- bare: aig 'on', inflected: agam 'on me', agad 'on you', … c2 : Definiteness => CoreCase ; -- most often dative - replacesPron : Bool ; -- NP has to keep track of if it comes from a Pron + replacesObjPron : Bool ; -- NP has to keep track of if it comes from a Pron -- If your language has both pre- and postpositions, you need an inherent parameter in Prep to record which one a given Prep is. -- position : PreOrPost ; @@ -396,38 +407,93 @@ oper -- Some cause lenition—is that separate from case? } ; - mkPrep : (replacesPron : Bool) + PrepForms : Type = {base, sg1, sg2, sg3M, sg3F, pl1, pl2, pl3 : Str} ; + + invarPrepForms : Str -> PrepForms = \str -> + {base=str ; sg1=str+"mo^L"; sg2=str+"do^L"; sg3M=str+"a^L"; + sg3F=str+"a^H"; pl1=str+"àr^N"; pl2=str+"ùr^N"; pl3=str+AN} ; -- AN is defined as an allomorph to def art, TODO does the possessive add t- before vowel? + + mkPrep : (replacesObjPron : Bool) -> (indef,defi : CoreCase) - -> (aig,agam,agad,aige,aice,againn,agaibh,aca : Str) + -> (objForms, possForms : PrepForms) -> LinPrep = - \replaces,casIndef,casDef,aig,agam,agad,aige,aice,againn,agaibh,aca -> { + \replaces,casIndef,casDef,objForms,possForms -> { s = table { - NotPron _ => aig ; Sg1 => agam ; Sg2 => agad ; - Sg3 Masc => aige ; Sg3 Fem => aice ; - Pl1 => againn ; Pl2 => agaibh ; Pl3 => aca } ; + PrepBase => aig ; + PrepDefiniteArticle Sg => aig + "✨" ++ BIND ++ AN ; -- TODO: merge with article!!!!!! + PrepDefiniteArticle Pl => aig + "✨" ++ BIND ++ NA ; -- TODO: merge with article!!!!!! + PrepObjectPron Sg1 => agam ; + PrepObjectPron Sg2 => agad ; + PrepObjectPron (Sg3 Masc) => aige ; + PrepObjectPron (Sg3 Fem) => aice ; + PrepObjectPron Pl1 => againn ; + PrepObjectPron Pl2 => agaibh ; + PrepObjectPron Pl3 => aca ; + PrepPossPron Sg1 => gam ; + PrepPossPron Sg2 => gad ; + PrepPossPron (Sg3 Masc) => ga_L ; + PrepPossPron (Sg3 Fem) => ga_H ; + PrepPossPron Pl1 => gar ; + PrepPossPron Pl2 => gur ; + PrepPossPron Pl3 => gan } ; c2 = table {Indefinite => casIndef ; Definite => casDef} ; - replacesPron = replaces + replacesObjPron = replaces + } where { + aig = objForms.base ; agam = objForms.sg1 ; agad = objForms.sg2 ; + aige = objForms.sg3M ; aice = objForms.sg3F ; + againn = objForms.pl1 ; agaibh = objForms.pl2 ; aca = objForms.pl3 ; + gam = possForms.sg1 ; gad = possForms.sg2 ; + ga_L = possForms.sg3M ; ga_H = possForms.sg3F ; + gar = possForms.pl1 ; gur = possForms.pl2 ; gan = possForms.pl3 ; } ; - smartPrep : (aig,agam,agad,aige,aice,againn,agaibh,aca : Str) -> LinPrep = + smartPrep : (objForms, possForms : PrepForms) -> LinPrep = mkPrep True Dat Dat ; emptyPrep : LinPrep = { s = \\_ => [] ; + poss = \\_ => [] ; c2 = \\_ => Dat ; - replacesPron = False + replacesObjPron = False } ; - aigPrep : LinPrep = smartPrep "aig" "agam" "agad" "aige" "aice" "againn" "agaibh" "aca" ; - airPrep : LinPrep = smartPrep "air" "orm" "ort" "air" "oirre" "oirrn" "oirbh" "orra" ; - annPrep : LinPrep = smartPrep "ann" "annam" "annad" "ann" "innte" "annainn" "annaibh" "annta" ; - àsPrep : LinPrep = smartPrep "às" "asam" "asad" "às" "aiste" "asainn" "asaibh" "asda" ; - bhoPrep : LinPrep = smartPrep "bho" "bhuam" "bhuat" "bhuaithe" "bhuaipe" "bhuainn" "buaibh" "bhuapa" ; + aigPrep : LinPrep = + smartPrep + {base="aig"; sg1="agam"; sg2="agad"; sg3M="aige"; sg3F="aice"; pl1="againn"; pl2="agaibh"; pl3="aca"} + {base="aig"; sg1="'gam^L"; sg2="'gad^L"; sg3M="'ga^L"; sg3F="'ga^H"; pl1="'gar^N"; pl2="'gur^N"; pl3="'gan"} ; + airPrep : LinPrep = + smartPrep + {base="air"; sg1="orm"; sg2="ort"; sg3M="air"; sg3F="oirre"; pl1="oirrn"; pl2="oirbh"; pl3="orra"} + (invarPrepForms "air") ; + + annPrep : LinPrep = + smartPrep + {base="ann"; sg1="annam"; sg2="annad"; sg3M="ann"; sg3F="innte"; pl1="annainn"; pl2="annaibh"; pl3="annta"} + {base="ann"; sg1="'nam^L"; sg2="'nad^L"; sg3M="'na^L"; sg3F="'na^H"; pl1="'nar^N"; pl2="'nur^N"; pl3="'nan"} ; + + àsPrep : LinPrep = + smartPrep + {base="às"; sg1="asam"; sg2="asad"; sg3M="às"; sg3F="aiste"; pl1="asainn"; pl2="asaibh"; pl3="asda"} + (invarPrepForms "às") ; + + bhoPrep : LinPrep = + smartPrep + {base="bho"; sg1="bhuam"; sg2="bhuat"; sg3M="bhuaithe"; sg3F="bhuaipe"; pl1="bhuainn"; pl2="buaibh"; pl3="bhuapa"} + {base="bho"; sg1="bhom^L"; sg2="bhod^L"; sg3M="bho a^L"; sg3F="bho a^H"; pl1="bhor^N"; pl2="bhu^N"; pl3="bhon"} ; {- dePrep : LinPrep = …-} - doPrep : LinPrep = smartPrep "do" "dhomh" "dhut" "dha" "dhi" "dhuinn" "dhuibh" "dhiubh" ; + + doPrep : LinPrep = + smartPrep + {base="do"; sg1="dhomh"; sg2="dhut"; sg3M="dha"; sg3F="dhi"; pl1="dhuinn"; pl2="dhuibh"; pl3="dhiubh"} + {base="bho"; sg1="dom^L"; sg2="dod^L"; sg3M="dhaL^"; sg3F="dha^H"; pl1="dor^N"; pl2="dhur^N"; pl3="don"} ; + {- eadarPrep : LinPrep = …-} {- foPrep : LinPrep = …-} - guPrep : LinPrep = smartPrep "gu" "ugam" "ugad" "uige" "uice" "ugainn" "ugaibh" "uca" ; + guPrep : LinPrep = + smartPrep + {base="gu"; sg1="ugam"; sg2="ugad"; sg3M="uige"; sg3F="uice"; pl1="ugainn"; pl2="ugaibh"; pl3="uca"} + {base="gu"; sg1="gum^L"; sg2="gud^L"; sg3M="gu a^L"; sg3F="gu a^H"; pl1="gar^N"; pl2="gur^N"; pl3="gun"} ; + -------------------------------------------------------------------------------- -- Adjectives -- Lamb p. 220 basic morphology, degree @@ -443,9 +509,27 @@ oper -- Verbs param - VForm = TODOVF Agr; + VAgr = VSg1 | VSg2 | VSg3 | VPl1 | VPl2 | VPl3 ; + VForm = VInf | VPres VAgr | VPast VAgr ; -- TODO oper + nagr2vagr : Agr -> VAgr = \a -> case a of { + NotPron (DDef Sg _) => VSg3 ; + NotPron (DDef Pl _) => VPl3 ; + + -- this is the number of the possessee—number of possessor only matters for PrepNP! + NotPron (DPoss Sg _) => VSg3 ; + NotPron (DPoss Pl _) => VPl3 ; + + -- this is subject pronoun, which agrees with verb + IsPron Sg1 => VSg1 ; + IsPron Sg2 => VSg2 ; + IsPron (Sg3 _) => VSg3 ; + IsPron Pl1 => VPl1 ; + IsPron Pl2 => VPl2 ; + IsPron Pl3 => VPl3 + } ; + LinV : Type = { s : VForm => Str } ; @@ -475,7 +559,7 @@ oper c2 : LinPrep ; } ; - linVP : LinVP -> Str = \vp -> vp.s ! TODOVF (NotPron Sg) ; + linVP : LinVP -> Str = \vp -> vp.s ! VInf ; -------------------------------------------------------------------------------- -- Cl, S diff --git a/src/gaelic/SentenceGla.gf b/src/gaelic/SentenceGla.gf index 9483fe6a..36c219ef 100644 --- a/src/gaelic/SentenceGla.gf +++ b/src/gaelic/SentenceGla.gf @@ -13,7 +13,7 @@ lin subj = np.s ! CC Nom ; pred = -- table {something with tense+polarity => - vp.s ! TODOVF np.a + vp.s ! VPres (nagr2vagr np.a) -- TODO: all of the VP's tense and polarity should be open here! -- PredVP only decides the subject. -- } diff --git a/src/gaelic/StructuralGla.gf b/src/gaelic/StructuralGla.gf index 28823c35..5d47c498 100644 --- a/src/gaelic/StructuralGla.gf +++ b/src/gaelic/StructuralGla.gf @@ -120,14 +120,14 @@ lin to_Prep = ResGla.guPrep ; -- Pronouns are closed class, no constructor in ParadigmsGla. --lin it_Pron = -lin i_Pron = mkPron "mi" Sg1 ; -lin youPol_Pron = mkPron"sibh" Pl2 ; -lin youSg_Pron = mkPron "tu" Sg2 ; -lin he_Pron = mkPron "e" (Sg3 Masc) ; -lin she_Pron = mkPron "i" (Sg3 Fem) ; -lin we_Pron = mkPron "sinn" Pl1 ; -lin youPl_Pron = mkPron "sibh" Pl2 ; -lin they_Pron = mkPron "iad" Pl3 ; +lin i_Pron = mkPron "mi" "mo^L" Sg1 ; +lin youPol_Pron = youPl_Pron ; +lin youSg_Pron = mkPron "tu" "do^L" Sg2 ; +lin he_Pron = mkPron "e" "a^L" (Sg3 Masc) ; +lin she_Pron = mkPron "i" "a^H" (Sg3 Fem) ; +lin we_Pron = mkPron "sinn" "àr^N" Pl1 ; +lin youPl_Pron = mkPron"sibh" "ùr^N" Pl2 ; +lin they_Pron = mkPron "iad" AN Pl3 ; {- lin whatPl_IP = lin whatSg_IP = From d652c81fa721433973bb18f7451048195d41e107 Mon Sep 17 00:00:00 2001 From: Inari Listenmaa Date: Wed, 27 Aug 2025 17:22:33 +0200 Subject: [PATCH 12/15] WIP more preposition contractions + phonological mutation rules --- src/gaelic/AdverbGla.gf | 4 ++- src/gaelic/NounGla.gf | 7 ++-- src/gaelic/ResGla.gf | 69 +++++++++++++++++++++++++++------------ src/gaelic/SentenceGla.gf | 2 +- 4 files changed, 57 insertions(+), 25 deletions(-) diff --git a/src/gaelic/AdverbGla.gf b/src/gaelic/AdverbGla.gf index f550ecc8..700f80b0 100644 --- a/src/gaelic/AdverbGla.gf +++ b/src/gaelic/AdverbGla.gf @@ -15,7 +15,9 @@ lin PrepNP prep np = { s = prepAndArt ++ noun } where { - complCase : Case = CC (prep.c2 ! getDefi np.a) ; + complCase : NPCase = case np.a of { + NotPron (DPoss _ (Sg1|Sg2|Sg3 Masc)) => NPLenited ; + _ => NPC (prep.c2 ! getDefi np.a) } ; prepStr : Str = prep.s ! agr2pagr np.a ; -- can be Prep or Prep+Pron merged artStr : Str = np.art ! complCase ; prepAndArt : Str = case np.a of { diff --git a/src/gaelic/NounGla.gf b/src/gaelic/NounGla.gf index fb882653..dae16a3b 100644 --- a/src/gaelic/NounGla.gf +++ b/src/gaelic/NounGla.gf @@ -8,7 +8,7 @@ concrete NounGla of Noun = CatGla ** open ResGla, Prelude in { -- : Det -> CN -> NP DetCN det cn = emptyNP ** { - art = \\c => det.s ! cn.g ! c ; + art = \\c => det.s ! cn.g ! npc2c c ; s = \\c => cn.s ! getNForm det.dt c ; a = NotPron det.dt ; } ; @@ -19,7 +19,10 @@ concrete NounGla of Noun = CatGla ** open ResGla, Prelude in { -- : Pron -> NP ; -- Assuming that lincat Pron = lincat NP - UsePron pron = emptyNP ** pron ** {a = IsPron pron.a} ; + UsePron pron = emptyNP ** pron ** { + s = \\c => pron.s ! npc2cc c ; + a = IsPron pron.a + } ; {- -- : Predet -> NP -> NP ; -- only the man PredetNP predet np = diff --git a/src/gaelic/ResGla.gf b/src/gaelic/ResGla.gf index bae20ef2..08253255 100644 --- a/src/gaelic/ResGla.gf +++ b/src/gaelic/ResGla.gf @@ -31,26 +31,47 @@ param Gender = Masc | Fem ; CoreCase = Nom | Gen | Dat ; Case = CC CoreCase | Voc ; + NPCase = NPC CoreCase | NPVoc | NPLenited ; Number = Sg | Pl ; Person = P1 | P2 | P3 ; Definiteness = Definite | Indefinite ; -- Some prepositions govern different case when definite vs. indefinite +oper + npc2cc : NPCase -> CoreCase = \npc -> case npc of { + NPC c => c ; + _ => Nom ------ TODO check? NPVoc and NPLenited (which is not a case but this is cheaper) + } ; + npc2c : NPCase -> Case = \npc -> case npc of { + NPC c => CC c ; + NPVoc => Voc ; + _ => CC Nom ---- this is just lenited TODO does this make any sense + } ; + +param NForm = Indef Number CoreCase | Def Number Case + | Lenited -- keep this separate from case, because some prepositions' requirement of lenited form overrides the usual case requirement | Dual -- only after number 2, only for a handful of nouns. TODO: does it have different cases? ; + {- + * The 1st person singular, 2nd person singular and 3rd person singular masculine forms here trigger lenition (indicated with a superscript L). + * 1st and 2nd person plurals trigger the prefixation of n- onto words beginning with vowels (nasalization), This is indicated with a superscript N. the pronunciation of the a consonant following these and the 3rd person plural is also frequently voiced or nasalized. + * Finally the 3rd person feminine forms prefix an onto words beginning with a vowel. This is indicated with H. + -} + oper - getNForm : DType -> Case -> NForm = \d,c -> + getNForm : DType -> NPCase -> NForm = \d,c -> case of { - => Def n Voc ; - => Indef n c ; - => Def n c ; - => Indef n Nom ; -- as per Michal on Discord https://discord.com/channels/865093807343140874/865094084683366400/1409838154550087711 . TODO: Def or Indef nom ???? - => Def n c -- ???????????????? + <_, NPLenited> => Lenited ; -- bit of a hack + => Def n Voc ; + => Indef n c ; + => Def n (npc2c npc) ; + => Indef n Nom ; -- as per Michal on Discord https://discord.com/channels/865093807343140874/865094084683366400/1409838154550087711 . TODO: Def or Indef nom ???? + => Def n (npc2c npc) -- ???????????????? } ; LinN : Type = { @@ -142,7 +163,8 @@ oper Def Pl (CC Gen) => n.base ; Def Pl (CC Dat) => n.pl ; Def Pl Voc => glue n.lenited "a" ; - Dual => fm n.palatalised n.base -- TODO: is this correct? only for 1-syllable feminine nouns? + Dual => fm n.palatalised n.base ; -- TODO: is this correct? only for 1-syllable feminine nouns? + Lenited => n.lenited } } where { fm : Str -> Str -> Str = \fem,masc -> case n.g of { @@ -218,7 +240,7 @@ oper oper LinPron : Type = { - s : Case => Str ; + s : CoreCase => Str ; a : PronAgr ; poss : Str ; -- if a case is needed, it comes from the Prep! TODO verify this (do we ever need a dative for poss pron without a prep present? some preps merge, others not, but the pronoun is present in all the preps. why this way—I counted on there being fewer pronouns than prepositions.) empty : Str ; -- to prevent metavariables @@ -228,8 +250,8 @@ oper -- not this weird unintuitive Agr param mkPron : (subj,poss : Str) -> PronAgr -> LinPron = \subj,poss,agr -> { s = table { - CC Nom => subj ; - _ => "gam" -- TODO fix this + Nom => subj ; + _ => "gam" -- TODO fix this } ; poss = poss ; a = agr ; @@ -256,12 +278,12 @@ oper -- does that param need to be kept in LinNP, and Prep need an inflection table from that param? -- or do we have an exhaustive list of prepositions that merge, and we can make that into a param and put on a LHS here? - s : Case => Str ; -- TODO: is lenition a separate dimension from case? + s : NPCase => Str ; -- TODO: is lenition a separate dimension from case? empty : Str ; -- to avoid metavariables a : Agr ; -- includes whether it's pron and whether it's definite. TODO: probably can make even leaner (wasn't a prio so far). } ; - linNP : LinNP -> Str = \np -> np.art ! (CC Nom) ++ np.s ! (CC Nom) ; + linNP : LinNP -> Str = \np -> np.art ! (NPC Nom) ++ np.s ! (NPC Nom) ; emptyNP : LinNP = { s,art = \\_ => [] ; @@ -290,9 +312,9 @@ oper getQuantForm : Number -> Gender -> Case -> QuantForm = \n,g,c -> case of { => QSg g c ; - => QSg g Nom ; --- ?????? + => QSg g Nom ; --- ?????? => QPl c ; - => QPl Nom --- ?????? + => QPl Nom --- ?????? } ; getArt : LinQuant -> Number -> Gender -> Case -> Str = \quant,n,g,c -> case c of { @@ -409,9 +431,14 @@ oper PrepForms : Type = {base, sg1, sg2, sg3M, sg3F, pl1, pl2, pl3 : Str} ; + H, N : Str ; + H = pre {#vowel => "h" ++ BIND ; _ => []} ; + N = pre {#vowel => "n-" ++ BIND ; _ => []} ; + + invarPrepForms : Str -> PrepForms = \str -> - {base=str ; sg1=str+"mo^L"; sg2=str+"do^L"; sg3M=str+"a^L"; - sg3F=str+"a^H"; pl1=str+"àr^N"; pl2=str+"ùr^N"; pl3=str+AN} ; -- AN is defined as an allomorph to def art, TODO does the possessive add t- before vowel? + {base=str ; sg1=str++"mo^L"; sg2=str++"do^L"; sg3M=str++"a^L"; + sg3F=str++"a"++H; pl1=str++"àr"++N; pl2=str++"ùr"++N; pl3=str++AN} ; -- AN is defined as an allomorph to def art, TODO does the possessive add t- before vowel? mkPrep : (replacesObjPron : Bool) -> (indef,defi : CoreCase) @@ -460,7 +487,7 @@ oper aigPrep : LinPrep = smartPrep {base="aig"; sg1="agam"; sg2="agad"; sg3M="aige"; sg3F="aice"; pl1="againn"; pl2="agaibh"; pl3="aca"} - {base="aig"; sg1="'gam^L"; sg2="'gad^L"; sg3M="'ga^L"; sg3F="'ga^H"; pl1="'gar^N"; pl2="'gur^N"; pl3="'gan"} ; + {base="aig"; sg1="'gam^L"; sg2="'gad^L"; sg3M="'ga^L"; sg3F="'ga"++H; pl1="'gar"++N; pl2="'gur"++N; pl3="'gan"} ; airPrep : LinPrep = smartPrep {base="air"; sg1="orm"; sg2="ort"; sg3M="air"; sg3F="oirre"; pl1="oirrn"; pl2="oirbh"; pl3="orra"} @@ -469,7 +496,7 @@ oper annPrep : LinPrep = smartPrep {base="ann"; sg1="annam"; sg2="annad"; sg3M="ann"; sg3F="innte"; pl1="annainn"; pl2="annaibh"; pl3="annta"} - {base="ann"; sg1="'nam^L"; sg2="'nad^L"; sg3M="'na^L"; sg3F="'na^H"; pl1="'nar^N"; pl2="'nur^N"; pl3="'nan"} ; + {base="ann"; sg1="'nam^L"; sg2="'nad^L"; sg3M="'na^L"; sg3F="'na"++H; pl1="'nar"++N; pl2="'nur"++N; pl3="'nan"} ; àsPrep : LinPrep = smartPrep @@ -479,20 +506,20 @@ oper bhoPrep : LinPrep = smartPrep {base="bho"; sg1="bhuam"; sg2="bhuat"; sg3M="bhuaithe"; sg3F="bhuaipe"; pl1="bhuainn"; pl2="buaibh"; pl3="bhuapa"} - {base="bho"; sg1="bhom^L"; sg2="bhod^L"; sg3M="bho a^L"; sg3F="bho a^H"; pl1="bhor^N"; pl2="bhu^N"; pl3="bhon"} ; + {base="bho"; sg1="bhom^L"; sg2="bhod^L"; sg3M="bho a^L"; sg3F="bho a"++H; pl1="bhor"++N; pl2="bhu"++N; pl3="bhon"} ; {- dePrep : LinPrep = …-} doPrep : LinPrep = smartPrep {base="do"; sg1="dhomh"; sg2="dhut"; sg3M="dha"; sg3F="dhi"; pl1="dhuinn"; pl2="dhuibh"; pl3="dhiubh"} - {base="bho"; sg1="dom^L"; sg2="dod^L"; sg3M="dhaL^"; sg3F="dha^H"; pl1="dor^N"; pl2="dhur^N"; pl3="don"} ; + {base="bho"; sg1="dom^L"; sg2="dod^L"; sg3M="dha^L"; sg3F="dha"++H; pl1="dor"++N; pl2="dhur"++N; pl3="don"} ; {- eadarPrep : LinPrep = …-} {- foPrep : LinPrep = …-} guPrep : LinPrep = smartPrep {base="gu"; sg1="ugam"; sg2="ugad"; sg3M="uige"; sg3F="uice"; pl1="ugainn"; pl2="ugaibh"; pl3="uca"} - {base="gu"; sg1="gum^L"; sg2="gud^L"; sg3M="gu a^L"; sg3F="gu a^H"; pl1="gar^N"; pl2="gur^N"; pl3="gun"} ; + {base="gu"; sg1="gum^L"; sg2="gud^L"; sg3M="gu a^L"; sg3F="gu a"++H; pl1="gar"++N; pl2="gur"++N; pl3="gun"} ; -------------------------------------------------------------------------------- -- Adjectives diff --git a/src/gaelic/SentenceGla.gf b/src/gaelic/SentenceGla.gf index 36c219ef..c7a8634b 100644 --- a/src/gaelic/SentenceGla.gf +++ b/src/gaelic/SentenceGla.gf @@ -10,7 +10,7 @@ lin -- : NP -> VP -> Cl PredVP np vp = { - subj = np.s ! CC Nom ; + subj = np.s ! NPC Nom ; pred = -- table {something with tense+polarity => vp.s ! VPres (nagr2vagr np.a) From 8c25bdeacc42bb8850c9e1439642a93fa90efb26 Mon Sep 17 00:00:00 2001 From: Inari Listenmaa Date: Thu, 28 Aug 2025 15:43:56 +0200 Subject: [PATCH 13/15] add lenition in the case table as separate dimension for Nom and Dat --- src/gaelic/AdverbGla.gf | 10 ++- src/gaelic/NounGla.gf | 4 +- src/gaelic/ResGla.gf | 157 ++++++++++++++++++++++---------------- src/gaelic/SentenceGla.gf | 2 +- 4 files changed, 100 insertions(+), 73 deletions(-) diff --git a/src/gaelic/AdverbGla.gf b/src/gaelic/AdverbGla.gf index 700f80b0..5a832613 100644 --- a/src/gaelic/AdverbGla.gf +++ b/src/gaelic/AdverbGla.gf @@ -15,9 +15,13 @@ lin PrepNP prep np = { s = prepAndArt ++ noun } where { - complCase : NPCase = case np.a of { - NotPron (DPoss _ (Sg1|Sg2|Sg3 Masc)) => NPLenited ; - _ => NPC (prep.c2 ! getDefi np.a) } ; + defaultCase : CoreCase = prep.c2 ! getDefi np.a ; + complCase : Case = case of { + + => CC (Dat Lenited) ; -- force lenition if possessive triggers it + + => CC (Nom Lenited) ; -- force lenition if possessive triggers it + _ => CC defaultCase } ; prepStr : Str = prep.s ! agr2pagr np.a ; -- can be Prep or Prep+Pron merged artStr : Str = np.art ! complCase ; prepAndArt : Str = case np.a of { diff --git a/src/gaelic/NounGla.gf b/src/gaelic/NounGla.gf index dae16a3b..40051660 100644 --- a/src/gaelic/NounGla.gf +++ b/src/gaelic/NounGla.gf @@ -8,7 +8,7 @@ concrete NounGla of Noun = CatGla ** open ResGla, Prelude in { -- : Det -> CN -> NP DetCN det cn = emptyNP ** { - art = \\c => det.s ! cn.g ! npc2c c ; + art = det.s ! cn.g ; s = \\c => cn.s ! getNForm det.dt c ; a = NotPron det.dt ; } ; @@ -58,7 +58,7 @@ concrete NounGla of Noun = CatGla ** open ResGla, Prelude in { -} -- MassNP : CN -> NP ; MassNP cn = emptyNP ** { - s = \\c => cn.s ! getNForm (DDef Sg Indefinite) c ---- ?????? + s = \\c => cn.s ! getNForm (DDef Sg Indefinite) c -- no article, singular indefinite forms, open for cases+mutations } ; diff --git a/src/gaelic/ResGla.gf b/src/gaelic/ResGla.gf index 08253255..3344124f 100644 --- a/src/gaelic/ResGla.gf +++ b/src/gaelic/ResGla.gf @@ -29,9 +29,10 @@ https://inariksit.github.io/gf/2018/08/28/gf-gotchas.html#my-naming-scheme-for-l param Gender = Masc | Fem ; - CoreCase = Nom | Gen | Dat ; + CoreCase = Nom Mutation | Gen | Dat Mutation ; Case = CC CoreCase | Voc ; - NPCase = NPC CoreCase | NPVoc | NPLenited ; +-- NPCase = NPC CoreCase | NPVoc ; + Mutation = Lenited | NoMutation ; Number = Sg | Pl ; @@ -39,39 +40,28 @@ param Definiteness = Definite | Indefinite ; -- Some prepositions govern different case when definite vs. indefinite oper - npc2cc : NPCase -> CoreCase = \npc -> case npc of { - NPC c => c ; - _ => Nom ------ TODO check? NPVoc and NPLenited (which is not a case but this is cheaper) - } ; - npc2c : NPCase -> Case = \npc -> case npc of { - NPC c => CC c ; - NPVoc => Voc ; - _ => CC Nom ---- this is just lenited TODO does this make any sense + NOM : CoreCase = Nom NoMutation ; -- shorthand + + npc2cc : Case -> CoreCase = \npc -> case npc of { + CC c => c ; + _ => NOM } ; param NForm = Indef Number CoreCase | Def Number Case - | Lenited -- keep this separate from case, because some prepositions' requirement of lenited form overrides the usual case requirement | Dual -- only after number 2, only for a handful of nouns. TODO: does it have different cases? ; - {- - * The 1st person singular, 2nd person singular and 3rd person singular masculine forms here trigger lenition (indicated with a superscript L). - * 1st and 2nd person plurals trigger the prefixation of n- onto words beginning with vowels (nasalization), This is indicated with a superscript N. the pronunciation of the a consonant following these and the 3rd person plural is also frequently voiced or nasalized. - * Finally the 3rd person feminine forms prefix an onto words beginning with a vowel. This is indicated with H. - -} - oper - getNForm : DType -> NPCase -> NForm = \d,c -> + getNForm : DType -> Case -> NForm = \d,c -> case of { - <_, NPLenited> => Lenited ; -- bit of a hack - => Def n Voc ; - => Indef n c ; - => Def n (npc2c npc) ; - => Indef n Nom ; -- as per Michal on Discord https://discord.com/channels/865093807343140874/865094084683366400/1409838154550087711 . TODO: Def or Indef nom ???? - => Def n (npc2c npc) -- ???????????????? + => Def n Voc ; + => Indef n c ; + => Def n c ; + => Indef n NOM ; -- as per Michal on Discord https://discord.com/channels/865093807343140874/865094084683366400/1409838154550087711 . TODO: Def or Indef nom ???? + => Def n c -- ???????????????? } ; LinN : Type = { @@ -81,7 +71,8 @@ oper -- TODO: for nouns that only use suffixes, should these just show theoretical forms? lenited, -- thunnag fhuil loch fhear palatalised, -- tunnaig fuil loch fir - lenited_palatalised -- thunnaig fhuil loch fhir + lenited_palatalised, -- thunnaig fhuil loch fhir + lenited_plural : Str ; g : Gender } ; @@ -90,6 +81,7 @@ oper smartN : (nom,gen,pl : Str) -> Gender -> LinN = \loch,locha,lochan,g -> { gen = locha ; pl = lochan ; + lenited_plural = lenite lochan ; base, lenited, palatalised, @@ -99,17 +91,19 @@ oper smartN : (base : Str) -> Gender -> LinN = \tunnag,g -> { base = tunnag ; gen = fm (tunnaig + "e") tunnaig ; - pl = fm (tunnag + "an") tunnaig ; -- for other allomorphs, use 4-argument paradigm + pl = plural ; -- for other allomorphs, use 4-argument paradigm + lenited_plural = lenite plural ; lenited = thunnag ; palatalised = tunnaig ; lenited_palatalised = thunnaig ; g = g } where { + fm : Str -> Str -> Str = \fem,masc -> case g of { + Fem => fem ; Masc => masc } ; tunnaig : Str = palatalise tunnag ; thunnag : Str = lenite tunnag ; thunnaig : Str = lenite tunnaig ; - fm : Str -> Str -> Str = \fem,masc -> case g of { - Fem => fem ; Masc => masc } + plural : Str = fm (tunnag + "an") tunnaig ; } } ; @@ -135,13 +129,14 @@ oper -- For inflection paradigms, see http://www.grammaticalframework.org/doc/tutorial/gf-tutorial.html#toc56 - mkNoun : (b,g,pl,l,p,lp : Str) -> Gender -> LinN = \b,gen,pl,l,p,lp,g -> { + mkNoun : (b,g,pl,l,p,lp,lpl : Str) -> Gender -> LinN = \b,gen,pl,l,p,lp,lpl,g -> { base = b ; -- tunnag fuil loch fear litir gen = gen ; -- tunnaige fala locha fir litreach pl = pl ; -- tunnagan lochan fir litrichean lenited = l ; -- thunnag fhuil loch fhear litir ? palatalised = p ; -- tunnaig fuil loch fir litir ? lenited_palatalised = lp ; -- thunnaig fhuil loch fhir litir ? + lenited_plural = lpl ; -- thunnagan lochan fhir litrichean ? g = g ; } ; @@ -149,22 +144,29 @@ oper -- can always replace morphology with Katya's automated tool useN : LinN -> LinCN = \n -> n ** { s = table { - Indef Sg Nom => n.base ; + Indef Sg (Nom NoMutation) => n.base ; + Indef Sg (Nom Lenited) => n.lenited ; Indef Sg Gen => n.gen ; - Indef Sg Dat => fm n.palatalised n.base ; - Def Sg (CC Nom) => n.base ; + Indef Sg (Dat NoMutation) => fm n.palatalised n.base ; + Indef Sg (Dat Lenited) => fm n.lenited_palatalised n.lenited ; + Def Sg (CC (Nom NoMutation)) => n.base ; + Def Sg (CC (Nom Lenited)) => n.lenited ; Def Sg (CC Gen) => fm n.gen n.lenited_palatalised ; - Def Sg (CC Dat) => fm n.palatalised n.lenited ; + Def Sg (CC (Dat NoMutation)) => fm n.palatalised n.lenited ; + Def Sg (CC (Dat Lenited)) => fm n.lenited_palatalised n.lenited ; Def Sg Voc => fm n.lenited n.lenited_palatalised ; - Indef Pl Nom => fm n.pl n.palatalised ; + Indef Pl (Nom NoMutation) => fm n.pl n.palatalised ; + Indef Pl (Nom Lenited) => fm n.lenited_plural n.lenited_palatalised ; Indef Pl Gen => n.lenited ; - Indef Pl Dat => fm n.pl n.palatalised ; -- TODO: is this correct? - Def Pl (CC Nom) => n.pl ; + Indef Pl (Dat NoMutation) => fm n.pl n.palatalised ; -- TODO: is this correct? + Indef Pl (Dat Lenited) => fm n.lenited_plural n.lenited_palatalised ; -- TODO: ???? + Def Pl (CC (Nom NoMutation)) => n.pl ; + Def Pl (CC (Nom Lenited)) => n.lenited_plural ; Def Pl (CC Gen) => n.base ; - Def Pl (CC Dat) => n.pl ; + Def Pl (CC (Dat NoMutation)) => n.pl ; + Def Pl (CC (Dat Lenited)) => n.lenited_plural ; Def Pl Voc => glue n.lenited "a" ; - Dual => fm n.palatalised n.base ; -- TODO: is this correct? only for 1-syllable feminine nouns? - Lenited => n.lenited + Dual => fm n.palatalised n.base -- TODO: is this correct? only for 1-syllable feminine nouns? } } where { fm : Str -> Str -> Str = \fem,masc -> case n.g of { @@ -180,7 +182,7 @@ oper -- ** postmod/premod/… : Str -- if needed? determiners can put stuff after head but it only comes at NP } ; - linCN : LinCN -> Str = \cn -> cn.s ! Indef Sg Nom + linCN : LinCN -> Str = \cn -> cn.s ! Indef Sg NOM -- ++ cn.postmod -- If there is another field, use here ; @@ -190,10 +192,10 @@ tunnag_N : LinN = { base = "tunnag" ; gen = "tunnaige" ; pl = "tunnagan" ; + lenited_plural = "thunnagan" ; lenited = "thunnag" ; palatalised = "tunnaig" ; lenited_palatalised = "thunnaig" ; - g = Fem ; } ; @@ -202,7 +204,8 @@ boireannach_N : LinN = { pl,gen = "boireannaich" ; lenited = "bhoireannach" ; palatalised = "boireannaich" ; - lenited_palatalised = "bhoireannaich" ; + lenited_palatalised, + lenited_plural = "bhoireannaich" ; g = Masc ; } ; @@ -250,7 +253,7 @@ oper -- not this weird unintuitive Agr param mkPron : (subj,poss : Str) -> PronAgr -> LinPron = \subj,poss,agr -> { s = table { - Nom => subj ; + Nom _ => subj ; _ => "gam" -- TODO fix this } ; poss = poss ; @@ -278,12 +281,12 @@ oper -- does that param need to be kept in LinNP, and Prep need an inflection table from that param? -- or do we have an exhaustive list of prepositions that merge, and we can make that into a param and put on a LHS here? - s : NPCase => Str ; -- TODO: is lenition a separate dimension from case? + s : Case => Str ; -- TODO: is lenition a separate dimension from case? empty : Str ; -- to avoid metavariables a : Agr ; -- includes whether it's pron and whether it's definite. TODO: probably can make even leaner (wasn't a prio so far). } ; - linNP : LinNP -> Str = \np -> np.art ! (NPC Nom) ++ np.s ! (NPC Nom) ; + linNP : LinNP -> Str = \np -> np.art ! CC NOM ++ np.s ! CC NOM ; emptyNP : LinNP = { s,art = \\_ => [] ; @@ -312,9 +315,9 @@ oper getQuantForm : Number -> Gender -> Case -> QuantForm = \n,g,c -> case of { => QSg g c ; - => QSg g Nom ; --- ?????? + => QSg g NOM ; --- ?????? => QPl c ; - => QPl Nom --- ?????? + => QPl NOM --- ?????? } ; getArt : LinQuant -> Number -> Gender -> Case -> Str = \quant,n,g,c -> case c of { @@ -379,7 +382,7 @@ oper defArt : LinQuant = { s = table { - QSg Masc Nom => AN ; + QSg Masc (Nom _) => AN ; QSg Masc _ => AN_L ; QSg Fem Gen => NA ; QSg Fem _ => AN_L ; @@ -431,16 +434,17 @@ oper PrepForms : Type = {base, sg1, sg2, sg3M, sg3F, pl1, pl2, pl3 : Str} ; - H, N : Str ; + H, N, LENITION_DEBUG : Str ; H = pre {#vowel => "h" ++ BIND ; _ => []} ; N = pre {#vowel => "n-" ++ BIND ; _ => []} ; + LENITION_DEBUG = "^L" ; -- Only for debugging purposes—replace with empty string for production invarPrepForms : Str -> PrepForms = \str -> - {base=str ; sg1=str++"mo^L"; sg2=str++"do^L"; sg3M=str++"a^L"; + {base=str ; sg1=str++"mo" + LENITION_DEBUG; sg2=str++"do" + LENITION_DEBUG; sg3M=str++"a" + LENITION_DEBUG; sg3F=str++"a"++H; pl1=str++"àr"++N; pl2=str++"ùr"++N; pl3=str++AN} ; -- AN is defined as an allomorph to def art, TODO does the possessive add t- before vowel? - mkPrep : (replacesObjPron : Bool) + mkLinPrep : (replacesObjPron : Bool) -> (indef,defi : CoreCase) -> (objForms, possForms : PrepForms) -> LinPrep = @@ -475,51 +479,70 @@ oper } ; smartPrep : (objForms, possForms : PrepForms) -> LinPrep = - mkPrep True Dat Dat ; + mkLinPrep True (Dat Lenited) (Dat Lenited) ; + + mkPrep = overload { + mkPrep : (objForms, possForms : PrepForms) -> LinPrep = smartPrep ; + mkPrep : (objForms, possForms : PrepForms) -> Mutation -> LinPrep = + \obj,poss,mutation -> mkLinPrep True (Dat mutation) (Dat mutation) obj poss ; + mkPrep : (replacesObjPron : Bool) -> (indef,defi : CoreCase) + -> (objForms, possForms : PrepForms) -> LinPrep = mkLinPrep + } ; emptyPrep : LinPrep = { s = \\_ => [] ; poss = \\_ => [] ; - c2 = \\_ => Dat ; + c2 = \\_ => Dat Lenited ; replacesObjPron = False } ; aigPrep : LinPrep = - smartPrep + mkPrep {base="aig"; sg1="agam"; sg2="agad"; sg3M="aige"; sg3F="aice"; pl1="againn"; pl2="agaibh"; pl3="aca"} - {base="aig"; sg1="'gam^L"; sg2="'gad^L"; sg3M="'ga^L"; sg3F="'ga"++H; pl1="'gar"++N; pl2="'gur"++N; pl3="'gan"} ; + {base="aig"; sg1="'gam" + LENITION_DEBUG; sg2="'gad" + LENITION_DEBUG; sg3M="'ga" + LENITION_DEBUG; sg3F="'ga"++H; pl1="'gar"++N; pl2="'gur"++N; pl3="'gan"} + NoMutation ; + airPrep : LinPrep = - smartPrep + mkPrep {base="air"; sg1="orm"; sg2="ort"; sg3M="air"; sg3F="oirre"; pl1="oirrn"; pl2="oirbh"; pl3="orra"} - (invarPrepForms "air") ; + (invarPrepForms "air") + NoMutation ; annPrep : LinPrep = - smartPrep + mkPrep {base="ann"; sg1="annam"; sg2="annad"; sg3M="ann"; sg3F="innte"; pl1="annainn"; pl2="annaibh"; pl3="annta"} - {base="ann"; sg1="'nam^L"; sg2="'nad^L"; sg3M="'na^L"; sg3F="'na"++H; pl1="'nar"++N; pl2="'nur"++N; pl3="'nan"} ; + {base="ann"; sg1="'nam" + LENITION_DEBUG; sg2="'nad" + LENITION_DEBUG; sg3M="'na" + LENITION_DEBUG; sg3F="'na"++H; pl1="'nar"++N; pl2="'nur"++N; pl3="'nan"} + NoMutation ; àsPrep : LinPrep = - smartPrep + mkPrep {base="às"; sg1="asam"; sg2="asad"; sg3M="às"; sg3F="aiste"; pl1="asainn"; pl2="asaibh"; pl3="asda"} - (invarPrepForms "às") ; + (invarPrepForms "às") + NoMutation ; bhoPrep : LinPrep = - smartPrep + mkPrep {base="bho"; sg1="bhuam"; sg2="bhuat"; sg3M="bhuaithe"; sg3F="bhuaipe"; pl1="bhuainn"; pl2="buaibh"; pl3="bhuapa"} - {base="bho"; sg1="bhom^L"; sg2="bhod^L"; sg3M="bho a^L"; sg3F="bho a"++H; pl1="bhor"++N; pl2="bhu"++N; pl3="bhon"} ; + {base="bho"; sg1="bhom" + LENITION_DEBUG; sg2="bhod" + LENITION_DEBUG; sg3M="bho a" + LENITION_DEBUG; sg3F="bho a"++H; pl1="bhor"++N; pl2="bhu"++N; pl3="bhon"} + Lenited ; {- dePrep : LinPrep = …-} doPrep : LinPrep = - smartPrep + mkPrep {base="do"; sg1="dhomh"; sg2="dhut"; sg3M="dha"; sg3F="dhi"; pl1="dhuinn"; pl2="dhuibh"; pl3="dhiubh"} - {base="bho"; sg1="dom^L"; sg2="dod^L"; sg3M="dha^L"; sg3F="dha"++H; pl1="dor"++N; pl2="dhur"++N; pl3="don"} ; + {base="bho"; sg1="dom" + LENITION_DEBUG; sg2="dod" + LENITION_DEBUG; sg3M="dha" + LENITION_DEBUG; sg3F="dha"++H; pl1="dor"++N; pl2="dhur"++N; pl3="don"} + Lenited ; {- eadarPrep : LinPrep = …-} {- foPrep : LinPrep = …-} guPrep : LinPrep = - smartPrep + mkPrep + True {-replaces object pronoun-} + (Dat NoMutation) {-governs dative when indefinite, no mutation-} + Gen {-governs genitive when definite-} {base="gu"; sg1="ugam"; sg2="ugad"; sg3M="uige"; sg3F="uice"; pl1="ugainn"; pl2="ugaibh"; pl3="uca"} - {base="gu"; sg1="gum^L"; sg2="gud^L"; sg3M="gu a^L"; sg3F="gu a"++H; pl1="gar"++N; pl2="gur"++N; pl3="gun"} ; + {base="gu"; sg1="gum" + LENITION_DEBUG; sg2="gud" + LENITION_DEBUG; sg3M="gu a" + LENITION_DEBUG; sg3F="gu a"++H; pl1="gar"++N; pl2="gur"++N; pl3="gun"} + ; -------------------------------------------------------------------------------- -- Adjectives diff --git a/src/gaelic/SentenceGla.gf b/src/gaelic/SentenceGla.gf index c7a8634b..523eb632 100644 --- a/src/gaelic/SentenceGla.gf +++ b/src/gaelic/SentenceGla.gf @@ -10,7 +10,7 @@ lin -- : NP -> VP -> Cl PredVP np vp = { - subj = np.s ! NPC Nom ; + subj = linNP np ; -- article and CN are discontinuous in NP! linNP just picks nominative unmutated. pred = -- table {something with tense+polarity => vp.s ! VPres (nagr2vagr np.a) From e14833217ee0f13e78eea0ea62169ee9cc2f4dde Mon Sep 17 00:00:00 2001 From: Inari Listenmaa Date: Thu, 28 Aug 2025 15:47:14 +0200 Subject: [PATCH 14/15] TODO notes --- src/gaelic/ParadigmsGla.gf | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/gaelic/ParadigmsGla.gf b/src/gaelic/ParadigmsGla.gf index fe9ab02c..ba520dec 100644 --- a/src/gaelic/ParadigmsGla.gf +++ b/src/gaelic/ParadigmsGla.gf @@ -77,9 +77,11 @@ oper --2 Structural categories -- If prepositions take case, add that as argument to mkPrep - mkPrep : overload { - mkPrep : Str -> Prep ; - } ; + -- mkPrep : overload { + -- mkPrep : Str -> Prep ; + -- } ; + -- TODO: should export the whole set of morphologically complex prepositions here and not let users construct them alone + -- but should include funs like "override complement case for existing preps" mkConj : overload { mkConj : (and : Str) -> Conj ; -- (coffee) and (tea) From 9f21a3d103a9bd2a755148462dc46b5f5cf7f623 Mon Sep 17 00:00:00 2001 From: Inari Listenmaa Date: Thu, 28 Aug 2025 16:01:58 +0200 Subject: [PATCH 15/15] add the correct word for bird (tunnag is "duck") --- src/gaelic/LexiconGla.gf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gaelic/LexiconGla.gf b/src/gaelic/LexiconGla.gf index bd5e1e36..e775e8b1 100644 --- a/src/gaelic/LexiconGla.gf +++ b/src/gaelic/LexiconGla.gf @@ -31,7 +31,7 @@ lin beg_V2V = mkV2V (mkV "") ; lin belly_N = mkN "" ; lin big_A = mkA "" ; lin bike_N = mkN "" ;-} -lin bird_N = smartN "tunnag" Fem ;{- +lin bird_N = smartN "eun" "eòin" "eòin" Masc ;{- lin bite_V2 = mkV2 "" ; lin black_A = mkA "" ; lin blood_N = mkN "" ;