Апертиум, как се създава нова езикова двойка

From Apertium
Revision as of 05:26, 26 November 2010 by Gradinarovo (talk | contribs)
Jump to navigation Jump to search

Апертиум, как се създава нова езикова двойка

Този документ има за цел да обясни как се създава нова езикова двойка в Апертиум системата за машинен превод от началото до края.

Не е необходимо никакво знание по лингвистика или по машинен превод над нивото на различаване на съществителни имена от глаголи (представки и други)

Въведение

Както може би вече сте се досетили, Апертиум е система за машинен превод. Всъщност, казано по-точно това е платформа за преводи. Разполага с машина и инструменти, които ви позволяват да създавате ваши собствени системи за превод. Единственото нещо, което трябва да направите е да запишете данните. Основно те се състоят от три речника и няколко правила за преподреждане на думите и други граматични трансформации.

За по конкретна информация как точно работи системата, има някои доста добри ръководства на уеб сайта на проекта apertium.sourceforge.net.

Какво ще ви е необходимо

  • lttoolbox (>= 3.0.0)
  • libxml utils (xmllint etc.)
  • apertium (>= 3.0.0)
  • текстов редактор (или ако предпочитате специализиран XML редактор)

Този документ няма да описва как да инсталирате тези пакети. За повече информация за това прочетете секцията с документацията на уеб сайта на Апертиум.

От какво се състои езиковата двойка?

Системата за машинен превод Апертиум е от повърхностно-трансферен тип, което ще рече, че работи с речници и повърхностни правила за позициониране на думите. Повърхностнното позициониране на думите се различава от "пълното позициониране" с това, че не прави цялостно синтактично парсиране. По принцип правилата са операции върху групи от лексически раздели, и не са операции върху дървовидни структури. Основно съществуват три основни речника:

  1. Морфологичния речник за език ХХ: той съдържа правилата за това как се спрягат думите в език ХХ. В нашия пример този речник ще се нарича: apertium-sh-en.sh.dix
  2. Морфологичния речник за език УУ: той съдържа правилата за това как се спрягат думите в език УУ. В нашия пример този речник ще се нарича: apertium-sh-en.en.dix
  3. Двуезичен речник: съдържа съответстия между думи и символи на двата езика. В нашия пример този речник ще се нарича: apertium-sh-en.sh-en.dix

В двойката за превод и двата езика могат да бъдат или източник или приемник на превода, това са относителни тернини.

Също така има два файла за правила на трансфера. Това са правилата, които управляват как се пренареждат думите в изреченията, пр. chat noir -> cat black -> black cat. Управляват се и родовете, числата и т.н. Правилата могат да бъдат използвани и да се смъкват или изтриват лексически елементи, както ще бъде описано по-късно. Тези файлове са:

  • правила за трансфер на език ХХ към УУ: този файл съдържа правила относно промяната от език ХХ към УУ. В нашия пример това ще бъде: apertium-sh-en.trules-sh-en.xml
  • правила за трансфер на език УУ към ХХ: този файл съдържа правила относно промяната на език УУ към ХХ. В нашия пример това ще бъде: apertium-sh-en.trules-en-sh.xml

Много от езиковите двойки, които са налични в момента имат и друг файлове, но ние няма да ги разясняваме тук. Горните файлове са тези, които са необходими за изграждането на една функционална система.

Езикова двойка

Както може да се предположи от имената на файловете, това ръководство ще използва за обяснение на създаването на основната система примери от сърбо-хърватски на английски. Това не е идеалната двойка, тъй като системата работи по-добре с по-близки езици, но това няма да бъде рпоблем за простите примери, с които ще се сблъскаме тук.

Кратка бележка за термините

Преди да продължим има няколко термини, които трябва да бъдат разяснени.

Първият е лема. Лема е цитирането на дума. Това представлява думата, без никаква граматическа информация. На пример, лемата на думата котки е котка. За английските съществителни това обикновенно е единственото число на въпросната дума. За глаголи, лемата е основната форма. Лемата на глагола бях е съм.

Вторият е символа. В контекста на Апертиум системата, символа означава граматически етикет. Думата котки е множествено число, следователно тя има символа за съществително и символа за многжествено число. На входа и изхода на модулите на Апертиум, горните обикновено се подавата между ъглови скоби, както следва:

  • <n>; за съществителни
  • <pl>; за множествено число

