Расширение детерминаторов в GF
Ранее я задавал вопрос о расширении записи which_RP и изменении относительного предложения «that» на «which» в этом вопросе здесь .
Недавно я начал работать над итальянским языком, и всякий раз, когда я использую функцию someSg_Det или somePl_Det, я получаю соответственно следующий результат.
qualche albero
qualche alberi
Из моих знаний итальянского языка я знал, что для существительных-одиночек
qualche albero
правильно, но для существительных во множественном числе мы должны использовать
alcune
или же
alcuni
в зависимости от пола существительного. Таким образом, я попытался расширить функцию somePl_Det до somePlM_Det и somePlF_Det, как показано ниже:
somePlM_Det : Str -> Det =
\str ->
somePl_Det ** {s = table {_ => "alcuni"}};
somePlF_Det : Str -> Det =
\str ->
somePl_Det ** {s = table {_ => "alcune"}};
Но компилятор GF продолжает сообщать об этой ошибке:
Happend in operation somePlM_Det
type of "alcuni"
Expected: DiffIta.Case => Str;
inferred: Str;
Happend in operation somePlF_Det
type of "alcune"
Expected: DiffIta.Case => Str;
inferred: Str;
В расширении отсутствует переменная DiffIta.Case . После поиска я нашел параметр Case, расположенный в файле DiffRomance.gf. Несмотря на то, что я нашел DiffRomance.Case, я все еще не могу расширить эту функцию.
Не могли бы вы объяснить использование DiffRomance.Case и как правильно расширить эту функцию. Спасибо ~
1 ответ
Просто чтобы прояснить для всех, кто читает этот ответ, а не предыдущий:
someWord ** {s = "some string"}
- это взлом, и нет никаких гарантий, что он будет работать, когда RGL обновится.
Я предлагал этот взлом, потому что он может быть полезен: иногда RGL не выводит именно то, что вы хотите, но на самом деле это не ошибка, которую следует исправлять в апстриме. Затем вы можете переопределить некоторые определения RGL локально в грамматике вашего приложения, но вы должны знать о потенциальной нестабильности.
Теперь к ответу на этот вопрос.
Lincat из итальянского RGL
Вы пытаетесь сделать это:
somePlM_Det : Str -> Det =
\str ->
somePl_Det ** {s = table {_ => "alcuni"}};
Вы пытаетесь вставить
table {_ => "alcuni"}
в поле Det на итальянском языке. Давайте посмотрим , здесь то , что фактическая lincat является:
Det = {
s : Gender => Case => Str ;
n : Number ;
s2 : Str ; -- -ci
sp : Gender => Case => Str ; -- substantival: mien, mienne
isNeg : Bool -- negative element, e.g. aucun
} ;
Обратите внимание на
s
поле типа
Gender => Case => Str
. Это два вложенных списка, тогда как вы пытались дать ему только один список.
Это сработает, но не имеет смысла:
somePlF_Det : Str -> Det =
\str ->
somePl_Det ** {s = table {_ => table {_ => "alcune"}}};
Что в этом плохого? Две вещи объяснены ниже.
имеет переменную
Gender
- не присуще
В RGL, в тех языках, в которых есть род или другой класс существительных, дизайн обычно выглядит следующим образом.
Существительные (и по наследству s и
NP
у) иметь врожденный пол. Это означает, что их линкаты выглядят так:
lincat
N = {s : Whatever => Str ; g : Gender} ;
Напротив, все модификаторы и квантификаторы существительных (и т. Д.) Имеют переменный род. Итак, их линкаты выглядят так:
lincat
Det, Quant, A, AP, RS ... = {s : Gender => Whatever => Str} ;
Пол находится в левой части таблицы перегиба, что означает, что вывод модификатора / квантификатора зависит от пола его возможной главы. Существительное (или CN, или NP) будет головой, и мы будем использовать неотъемлемый род головы, чтобы выбрать правильный пол из модификатора / квантификатора. Код GF выглядит так:
-- In the abstract syntax
fun
Modify : Modifier -> Head -> Head ;
-- In the concrete syntax (different file)
lin
Modify mod head = {
s = \\x => mod.s ! head.g ! x ++ head.s ! x
} ;
Мы используем
head.g
выбрать строку из
mod.s
. Переменная
x
может представлять любые другие особенности перегиба, такие как регистр или число --- не имеет значения для этого примера.
Так что нет смысла определять
somePlM_Det
и
somePlF_Det
. Мы хотим применить только один к любому, а
CN
решает, будет ли
Det
выведет
alcune
или же
alcuni
.
Что делать с
Case
Другой неправильный поступок - просто заменить каждую ветвь таблицы перегибов одной строкой «alcune» или «alcuni». Эти случаи (и пол) на самом деле что-то делают. Давайте посмотрим на таблицу какого-нибудь другого Det, не нуждающегося в исправлении.
Я в каталоге
gf-rgl/src/italian
и открываю оболочку GF. (Команды с префиксом
>
выполняются внутри оболочки GF. Я использую флаги
-retain -no-pmcfg
потому что итальянская гимнастическая гитара настолько медленная, что делает ее быстрее.)
$ gf
> i -retain -no-pmcfg LangIta.gf
> cc -unqual -table many_Det
s . Masc => Nom => molti
s . Masc => Acc => molti
s . Masc => CPrep P_di => di molti
s . Masc => CPrep P_a => a molti
s . Masc => CPrep P_da => da molti
s . Masc => CPrep P_in => in molti
s . Masc => CPrep P_su => su molti
s . Masc => CPrep P_con => con molti
s . Fem => Nom => molte
s . Fem => Acc => molte
s . Fem => CPrep P_di => di molte
s . Fem => CPrep P_a => a molte
s . Fem => CPrep P_da => da molte
s . Fem => CPrep P_in => in molte
s . Fem => CPrep P_su => su molte
s . Fem => CPrep P_con => con molte
Все эти предлоги входят в таблицу перегибов! Если вам интересно, почему, это потому, что эти предлоги сливаются со статьями. Во-первых, примеры, в которых они не сливаются:
> cc -one PrepNP in_Prep (DetCN many_Det (UseN house_N))
in molte case
> cc -one PrepNP with_Prep (DetCN many_Det (UseN cat_N))
con molti gatti
И с ними они действительно сливаются.
> cc -one PrepNP in_Prep (DetCN (DetQuant DefArt NumPl) (UseN house_N))
nelle case -- not "in le case"
> cc -one PrepNP with_Prep (DetCN (DetQuant DefArt NumPl) (UseN cat_N))
coi gatti -- not "con i gatti"
Вот почему нам нужен падеж в таблице перегибов. Если бы я заменил то, что вы написали, то получил бы следующее:
> cc -one PrepNP with_Prep (DetCN somePl_Det (UseN cat_N))
alcuni gatti -- "with" is missing!
> cc -one PrepNP in_Prep (DetCN somePl_Det (UseN house_N))
alcuni case -- "in" is missing, and no gender agreement!
Как на самом деле исправить
somePl_Det
Это похоже на то, что нужно исправить в апстриме, а не взламывать индивидуально для каждой локальной грамматики.
Замените строку 86 в StructuralIta следующим образом:
somePl_Det = {s,sp = \\g,c => prepCase c ++ genForms "alcuni" "alcune" ! g ; n = Pl ; s2 = [] ; isNeg = False} ;
Перекомпилируйте свой RGL, и с этого момента вы должны получить следующий результат:
> cc -one PrepNP in_Prep (DetCN somePl_Det (UseN house_N))
in alcune case
> cc -one PrepNP with_Prep (DetCN somePl_Det (UseN cat_N))
con alcuni gatti
Если вы сделаете форк репозитория gf-rgl и исправите это в своей собственной ветке, вы можете сделать запрос на вытягивание из своей ветки и объединить его с восходящим потоком.