2  Введение в lexd: морфология

2.1 Техническое введение

В данном разделе мы обсуждаем синтаксис программы lexd (Swanson и Howell 2021). Данная программа работает в связке

Это консольная программа, работающая на юниксоподобных системах. Чтобы избежать сложностей на начальных этапах курса, мы решили вначале познакомиться с синтаксисом lexd и попробовать описывать разные языковые явления, не затрудняя всех установкой и запуском у себя на компьютере. В связи с этим мы предлагаем выучить следующие четыре команды, которые будут работать на операционных системах Linux, основанных на Debian/Ubuntu, и в Google Colab:

  • скачиваем инструкции для установки lexd и hfst и дальнейшей работы с ними, записанные в простом текстовом файле, которые можно прочитать, если открыть ссылку из команды. Команда make запускает установку. Для того, чтобы это работало в Google Colab нужно перед командой нужно поставить восклицательный знак: !curl .... Знак доллара означает, что дальше следует команда командной строки, не надо его никуда копировать.
```{shell}
$ curl -s https://raw.githubusercontent.com/agricolamz/2025_morphological_transducers/refs/heads/main/task_tests/Makefile -o Makefile; make
```
  • дальше мы ожидаем, что вы создадите в коллабе или у себя на компьютере (если у вас Linux), файл с названием task.lexd. В Google Colab для этого достаточно вставить первой строкой кодового блока %%writefile task.lexd. Вот пример такого файла:
```{lexd}
PATTERNS
VerbRoot VerbInfl

LEXICON VerbRoot
sing<v>:sing
walk<v>:walk
dance<v>:dance

LEXICON VerbInfl
<pres>:
<pres><3><sg>:s
```
  • После того, как вы установили нужные программы и создали файл, можно посмотреть формы и разборы, которые генерируются трансдьюсером. Это можно сделать следующей командой (не забудьте поставить восклицательный знак перед make в Google Colab):
```{shell}
$ make forms

sing<v><pres>:sing
sing<v><pres><3><sg>:sings
walk<v><pres>:walk
walk<v><pres><3><sg>:walks
dance<v><pres>:dance
dance<v><pres><3><sg>:dances
```
  • Кроме того можно посмотреть анализ/генерацию конкретных форм (не забудьте поставить восклицательный знак перед make в Google Colab):
```{shell}
$ make analysis FORM="sings"

hfst-lookup: Warning: It is not possible to perform fast lookups with OpenFST, std arc, tropical semiring format automata.
Using HFST basic transducer format and performing slow lookups
> sings sing<v><pres><3><sg>    0,000000
```
```{shell}
$ make generation FORM="walk<v><pres><3><sg>"

hfst-lookup: Warning: It is not possible to perform fast lookups with OpenFST, std arc, tropical semiring format automata.
Using HFST basic transducer format and performing slow lookups
> walk<v><pres><3><sg>  walks   0,000000
```
  • В ходе курса мы будем разбирать разные лингвистические задачи. У каждой задачи есть номер и автоматический тест, который его проверяет. Чтобы запустить автоматическую проверку, следует ввести команду, где первое число – номер раздела, а второе число – номер задачи. Например, для того, чтобы проверить, работает ли проверка задания, попробуйте запустить следующую команду:
```{shell}
$ make test_02_01
```
  • Чтобы окончательно посмотреть все варианты, попробуйте изменить последнюю строчку файла task.lexd на <pres><3><sg>:S и снова перезапустить команду:
```{shell}
$ make test_02_01
```

2.2 Программа lexd

У программы lexd есть подробный туториал, так что данный раздел во многом опирается на него. Давайте подробнее рассмотрим lexd файл, который мы видели в прошлом разделе:

```{lexd}
1PATTERNS
VerbRoot VerbInfl   

2LEXICON VerbRoot
3sing<v>:sing
walk<v>:walk
dance<v>:dance

4LEXICON VerbInfl
5<pres>:
6<pres><3><sg>:s
```
1
Обязательный раздел PATTERNS, в котором каждая строка сообщает, как могут соединяться элементы из разных групп лексикона.
2
Группа лексикона, которая состоит из слова LEXICON и имени, под которым данная группа появляется в разделе PATTERNS
3
Наполнение группы. Первым идет разбор, а потом после двоеточия языковой материал. Морфологические теги принято записывать в треугольных скобках.
4
Вторая группа LEXICON и ее имя.
5
Пример нулевой морфемы.
6
Пример морфемы с несколькими морфологическими тегами.

Отметим, что можно создавать свои именнованные подразделы PATTERN, которые потом можно использовать в разделе PATTERNS, например:

```{lexd}
PATTERNS
VerbStem Tense PersonNumber

1PATTERN VerbStem
VerbRoot
VerbRoot Causative

LEXICON VerbRoot
...

LEXICON Causative
...

LEXICON Tense 
...

LEXICON PersonNumber
...
```
1
Именованный раздел PATTERN, который используется потом в разделе PATTERNS.

Таким образом, в каждом файле lexd должен быть раздел PATTERNS, содержащий в себе переменные, которые могут быть заданы либо в разделе PATTERN, либо в разделе LEXICON, либо их анонимные варианты (см. раздел Раздел 2.2.2). Также разные разделы можно переименовывать при помощи группы ALIAS (см. мануал). Комментарии можно оформлять при помощи хеша #.

Задание 02_02

Ниже представлен фрагмент ицаринской (даргинские, нахско-дагестанские) парадигмы из (Sumbatova и Mutalov 2003). Попробуйте смоделировать ее при помощи lexd. Для корректного моделирования формы sup.lat нужна морфонология, так что при моделировании используйте форму в скобках. При моделировании придется покривить душой: в формах ess и dir — инфикс классного показателя. Помните, что каждый морфологический тег следует обрамлять в отдельные треугольные скобки, например, ссика<n><ant><dir>:ссикасабал. Для ориентации в нашем lexd файле 26 строк.

форма козел медведь
abs кьаца ссика
erg кьацал ссикал
gen кьацала ссикала
com кьацаццилли ссикаццилли
sup.lat кьацай (< кьацайи) ссикай (< ссикайи)
sup.ess кьацайиб ссикайиб
sup.dir кьацайибал ссикайибал
sup.el кьацайир ссикайир
sub.lat кьацагъу ссикагъу
sub.ess кьацагъуб ссикагъуб
sub.dir кьацагъубал ссикагъубал
sub.el кьацагъур ссикагъур
ant.lat кьацаса ссикаса
ant.ess кьацасаб ссикасаб
ant.dir кьацасабал ссикасабал
ant.el кьацасар ссикасар
post.lat кьацагьа ссикагьа
post.ess кьацагьаб ссикагьаб
post.dir кьацагьабал ссикагьабал
post.el кьацагьар ссикагьар
in.lat кьацацци ссикацци
in.ess кьацацциб ссикацциб
in.dir кьацаццибал ссикаццибал
in.el кьацаццир ссикаццир

2.2.1 Операторы

Квантификация напоминает регулярные выражения:

  • ? — ноль или один раз
  • * — ноль и более раз 1
  • + — один и более раз
```{lexd}
PATTERNS
Root Negation?

LEXICON Root
...

LEXICON Negation
...
```
```{lexd}
PATTERNS
Root
Root Negation

LEXICON Root
...

LEXICON Negation
...
```
  • | — оператор или (можно с пробелами вокруг)
```{lexd}
PATTERNS
Root PastInflection|PresentInflection

LEXICON Root
...

LEXICON PastInflection
...

LEXICON PresentInflection
...
```
```{lexd}
PATTERNS
Root PastInflection
Root PresentInflection

LEXICON Root
...

LEXICON PastInflection
...

LEXICON PresentInflection
...
```
  • Кроме того есть операторы, названные в матералах lexd ситом, > и <:
```{lexd}
PATTERNS
VerbRoot > TAM > CLITICS

LEXICON Root
...

LEXICON TAM
...

LEXICON CLITICS
...
```
```{lexd}
PATTERNS
VerbRoot
VerbRoot TAM
VerbRoot TAM CLITICS

LEXICON Root
...

LEXICON TAM
...

LEXICON CLITICS
...
```

2.2.2 Анонимные разделы

Некоторые фрагменты аннотации можно вставлять прямо в раздел PATTERNS. Для этого используются квадртные скобки.

```{lexd}
PATTERNS
NounStem [<n>:] NounNumber

LEXICON NounStem
sock
ninja

LEXICON NounNumber
<sg>:
<pl>:s
```
```{lexd}
PATTERNS
NounStem NounNumber

LEXICON NounStem
sock<n>:sock
ninja<n>:ninja

LEXICON NounNumber
<sg>:
<pl>:s
```
```{lexd}
PATTERNS
NounStem NounTag NounNumber

1LEXICON NounTag
<n>:

LEXICON NounStem
sock
ninja

LEXICON NounNumber
<sg>:
<pl>:s
```
1
Новый раздел LEXICON.

В мануале это трюк назван Anonymous LEXICON, видимо, потому что предполагается, что мы таким образом избегаем создания дополнительного раздела LEXICON (см. развернутый пример 2).

По аналогии с анонимным разделом LEXICON есть анонимный раздел PATTERN. Для этого используются круглые скобки.

```{lexd}
PATTERNS
(VerbRoot Causative?) | AuxRoot Tense PersonNumber

LEXICON VerbRoot
...

LEXICON Causative
...

LEXICON AuxRoot
...

LEXICON Tense 
...

LEXICON PersonNumber
...
```
```{lexd}
PATTERNS
VerbStem | AuxRoot Tense PersonNumber

1PATTERN VerbStem
VerbRoot Causative?

LEXICON VerbRoot
...

LEXICON Causative
...

LEXICON AuxRoot
...

LEXICON Tense 
...

LEXICON PersonNumber
...
```
1
Новый раздел PATTERN.

2.2.3 Теги

На содержимое разделов LEXICON можно вешать теги. Это может быть полезно, например, для моделирования словоизменительных классов. Рассмотрим пример из русского языка (славянские, индоевропейские):

```{lexd}
PATTERNS
NounStem[hard] Inflection[hard]
NounStem[soft] Inflection[soft]

LEXICON NounStem
мама:мам[hard]
папа:пап[hard]
няня:нян[soft]
Таня:Тан[soft]

LEXICON Inflection
<nom><sg>:а[hard]
<nom><sg>:я[soft]
<gen><sg>:ы[hard]
<gen><sg>:и[soft]
```

То же самое можно записать при помощи одного тега, используя операцию отмены тега:

```{lexd}
PATTERNS
NounStem[hard] Inflection[hard]
NounStem[-hard] Inflection[-hard]

LEXICON NounStem
мама:мам[hard]
папа:пап[hard]
няня:нян
буря:бур

LEXICON Inflection
<nom><sg>:а[hard]
<nom><sg>:я
<gen><sg>:ы[hard]
<gen><sg>:и
```

Однако в русском языке можно найти аффиксы, которые присоединяются к обоим типам основ, в таком случае, придется усложнить наше описание:

```{lexd}
PATTERNS
NounStem[hard] Inflection[hard]
NounStem[soft] Inflection[soft]
NounStem Inflection[-hard,-soft]

LEXICON NounStem
мама:мам[hard]
папа:пап[hard]
няня:нян[soft]
Таня:Тан[soft]

LEXICON Inflection
<nom><sg>:а[hard]
<nom><sg>:я[soft]
<gen><sg>:ы[hard]
<gen><sg>:и[soft]
<pos>:ин
```