Други примери за символи са <sg>; единствено число, <p1> първо лице, <pri> сегашно изявително наклонение и др. Когато са записани в квадратни скобки символите могат същото така да се приемат като тагове. Важно е да се отбележи, че в много от съществуващите езикови двойки дефинициите на символите са думи, образувани от началните букви на други думи на Каталонски език. На пример, vbhaver - от vb (глагол) и haver ("да имам" на каталонски). Символите са дефинирани в <sdef> тагове и се използват с <s> тагове.

Третата дума е парадигма. В контекста на Апертиум системата, парадигмата се отнася примерно как се спряга цяла група от думи. В морфологичния речник, лемите (виж по-горе) се свързват с парадигмите, което ни дава възможност да опишем как всяка лема може да бъде спрегната без да се налага да описваме всички наставки.

Примерно, ако искаме да съхраним две прилагателни happy и lazy, вместо да запазваме две еднакви наствки:

  • happy, happ (y, ier, iest)
  • lazy, laz (y, ier, iest)

Можем просто да съхраним едната и после да кажем, че "lazy, се спряга като happy", или "shy се спряга като happy","naughty се спряга като happy", "friendly се спряга като happy" и така нататък. В този пример, happy ще е парадигмата, модела за това как всички останали се спрягат. Точното описание на как точно се дефинира това ще бъде обяснено скоро. Парадигмите се дефинират в <pardef> тагове и се използват в <par> тагове.

Начало

Многоезини речници

Нека да започнем като направим нашия първи езиков речник. Речника представлява XML файл. Пуснете си вашия текстов редактор и напишете следното:

<?xml version="1.0" encoding="UTF-8"?>
<dictionary>

</dictionary>

Така, файла дефинира за сега, че искаме да направим речник. За да бъде полезен този файл трябва да добавим още няколко реда, първия от които е азбука. Тя дефинира поредицата от букви, които мога да се използват в речника за Сърбо-Хърватски. Ще изглежда по следния начин и ще съдържа всички букви от Сърбо-Хърватската азбука:

<alphabet>ABCČĆDDžĐEFGHIJKLLjMNNjOPRSŠTUVZŽabcčćddžđefghijklljmnnjoprsštuvzž</alphabet>

Поставете азбуката под тага <dictionary>.

След това трябва да дефинираме някои символи. Да започнем с нещо по-елементарно, съществително (n) в единствено число (pl) и множествено число (pl).

<sdefs>
   <sdef n="n"/>
   <sdef n="sg"/>
   <sdef n="pl"/>
</sdefs>

Символните имена не трябва да бъдат толкова кратки, всъщност те биха могли дори да бъдат написани пълно, но тъй като ще се налага да ги пишем често, има логика да използваме съкращения.

За нещастие, не е толкова лесно, съществителните в Сърбо-Хърватския се спрягат не само по число, а също така и по род и наклонение. Обаче, за този пример ще приемем, че съществителното е в мъжки род и в именителен падеж ( цялостен пример може да бъде намерен в края на този документ )

Следва да дефинираме секция за парадигмите,

<pardefs>

</pardefs>

и секция за речника:

<section id="main" type="standard">

</section>

Има два вида секции, първия е стандартна секция, която съдържа думи, енклитика и други. Втория вид е неусловна секция, която най-често съдържа препинателни знаци и други. Тук нямаме такава неусловна секция, но тя ще бъде описана по-късно.

Така, файла ни трябва да изглежда по следния начин:

<?xml version="1.0" encoding="UTF-8"?>
<dictionary>
   <sdefs>
     <sdef n="n"/>
     <sdef n="sg"/>
     <sdef n="pl"/>
   </sdefs>
   <pardefs>

   </pardefs>
   <section id="main" type="standard">

   </section>
</dictionary>

Сега имаме структурата, можем да започнем с добавянето на съществително. За пример ще използваме "gramofon", който означава "грамофон" или "устройство, което свири плочи".

Първото нещо, което трябва да направим, тъй като нямаме предишни парадигми е да дефинираме парадигма.

Запомнете, че приемаме мъжки род и именителен падеж. Единственото число на съществителното е "gramofon", и множественото число е "gramofoni". Така:

<pardef n="gramofon__n">
   <e>
     <p>
       <l/>
       <r><s n="n"/><s n="sg"/></r>
     </p>
   </e>
   <e>
     <p>
       <l>i</l>
       <r><s n="n"/><s n="pl"/></r>
     </p>
   </e>
</pardef>

Забележка: '<l/>' (еквивалент на <l></l>) означава, че няма допълнителен материял да бъде добавян в основата на думата в единствено число.

