Files
gf-rgl/src/TEMPLATE/ResTMP.gf
Inari Listenmaa 6c71465939 Template for starting a new resource grammar (#441)
Also addressing this https://github.com/GrammaticalFramework/gf-rgl/issues/238 with a README that adds a suggested implementation order.
2023-08-25 11:35:54 +03:00

297 lines
9.5 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
resource ResTMP = 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
{-The param Number comes from common/ParamX, and has the values Sg and Pl.
* If your language doesn't have number, remove Number from all records.
* If your language has number with more than 2 values, define your own number in this module
(e.g. uncomment line 56) and use that Number instead of Number.
The param Gender is defined here, and has the values Gender1 and Gender2.
Currently it's only as a suggestion to be an inherent field in LinN.
* If your language doesn't have gender, remove Gender from all records.
* If your language has genders/noun classes, replace the placeholder Gender1 and Gender1
with the actual values of your language (there can be more than 2!), and uncomment
the g : Gender field from the definition of LinN.
If your nouns inflect in more things, like case, you can do one of the following
* Replace the placeholder cases on line 53 and make the table 2-dimensional, like this:
oper LinN : Type = {s : Number => Case => Str ; …} ;
* Make your own parameter that combines all the relevant features, like this:
param NForm = Whatever | You | Need | For | Noun | Inflection ;
oper LinN : Type = {s : NForm => Str ; …} ;
This can be a good idea, if your inflection table has some gaps, i.e. not all combinations are in use
See https://gist.github.com/inariksit/708ab9df2498e88bc63aedf5fc7be2f3#file-tables-gf-L48-L122 for explanation
-}
param
Gender = Gender1 | Gender2 ; -- Just a placeholder, see lines 34-39 above
Case = Case1 | Case2 | Case3 ; -- Just a placeholder, see lines 41-48 above
Number = Sg
| Pl
-- | Dual -- If your language has numbers other than Sg and Pl, add them to the parameter
;
Person = P1 | P2 | P3 ;
oper
LinN : Type = {
s :
-- Case => -- uncomment if your language has case
Number => -- variable number: table {Sg => "house" ; Pl => "houses"}
Str ;
-- g : Gender ; -- inherent gender/noun class, if your language has that
} ;
-- 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 -> LinN = \str -> {
s = table {
_ => str -- TODO: actual morphology
} ;
-- 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
-- ++ cn.postmod -- If there is another field, use here
;
---------------------------------------------
-- Numeral
-- Used in NumeralTMP
param
CardOrd = NCard | NOrd ;
oper
LinNumeral : Type = {s : CardOrd => Str ; n : Number} ;
mkNumeral : Str -> LinNumeral = \s -> {
s = table {
NCard => s ;
NOrd => s + "th"
} ;
n = Pl ; -- NB. probably singular for number 1
} ;
---------------------------------------------
-- Pronoun
{-The param Person comes from common/ParamX, and has the values P1, P2 and P3.
* If your language doesn't inflect in person, you may be able to remove Person from all records.
- However, consider if it's really never present? How about e.g. reflexive ("myself", "yourself" etc?)
* If your language is more fine-grained than {P1,P2,P3} x {Sg,Pl} (for instance gender and familiarity),
you can define your own param. We provide an example called Agr to take inspiration from—remove if
not needed, or use and refine if needed.
-}
param
-- These params are just for inspiration, not used anywhere currently.
Agr = SgP1 -- I
| SgP2 Politeness -- e.g. tū, tum, āp (Hindi) — note that the verb really inflects differently for all three!
| SgP3 Gender -- e.g. he, she (verb inflects the same, but distinction in reflexive: himself / herself)
| FillInTheRestYourself ;
Politeness = Intimate | Familiar | Polite ;
oper
LinPron : Type = {
s : Str ;
-- Alternative if your language has case and pronouns inflect in case (e.g. English I/me/my, she/her/hers)
-- s : Case => Str ;
n : Number ;
p : Person ;
-- Alternative to the `n` and `p` fields:
-- a : Agr -- sketched above, lines 97-103
} ;
mkPron : (_ : Str) -> Person -> Number -> LinPron = \str,per,num -> {
s = str ;
{- If there is case inflection, you need a table here
table {
_ => 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`.
-}
LinNP : Type = {
s : Str ;
-- Alternative: If anything inflects in case (nouns, pronouns), NP has to also inflect in case!
-- s : Case => Str ;
n : Number ;
p : Person ;
-- Alternative to the `n` and `p` fields:
-- a : Agr -- sketched on lines 97-101
} ;
linNP : LinNP -> Str = \np -> np.s ; -- Change when you change LinNP
emptyNP : LinNP = { -- Change when you change LinNP
s = [] ;
n = Sg ;
p = P3 ;
} ;
--------------------------------------------------------------------------------
-- 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 : 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 ;
Pl => these } ;
};
mkDet : Str -> Number -> LinDet = \str, num -> {
s = str ;
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.
-}
oper
LinPrep : Type = {
s : Str ;
-- If your language has cases, and different prepositions choose different cases.
-- c2 : Case ;
-- 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 ;
} ;
--------------------------------------------------------------------------------
-- 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
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 ;
}