Авторы lexd добавили возможность взаимодействия тегов, чтобы не надо было писать одно и то же.

  • (A B)[x] = (A[x] B) | (A B[x])
```{lexd}
PATTERNS
(A B)[x]

LEXICON A
aaa[x]
bbb

LEXICON B
AAA[x]
BBB
```
aaaAAA
aaaBBB
bbbAAA
  • (A B)[-x] = A[-x] B[-x]
```{lexd}
PATTERNS
(A B)[-x]

LEXICON A
aaa[x]
bbb

LEXICON B
AAA[x]
BBB
```
bbbBBB
  • A[|[x,y]] = A[x] | A[y]
```{lexd}
PATTERNS
A[|[x,y]]

LEXICON A
aaa[x]
bbb[y]
ccc
```
aaa
bbb
  • A[^[x,y]] = A[x,-y] | A[-x,y]
```{lexd}
PATTERNS
A[^[x,y]]

LEXICON A
aaa[x]
bbb[y]
ccc[z]
ddd[x,y]
eee[x,z]
fff[y,z]
ggg
```
aaa
eee
bbb
fff 

^ — очень полезный оператор, который позволяет смоделировать согласование по признакам

(A B)[^[x,y]] = (A[x,-y] B[x,-y]) | (A[-x,y] B[-x, y]):

```{lexd}
PATTERNS
(A B)[^[x,y]]

LEXICON A
aaa[x]
bbb[y]
ccc

LEXICON B
AAA[x]
BBB[y]
CCC
```
aaaAAA
aaaCCC
cccAAA
cccBBB
bbbCCC
bbbBBB

Это позволяет смоделировать наш русский пример одной строчкой:

```{lexd}
PATTERNS
(NounStem Inflection)[^[hard,soft]]

LEXICON NounStem
мама:мам[hard]
папа:пап[hard]
няня:нян[soft]
Таня:Тан[soft]

LEXICON Inflection
<nom><sg>:а[hard]
<nom><sg>:я[soft]
<gen><sg>:ы[hard]
<gen><sg>:и[soft]
<pos>:ин
```
```{lexd}
PATTERNS
NounStem[hard] Inflection[hard]
NounStem[soft] Inflection[soft]
NounStem Inflection[-hard,-soft]

LEXICON NounStem
мама:мам[hard]
папа:пап[hard]
няня:нян[soft]
Таня:Тан[soft]

LEXICON Inflection
<nom><sg>:а[hard]
<nom><sg>:я[soft]
<gen><sg>:ы[hard]
<gen><sg>:и[soft]
<pos>:ин
```
Задание 02_03

Ниже представлен фрагмент финской (фино-угорские, уральские) парадигмы (Karlsson 2013), как видно, здесь слова двух словоизменительных типов. Попробуйте смоделировать представленную парадигму, используя теги.

glosses зал общежитие дверь зима
nom.sg sali hostelli ovi talvi
acc.sg sali hostelli ovi talvi
gen.sg salin hostellin oven talven
prt.sg salia hostellia ovea talvea
in.ess.sg salissa hostellissa ovessa talvessa
in.abl.sg salista hostellista ovesta talvesta
at.ess.sg salilla hostellilla ovella talvella
at.abl.sg salilta hostellilta ovelta talvelta
at.all.sg salille hostellille ovelle talvelle
frml.sg salina hostellina ovena talvena
trans.sg saliksi hostelliksi oveksi talveksi
priv.sg salitta hostellitta ovetta talvetta

2.2.4 Моделирование разрывных морфем: инфиксы, редупликация, семитские корни

В разеделе PATTERNS можно перечислять разные стороны единиц (или входное и выходное значение), записанных в LEXICON2. Это позволяет:

  • опускать либо глоссы, либо морфемы (полезно для моделирования редупликации);
  • иметь разный порядок глосс и морфем (но зачем?).

Вот пример моделирования дистрибутивных числительных (т. е. числительных со значением ‘по Х’) в зиловском андийском (андийские, нахско-дагестанские):