Това може да изглежда като доста подробен начин за описването му, но има причини за това и скоро се свиква с него. Вие сигурно се чудите какво означават <e>,

, <l> и <r>. Така,

  • e - запис.
  • p - двойка.
  • l - ляво.
  • r - дясно.

Защо ляво и дясно? Ами морфологичните речници по-късно ще бъдат компилирани в крайни автомати. Компилирането им отляво надясно създава анализ от думи и от дясно наляво думи от анализи. Например:

* gramofoni (отляво надясно) gramofon<n><pl> (анализ)
* gramofon<n><pl> (отдясно наляво) gramofoni (генерация)

Сега дефинирахме парадигма, трябва да я свържем с нейната лема, gramofon. Поставяме я в секцията, която дефинирахме.ed.

Записа, който ще сложим в </dictionary>

Сега е необходимо да добавим запис за превод между двете думи. Нещо като:

<e><p><l>gramofon<s n="n"/></l><r>gramophone<s n="n"/></r></p></e>

Тъй като има много такива записи, те се пишат обикновено на един и същи ред за да се улесни четенето на файла. Отново с 'l' и 'r'? Компилираме го от ляво надясно за да се създаде сърбо-хърватски > английски речник, и отдясно наляво за създаването на английски > сърбо-хърватски речник.

И така, когато сме готови стартираме следните команди:

$ lt-comp lr apertium-sh-en.sh.dix sh-en.automorf.bin
$ lt-comp rl apertium-sh-en.en.dix sh-en.autogen.bin

$ lt-comp lr apertium-sh-en.en.dix en-sh.automorf.bin
$ lt-comp rl apertium-sh-en.sh.dix en-sh.autogen.bin

$ lt-comp lr apertium-sh-en.sh-en.dix sh-en.autobil.bin
$ lt-comp rl apertium-sh-en.sh-en.dix en-sh.autobil.bin

Така се генерират морфологичните анализатори (automorf), морфологичните генератори (autogen) и се проверяват думите (autobil), думата bil означава двуезичен.

Правила за трансфер

Така, имаме два морфологични речника и двуезичен речник. Това от което се нуждаем сега е правило за трансфер за съществителни. Оравилата за трансфер имат собствени DTD фаилове(transfer.dtd), които могат да бъдат открити в пакета Apertium. Ако трябва да създадете ново правило е желателно да погледнете във файловете с правила на други езикови двойки първо. Много правила могат да бъдат използвани многократно от различните езици. Например правилото описано по-долу ще е полезно за всеки език, който използва падежи за определяне на личните местоимения(аз, ти, той, ние, вие, те) и те могат да се изпускат.

Започнете като всички други с основна структура:

<?xml version="1.0" encoding="UTF-8"?>
<transfer>

</transfer>

Тъй като в момента игнорираме падежа трябва само да направим правило, което да взема граматичните символи на входа и да ги извежда отново.

Първо трябва да се дефинират категории и атрибути. Категориите и атрибутите позволяват да групираме граматични символи. Категориите позволяват да групуираме символи за съвпадение, например 'n.*' за всички съществителни(nouns). Атрибутите позволяват да се групират символи, от които може да се избира. Например 'sg' и 'pl' могат да се групират в атрибута число (number).

Нека да добавим необходимите раздели:

<section-def-cats>

</section-def-cats>
<section-def-attrs>

</section-def-attrs>

Тъй като само спрягаме съществителните в единствено и множествено число трябва да добавим категория за съществителни и атрибут за число. Нещо като следващото ще бъде достатъчно:

В section-def-cats се добавя:

<def-cat n="nom">
   <cat-item tags="n.*"/>
</def-cat>

Това прихваща всички съществителни (леми след които има <n> и след това каквото и да е друг) и се отнася към тях като с "nom"(ще демонстрираме използването му по-късно).

В секцията section section-def-attrs се добавя:

<def-attr n="nbr">
   <attr-item tags="sg"/>
   <attr-item tags="pl"/>
</def-attr>

и след това

<def-attr n="a_nom">
   <attr-item tags="n"/>
</def-attr>

Първото дефинира атрибута nbr(номер), който може да бъде и в единствено(sg) и в множествено число(pl).

Второто дефинира атрибута a_nom (атрибут съществително).

Следва да добавим секция за глобални променливи:

<section-def-vars>

</section-def-vars>

Тези променливи се използват за съхранение или трансфер на атрибути между правила. Необходимо ни е само едно за сега:

