Расширение детерминаторов в 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 и исправите это в своей собственной ветке, вы можете сделать запрос на вытягивание из своей ветки и объединить его с восходящим потоком.

Другие вопросы по тегам