```{lexd}
PATTERNS
Numerals NumeralMarker
NumeralReduplication :Numerals Numerals NumeralMarker NumeralDistributiveMarker

LEXICON Numerals
чIе               # числительное 2
лъоб              # числительное 3
ойлIи             # числительное 6

LEXICON NumeralMarker
<num>:гу

LEXICON NumeralDistributiveMarker
<distr>:

LEXICON NumeralReduplication
<rdp>:
```
чIе<num>:чIегу
лъоб<num>:лъобгу
ойлIи<num>:ойлIигу
<rdp>чIе<num><distr>:чIечIегу
<rdp>лъоб<num><distr>:лъоблъобгу
<rdp>ойлIи<num><distr>:ойлIиойлIигу

Кроме того для моделирования разрывных морфем, вводится номер в круглых скобках, а элементы морфемы перечисляются через пробел. Вот пример, из иврита (симитские, афразийские):

```{lexd}
PATTERNS
C(1) V(1) C(2) :V(2) C(3) V(2):

LEXICON C(3)
sh m r          # соблюдать, защищать
y sh v          # садиться

LEXICON V(2)
:a <v><p3><sg>:a
:o <v><pprs>:e
```
shmr<v><p3><sg>:shamar
shmr<v><pprs>:shomer
yshb<v><p3><sg>:yashab
yshb<v><pprs>:yosheb
Задание 02_04

Ниже даны количественные, кратные (со значение ‘Х раз’) и дистрибутивные (со значение ‘по Х’) числительные адыгейского языка (абхазо-адыгские) (Рогава и Керашева 1966: 79, 81). Смоделируйте перечисленные формы:

значение лемма количественные
<card>
кратные
<adv>
дистрибутивные
<distr>
1 зы зы зэ зырыз
3 щы щы щэ щырыщ
4 плIы плIы плIэ плIырыплI
5 тфы тфы тфэ тфырытф
6 хы хы хэ хырых
10 пшIы пшIы пшIэ пшIырыпшI

2.2.5 Регулярные выражения

В разделе LEXICON допускаются регулярные выражения, для этого их нужно обромлять косыми чертами /:

  • группировка при помощи скобок ()
  • квантификация при помощи ?, *, и +. Объект квантификации должен быть обрамлен круглыми скобками.
  • логическое ‘или’ |
  • группы символов при помощи квадратных скобок []
  • промежутки символов [a-z]
```{lexd}
PATTERNS
SomeLexicon

LEXICON SomeLexicon
/x(y|zz)?[n-p]/
```
xyn
xyo
xyp
xzzn
xzzo
xzzp
xn
xo
xp

Это позволяет добавлять разбор неизвестных единиц в lexd. Важно отметить, что добавление некоторых типов регулярных выражение делает циклический трансдьюсер, поэтому результат такого трансдьюссера можно посмотреть только при помощи команд make analysis FORM="..." или make generation FORM="...".

```{lexd}
PATTERNS
Stem Affix

LEXICON Stem
стол
дом
/([а-я])*/

LEXICON Affix
<nom><sg>:
<gen><sg>:а
<acc><sg>:
<dat><sg>:у
<ins><sg>:ом
<loc><sg>:е
```
```{shell}
$ make analysis FORM="комом"

hfst-lookup: Warning: It is not possible to perform fast lookups with OpenFST, std arc, tropical semiring format automata.
Using HFST basic transducer format and performing slow lookups
> комом ком<ins><sg>    0,000000
комом   комом<acc><sg>  0,000000
комом   комом<nom><sg>  0,000000
```

  1. Мы какое-то время думали, зачем это может быть нужно и придумали только странные сценарии типа пра-пра-пра-пра-бабушка. Но вообще это порождает циклы, от которых одни проблемы.↩︎

  2. К сожалению, нельзя делать аналогичное для единиц из разделов PATTERN.↩︎