<def-var n="number"/>

Накрая добавяме правило, което да приеме съществителното и да го генерира в правилната форма. Ще ни трябва секция с правила...

<section-rules>

</section-rules>

Като сменяме стъпката от предишния пример ще покажем правилото, след това ще го разгледаме, отколкото наобратно.

<rule>
   <pattern>
     <pattern-item n="nom"/>
   </pattern>
   <action>
     <out>
       <lu>
         <clip pos="1" side="tl" part="lem"/>
         <clip pos="1" side="tl" part="a_nom"/>
         <clip pos="1" side="tl" part="nbr"/>
       </lu>
     </out>
   </action>
</rule>

Първия таг е очевиден, той дефинира правило. Втория таг основно казва: "приложи правилото, ако примера е намерен". В този случай примера се състои от едно съществително (дефинирано от категорията nom). Забележете, че примерите се съпоставят по правилото на по-дългото съвпадение е първо. Така че ако имате три правила, пърото прихваща "<prn><vblex><n>", второто прихваща "<prn><vblex>", третото прихваща "<n>", примера който ще съвпадне и правилото, което ще се изпулни е първото.

За всеки пример има свързано действие, което генерира определен изход. Изхода е лексическа мярка (lu).

Клип тага позволява на потребителя да избира и манипулира атрибути и части на лексическия параграф на входния език (side="sl"), или изходния език (side="tl").

Нека да го компилираме и да го тестваме. Правилата за трансфер се компилират с:

$ apertium-preprocess-transfer apertium-sh-en.trules-sh-en.xml trules-sh-en.bin

Файла trules-sh-en.bin ще бъде създаден.

Сега вече сме готови да тестваме нашата система за машинен превод. Липсва една важна част, част на говора (PoS) тагер, но той ще бъде описан скоро. Междувременно можем да тестваме по следния начин:

Първо да анализираме думата gramofoni:

$ echo "gramofoni" | lt-proc sh-en.automorf.bin 
^gramofon/gramofon<n><pl>$

Обикновенно тук тагера PoS ще избере правилната версия на базата на част от речта, но тъй като нямаме PoS тагер все още можем да използваме следния елементарен gawk скрипт (благодарение на Segio), който просто ще ни даде първия елемент, който е получен.

$ echo "gramofoni" | lt-proc sh-en.automorf.bin | \
  gawk 'BEGIN{RS="$"; FS="/";}{nf=split($1,COMPONENTS,"^"); for(i = 1; i<nf; i++) printf COMPONENTS[i]; if($2 != "") printf("^%s$",$2);}' | \
^gramofon<n><pl>$

Сега нека да обработим резултата с правило за трансфер:

$ echo "gramofoni" | lt-proc sh-en.automorf.bin | \
  gawk 'BEGIN{RS="$"; FS="/";}{nf=split($1,COMPONENTS,"^"); for(i = 1; i<nf; i++) printf COMPONENTS[i]; if($2 != "") printf("^%s$",$2);}' | \
  apertium-transfer apertium-sh-en.trules-sh-en.xml trules-sh-en.bin sh-en.autobil.bin

Това ще ни даде:

^gramophone<n><pl>$^@
  • 'gramophone' е изходният език (side="tl") лема (lem) на позиция 1 (pos="1").
  • '<n>' е a_nom на изходния език на позиция 1.
  • '<pl>' е атрибута за число (nbr) на изходния език на позиция 1.

Опитайте се да коментирате едно от тези клипови твърдения, да компилирате отново и да видите какво се случва.

Така, сега имаме изхода от прехвърлянето, единственото което остава е да се генерират спрегнатите форми на изходния език. За тази цел ние използваме lt-proc, но в режим на генериране (-g), не на анализ.

$ echo "gramofoni" | lt-proc sh-en.automorf.bin | \
  gawk 'BEGIN{RS="$"; FS="/";}{nf=split($1,COMPONENTS,"^"); for(i = 1; i<nf; i++) printf COMPONENTS[i]; if($2 != "") printf("^%s$",$2);}' | \
  apertium-transfer apertium-sh-en.trules-sh-en.xml trules-sh-en.bin sh-en.autobil.bin | \
  lt-proc -g sh-en.autogen.bin

gramophones\@

И c'est ca. Сега имате система за машинен превод, която превежда съществително от сърбо-хърватски в съществително на английски. Очевидно това не е много полезно, но скоро ще се спрем на по-сложните неща. А, и не се тревожете за символа '@', ще обясня това скоро.

Помислете за няколко други думи, които се спрягат по същия начин като грамофон. Какво ще кажете за добавянето на тези. Не трябва да добавяме никакви парадигми, само записите в главната секция на едноезичните и двуезичните речници.

Да вкараме глаголите в играта

Добре, имаме система, която превежда съществителни, но това е доста безполезно, ние искаме също така да превеждаме глаголи и дори цели изречения! Какво ще кажете да започнем с глагола, за да видите. В сърбо-хърватския това е videti. Сърбо-хърватският е език с нулев подлог, това означава, че обикновено не използва лични местоимения преди спрегнатата форма на глагола. При английския не е така. Например: Аз виждам на английски би било преведено като vidim на сърбо-хърватски.

  • Vidim
  • виждам<p1><sg>
  • Аз виждам

Забележка: <p1> обозначава първо лице

Това ще бъде важно когато трябва да напишем правилото за прехвърляне на глаголи. Други примери за нулев подлог включват: испански, румънски и полски. Също така има и последицата, че докато ние само се нуждаем да добавим глагола в сърбо-хърватския морфологичен речник, трябва да добавим както глагола, така и личните местоимения в английският морфологичен речник. Ще минем и през двете.

Другите форми на глагола videti са: vidis, vidi, vidimo, vidite, and vide; които съответстват на: ти виждаш (единствено), той вижда, ние виждаме, вие виждате (множествено число) и те виждат.

Има две форми на ти виждаш(you see), едната е в множествено и формално единствено число (vidite) и другата е в единствено неформално число (vidis).

Ще се опитаме да преведем изречението: "Vidim gramofoni" в "Виждам грамофони". Всъщност, само ще добавим достатъчно информация да направим превода и ще оставим попълването на парадигмите (добавянето на другото спрежение на глагола) като задача на читателя.

Проницателният читател вече ще е разбрал, че не можем просто да преведем vidim gramofoni, защото не е граматично правилно изречение на сърбо-хърватски. Правилното изречение би било vidim gramofone, като съществителното е във винителен падеж. Ще трябва също да добавим тази форма, няма нужда обаче за сега да се добавя информация за падежа , просто го добавяме като друга опция за множествено число. Така че, просто копирайте 'e' за 'i' и променете 'i' на 'e'.

Първото нещо, което трябва да направим е да добавим повече символи. Първо трябва да добавим символ за 'глагол', което ще наречем "vblex" (това означава лексикален глагол, обратно на модални глаголи и фруги типове). Глаголите имат 'лице' и 'време' заедно с число, така че нека да добавим също така няколко от тези. Трябва да преведем "Аз виждам", така че за лице трябва да добавим "p1" или 'първо лице' и за време "pri" или 'сегашно изявително'.

<sdef n="vblex"/>
<sdef n="p1"/>
<sdef n="pri"/>

След като сме приключили с това, същото със съществителните, добавяме парадигма за спрягането на глагола. Първият ред ще бъде:

<pardef n="vid/eti__vblex">

'/' се използва да разграничава къде се добавят stems-ите (частите между таговете <l> </l>).

След това окончанието за първо лице, единствено число:

<e>
   <p>
     <l>im</l>
     <r>eti<s n="vblex"/><s n="pri"/><s n="p1"/><s n="sg"/></r>
   </p>
</e>

'im' обозначава края (като при 'vidim'), необходимо е да се добави 'eti' към секцията <r>, тъй като това ще бъде отрязано от дефиницията. Останалото е сравнително лесно, 'vblex' е лексикален глагол, 'pri' е сегашно изявително наклонение, 'p1' е първо лице и 'sg' е единствено число. Можем също да добавим множественото число, което ще бъде същото, освен 'imo' вместо 'im' и 'pl' вместо 'sg'.

След това трябва да добавим лема, парадигмично картографиране към главния раздел:

<e lm="videti"><i>vid</i><par n="vid/eti__vblex"/></e>

Забележка: съдържанието на <i> </i> е коренът, не лемата.

Това е работата по сърбо-хърватския речник, която сме свършили за сега. Нека да го компилираме и изпробваме.

$ lt-comp lr apertium-sh-en.sh.dix sh-en.automorf.bin
main@standard 23 25
$ echo "vidim" | lt-proc sh-en.automorf.bin
^vidim/videti<vblex><pri><p1><sg>$
$ echo "vidimo" | lt-proc sh-en.automorf.bin
^vidimo/videti<vblex><pri><p1><pl>$

Добре, сега правим същото и за английския речник (не забравяйте да добавите същите символни дефиниции, каквито добавихте за сърбо-хърватския речник).

Парадигмата е:

<pardef n="s/ee__vblex">

защото миналото време е 'видях'. Сега можем да направим едно от двете неща, можем да добавим и първо, и второ лице, но те са в една и съща форма. Фактически, всички форми (освен трето лице, единствено число) на глагола 'да видя' са 'виждам'. Така че вместо това ние правим само един запис за 'виждам' и му задаваме само символа 'pri'.

<e>
   <p>
     <l>ee</l>
     <r>ee<s n="vblex"/><s n="pri"/></r>
   </p>
</e>

и както винаги, запис в главния раздел:

<e lm="see"><i>s</i><par n="s/ee__vblex"/></e>

Тогава нека да запишем, да прекомпилираме и изпробваме:

$ lt-comp lr apertium-sh-en.en.dix en-sh.automorf.bin
main@standard 18 19

$ echo "see" | lt-proc en-sh.automorf.bin
^see/see<vblex><pri>$

Сега за задължителния запис в двуезичния речник:

<e><p><l>videti<s n="vblex"/></l><r>see<s n="vblex"/></r></p></e>

(отново, не забравяйте да добавите sdefs от по-рано)

И прекомпилираме:

$ lt-comp lr apertium-sh-en.sh-en.dix sh-en.autobil.bin
main@standard 18 18
$ lt-comp rl apertium-sh-en.sh-en.dix en-sh.autobil.bin
main@standard 18 18

Сега изпробваме:

$ echo "vidim" | lt-proc sh-en.automorf.bin | \
  gawk 'BEGIN{RS="$"; FS="/";}{nf=split($1,COMPONENTS,"^"); for(i = 1; i<nf; i++) printf COMPONENTS[i]; if($2 != "") printf("^%s$",$2);}' | \
  apertium-transfer apertium-sh-en.trules-sh-en.xml trules-sh-en.bin sh-en.autobil.bin 

^see<vblex><pri><p1><sg>$^@

Анализът преминава правилно, но когато се опитаме да генерираме повърхностна форма, получаваме '#' като по-долу:

$ echo "vidim" | lt-proc sh-en.automorf.bin | \
  gawk 'BEGIN{RS="$"; FS="/";}{nf=split($1,COMPONENTS,"^"); for(i = 1; i<nf; i++) printf COMPONENTS[i]; if($2 != "") printf("^%s$",$2);}' | \
  apertium-transfer apertium-sh-en.trules-sh-en.xml trules-sh-en.bin sh-en.autobil.bin | \
  lt-proc -g sh-en.autogen.bin
#see\@

Като '#' означава, че генераторът не може да генерира правилната лексикална форма, защото не я съдържа. Защо се получава така?

Принципно, анализите не съвпадат, 'виждам' в речника е виждам<vblex><pri>, но виждам получено от трансфера е виждам<vblex><pri><p1><sg>. В сърбо-хърватската страна има повече информация отколкото английската страна се нуждае. Можете да изпробвате това като добавите липсващите символи към английския речник, и след това прекомпилирате и тествате отново.

Все пак, по-парадигматичен начин да се погрижим за това е като напишем правило. Така, отваряме файлът с правилата (apertium-sh-en.trules-sh-en.xml в случай, че сте забравили).

Трябва да добавим нова категория за 'глагол'.

<def-cat n="vrb">
   <cat-item tags="vblex.*"/>
</def-cat>

Също така трябва да добавим атрибути за глаголно време и лице. Ще го направим много просто за сега, можете да добавите p2 и p3, но аз няма да го направя, за да спестя място.

<def-attr n="temps">
   <attr-item tags="pri"/>
</def-attr>

<def-attr n="pers">
   <attr-item tags="p1"/>
</def-attr>

Трябва също да добавим атрибут за глаголи.

<def-attr n="a_verb">
   <attr-item tags="vblex"/>
</def-attr>

Сега върху правилото:

<rule>
   <pattern>
     <pattern-item n="vrb"/>
   </pattern>
   <action>
     <out>
       <lu>
         <clip pos="1" side="tl" part="lem"/>
         <clip pos="1" side="tl" part="a_verb"/>
         <clip pos="1" side="tl" part="temps"/>
       </lu>
     </out>
   </action>
</rule>

Спомнете си когато се опитахте да махнете коментара на 'clip' таговете в предишния пример с правило и те изчезнаха от трансфера, ами, това е доста от което правим тук. Въвеждаме глагол с пълен анализ, но извеждаме само частичен анализ (лема + таг на глагола + таг на глаголното време).

Така че сега ако го прекомпилираме, получаваме:

$ echo "vidim" | lt-proc sh-en.automorf.bin | \
  gawk 'BEGIN{RS="$"; FS="/";}{nf=split($1,COMPONENTS,"^"); for(i = 1; i<nf; i++) printf COMPONENTS[i]; if($2 != "") printf("^%s$",$2);}' | \
  apertium-transfer apertium-sh-en.trules-sh-en.xml trules-sh-en.bin sh-en.autobil.bin
^see<vblex><pri>$^@

и:

$ echo "vidim" | lt-proc sh-en.automorf.bin  | \
  gawk 'BEGIN{RS="$"; FS="/";}{nf=split($1,COMPONENTS,"^"); for(i = 1; i<nf; i++) printf COMPONENTS[i]; if($2 != "") printf("^%s$",$2);}' | \
  apertium-transfer apertium-sh-en.trules-sh-en.xml trules-sh-en.bin sh-en.autobil.bin | \
  lt-proc -g sh-en.autogen.bin
see\@

Опитайте с 'vidimo' (ние виждаме) да видите дали получавате правилния изход.

Сега опитайте с "vidim gramofone":

$ echo "vidim gramofoni" | lt-proc sh-en.automorf.bin | \
  gawk 'BEGIN{RS="$"; FS="/";}{nf=split($1,COMPONENTS,"^"); for(i = 1; i<nf; i++) printf COMPONENTS[i]; if($2 != "") printf("^%s$",$2);}' | \
  apertium-transfer apertium-sh-en.trules-sh-en.xml trules-sh-en.bin sh-en.autobil.bin | \
  lt-proc -g sh-en.autogen.bin
see gramophones\@

Но какво да кажем за личните местоимения?

Ами, това е страхотно, но все още ни липсва личното местоимение, което е необходимо за английския. За да го добавим, трябва първо да редактираме английският морфологичен речник.

Като преди, първото нещо да направим е да добавим необходимите символи:

<sdef n="prn"/>
<sdef n="subj"/>

От двата символа, prn е местоимение и subj е подлог (като в подлога на изречение).

Защото няма корен или 'лема' за подлози лични местоимения, просто добавяме pardef както следва:

<pardef n="prsubj__prn">
   <e>
     <p>
       <l>I</l>
       <r>prpers<s n="prn"/><s n="subj"/><s n="p1"/><s n="sg"/></r>
     </p>
   </e>
</pardef>

Като 'prsubj' е 'личен подлог'. Останалите от тях (Вие, Ние и др.) са оставени като упражнение за читателя.

Можем да добавим запис към основния раздел както следва:

<e lm="personal subject pronouns"><i/><par n="prsubj__prn"/></e>

Така, записваме, прекомпилираме и тестваме, и трябва да получим нещо като:

$ echo "I" | lt-proc en-sh.automorf.bin
^I/PRPERS<prn><subj><p1><sg>$

(Забележка: в главни букви е, защото 'Аз' е с главни букви).

Сега трябва да коригираме правилото за 'глагол' да изкара подлог лично местоимение заедно с правилната форма на глагола.

Първо, добавяме категория (това трябва да бъде доста прозаично за сега):

<def-cat n="prpers">
   <cat-item lemma="prpers" tags="prn.*"/>
</def-cat>

Сега добавяме типовете местоимение като атрибути, можем да добавим и типа 'obj' като сме на него, въпреки че няма да ни трябва за сега:

<def-attr n="tipus_prn">
   <attr-item tags="prn.subj"/>
   <attr-item tags="prn.obj"/>
</def-attr>

И сега да въведем правилото:

<rule>
   <pattern>
     <pattern-item n="vrb"/>
   </pattern>
   <action>
     <out>
       <lu>
         <lit v="prpers"/>
         <lit-tag v="prn"/>
         <lit-tag v="subj"/>
         <clip pos="1" side="tl" part="pers"/>
         <clip pos="1" side="tl" part="nbr"/>
       </lu>
       <b/>
       <lu>
         <clip pos="1" side="tl" part="lem"/>
         <clip pos="1" side="tl" part="a_verb"/>
         <clip pos="1" side="tl" part="temps"/>
       </lu>
     </out>
   </action>
</rule>

Това е почти същото правило като преди, само ще направим няколко малки промени.

Трябваше да изкараме:

^prpers<prn><subj><p1><sg>$ ^see<vblex><pri>$

така че генераторът да може да избере правилното местоимение и правилната форма на глагола.

Така че накратко:

  • <lit>, отпечатва буквен низ, в този случай "prpers"
  • <lit-tag>, отпечатва буквен таг, защото не можем да вземем таговете от глагола ги добавяме сами, "prn" за местоимение и "subj" за подлог.
  • , отпечатва празно пространство.

Забележете, че получихме информацията за номер и време директно от глагола.

Така, сега ако го прекомпилираме и тестваме отново:

$ echo "vidim gramofone" | lt-proc sh-en.automorf.bin  | \
  gawk 'BEGIN{RS="$"; FS="/";}{nf=split($1,COMPONENTS,"^"); for(i = 1; i<nf; i++) printf COMPONENTS[i]; if($2 != "") printf("^%s$",$2);}' | \
  apertium-transfer apertium-sh-en.trules-sh-en.xml trules-sh-en.bin sh-en.autobil.bin | \
  lt-proc -g sh-en.autogen.bin
I see gramophones

Което, макар и да не е точно проза на лауреат (много харесвам това HOWTO), е относително точен превод.

Кажи ми за грамофона (Мултидуми)

Докато грамофон е английска дума, това не е най-добрият превод. Грамофон обикновено се използва за много стар вид, който вие познавате с игла вместо с щифт без усилване. По-добър превод би бил 'record player'('записващ плейър'). Въпреки че това е повече от една дума, може да го разглеждаме като, че е една дума като използваме конструкции на мултидуми (multipalabra).

Не трябва да пипаме сърбо-хърватския речник, само английския и двуезичния, така че го отворете.

Множественото число на 'record player' е 'record players', така че да приема същата парадигма като грамофон (gramophone__n) — при това ние просто добавихме 's'. Всичко, което е необходимо да направим е да добавим нов елемент към главния раздел.

<e lm="record player"><i>record<b/>player</i><par n="gramophone__n"/></e>

Единственото различно тук е използването на тага , въпреки че това не е изцяло ново както го видяхме в употреба във файлът с правила.

Така, прекомпилираме и тестваме в старата последователност:

$ echo "vidim gramofone" | lt-proc sh-en.automorf.bin | \
  gawk 'BEGIN{RS="$"; FS="/";}{nf=split($1,COMPONENTS,"^"); for(i = 1; i<nf; i++) printf COMPONENTS[i]; if($2 != "") printf("^%s$",$2);}' | \
  apertium-transfer apertium-sh-en.trules-sh-en.xml trules-sh-en.bin sh-en.autobil.bin  | \
  lt-proc -g sh-en.autogen.bin
I see record players

Перфектно. Голяма полза от използването на мултидуми е, че можете да превеждате идиоматични изрази дословно, без да се налага да превеждате дума-по-дума. Например английската фраза "at the moment"("в момента") би била преведена на сръбско-хърватски като "trenutno" (trenutak = moment, trenutno е наречие на това) — преводът на тази английска фраза в сърбо-хърватски не би бил възможен дума по дума.

Справяне с незначително изменение

Сърбо-хърватският обикновено има няколко начина за изписване на всяка дума заради диалектните варианти. Има яка фонетична писмена система, така че се пише както се изговаря. Например, хората говорещи в Ijekavian биха казали "rječnik", докато някой говорещ Ekavian би казал "rečnik", което отразява разликите в произношението на прото-славянската гласна yat.

Анализ

Трябва да има относително лесен начин за справяне с това, и има, отново чрез използване на парадигми. Парадигми не се използват само за добавяне на граматични символи, но те също така могат да бъдат използвани да заменят всеки знак/символ с друг. Например, ето парадигма за приемане на "e" и "je" в анализа. Парадигмата трябва, както другите, да отиде в едноезичния сърбо-хърватски речник.

  <pardef n="e_je__yat">
    <e>
      <p>
        <l>e</l>
        <r>e</r>
      </p>
    </e>
    <e>
      <p>
        <l>je</l>
        <r>e</r>
      </p>
    </e>
  </pardef>

Тогава в "основния раздел":

    <e lm="rečnik"><i>r</i><par n="e_je__yat"/><i>čni</i><par n="rečni/k__n"/></e>

Но това само ни позволява да анализираме двете форми... необходима е повече работа, ако искаме да генерираме и двете форми.

Възпроизвеждане

Виж също