Difference between revisions of "Uputstvo za novi jezički par za Apertium"

From Apertium
Jump to navigation Jump to search
m (Reverted edits by 74.231.24.2 (Talk); changed back to last version by Francis Tyers)
 
(8 intermediate revisions by 3 users not shown)
Line 74: Line 74:


Prvo ćemo napraviti rečnik za izvorni jezik, koji se nalazi u XML fajlu. Pokrenite tekst editor i ukucajte sledeće:
Prvo ćemo napraviti rečnik za izvorni jezik, koji se nalazi u XML fajlu. Pokrenite tekst editor i ukucajte sledeće:
and type the following:


<pre>
<pre>
Line 182: Line 181:
* par, je za paradigmu.
* par, je za paradigmu.


Ovaj unos navodi lemu reči (gramofon), koren reči (gramogon) i paradigmu kojom se menja (gramofon__n). Razlika između leme i korena je u tome što je lema oblik reči kako se navodi u rečniku, a koren je deo leme na koji se dodaju dodaci. Ovo će biti jasnije s primerom gde se lema i koren razlikuju.
Ovaj unos navodi lemu reči (gramofon), koren reči (gramofon) i paradigmu kojom se menja (gramofon__n). Razlika između leme i korena je u tome što je lema oblik reči kako se navodi u rečniku, a koren je deo leme na koji se dodaju dodaci. Ovo će biti jasnije s primerom gde se lema i koren razlikuju.


Sada možemo da testiramo rečnik. Sačuvajte ga, te se vratite u shell. Prvo treba da ga kompajliramo (sa lt-comp), a onda da ga testiramo (sa lt-proc).
Sada možemo da testiramo rečnik. Sačuvajte ga, te se vratite u shell. Prvo treba da ga kompajliramo (sa lt-comp), a onda da ga testiramo (sa lt-proc).
Line 206: Line 205:
^gramofoni/gramofon<n><pl>$
^gramofoni/gramofon<n><pl>$
</pre>
</pre>
Uradimo isto i za engleski rečnik, ali zamenimo Englesku reč gramophone sa gramofon i promenimo menjanje u množini. Kasnije ćemo objasniti šta bi radili da želimo da koristimo formalniji izraz „record plazer“.
Uradimo isto i za engleski rečnik, ali zamenimo Englesku reč gramophone sa gramofon i promenimo menjanje u množini. Kasnije ćemo objasniti šta bi radili da želimo da koristimo formalniji izraz „record player“.


Sada bi trebalo da imate dva fajla u direktorijumu:
Sada bi trebalo da imate dva fajla u direktorijumu:
Line 243: Line 242:
<pre>
<pre>
$ lt-comp lr apertium-sh-en.sh.dix sh-en.automorf.bin
$ lt-comp lr apertium-sh-en.sh.dix sh-en.automorf.bin
$ lt-comp rl apertium-sh-en.sh.dix sh-en.autogen.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 lr apertium-sh-en.en.dix en-sh.automorf.bin
$ lt-comp rl apertium-sh-en.en.dix en-sh.autogen.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 lr apertium-sh-en.sh-en.dix sh-en.autobil.bin
Line 350: Line 349:
koja će generisati fajl trules-sh-en.bin.
koja će generisati fajl trules-sh-en.bin.


Sada smo spremni isprobati naš automatizirani sustav za prevođenje. Fali nam još jedan ključni dio, a to je „part-of-speech“ (PoS) navodioc, ali to će biti uskoro objašnjeno. Za sada možemo izvršiti probu ovako kako jest.
Now we're ready to test our machine translation system. There is one crucial part missing, the part-of-speech (PoS) tagger, but that will be explained shortly. In the meantime we can test it as is:


First, lets analyse a word, gramofoni:
Prvo, analizirajmo riječ, gramofoni:
<pre>
<pre>
$ echo "gramofoni" | lt-proc sh-en.automorf.bin
$ echo "gramofoni" | lt-proc sh-en.automorf.bin

^gramofon/gramofon<n><pl>$
^gramofon/gramofon<n><pl>$
</pre>
</pre>

Now, normally here the POS tagger would choose the right version based on the part of speech, but we don't have a POS tagger yet, so we can use this little gawk script (thanks to Sergio) that will just output the first item retrieved.
Ovdje bi inače POS navodioc odabrao ispravnu verziju baziranu na dijelu govora, ali pošto za sada još ne koristimo POS navodioc, pa možemo koristiti ovu mali „gawk“ skriptu (pohvala Sergiu) koja će jednostavno ispisati prvu dobivenu stavku.

<pre>
<pre>
$ echo "gramofoni" | lt-proc sh-en.automorf.bin | \
$ 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);}' | \
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>$
^gramofon<n><pl>$
</pre>
</pre>

Now let's process that with the transfer rule:
Ajmo sad to procesirati sa transfernom naredbom:
<pre>
<pre>
$ echo "gramofoni" | lt-proc sh-en.automorf.bin | \
$ echo "gramofoni" | lt-proc sh-en.automorf.bin | \
Line 369: Line 373:
apertium-transfer apertium-sh-en.trules-sh-en.xml trules-sh-en.bin sh-en.autobil.bin
apertium-transfer apertium-sh-en.trules-sh-en.xml trules-sh-en.bin sh-en.autobil.bin
</pre>
</pre>
Ispis će biti:
It will output:
<pre>
<pre>
^gramophone<n><pl>$^@
^gramophone<n><pl>$^@
</pre>
</pre>
* 'gramophone' is the target language (side="tl") lemma (lem) at position 1 (pos="1").
* '<n>' is the target language a_nom at position 1.
* '<pl>' is the target language attribute of number (nbr) at position 1.


* 'gramophone' je ciljani jezik (side="tl") lema (lem) na poziciji 1 (pos="1").
Try commenting out one of these clip statements, recompiling and seeing what happens.
* '<n>' je ciljani jezik a_nom na poziciji 1.
* '<pl>' jest ciljani jezični brojčani atribut (nbr) na poziciji 1.


Pokušajte kometirati iz ovih izdvojanih naredbi, rekompilirajte i vidite što se događa.
So, now we have the output from the transfer, the only thing that remains is to generate the target-language inflected forms. For this, we use lt-proc, but in generation (-g), not analysis mode.

Sad posjedujemo ispis iz transfera, jedino što nam još nedostaje je sklonidba ciljanog jezika. Radi ovoga imamo lt-proc, ali to je kod generiranja (-g), a ne u analitičkom načinu rada.
<pre>
<pre>
$ echo "gramofoni" | lt-proc sh-en.automorf.bin | \
$ 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);}' | \
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 | \
apertium-transfer apertium-sh-en.trules-sh-en.xml trules-sh-en.bin sh-en.autobil.bin | \
lt-proc -g sh-en.autogen.bin
lt-proc -g sh-en.autogen.bin


gramophones\@
gramophones\@
</pre>
</pre>
And c'est ca. You now have a machine translation system that translates a Serbo-Croatian noun into an English noun. Obviously this isn't very useful, but we'll get onto the more complex stuff soon. Oh, and don't worry about the '@' symbol, I'll explain that soon too.


I „c'est ca“. Sada posjedujete automatizirani sustav za prevođenje koji može prevesti Srpsko-Hrvatsku imanicu u Englesku imenicu. Naravno da ovo nije od neke koristi, ali uskoro prelazimo na kompliciranije stvari. I ne brinite za '@' symbol, I to će vam biti uskoro objašnjeno.
Think of a few other words that inflect the same as gramofon. How about adding those. We don't need to add any paradigms, just the entries in the main section of the monolingual and bilingual dictionaries.

Sjetite se nekih drugih riječi kao što je „gramofon“. Možete njih uključiti. Ne moramo pridodati obrazce, jedino unose u glavnoj sekciji u monolingvističkim te bilingvističkim rječnicima.

==Bring on the verbs==

Ok, so we have a system that translates nouns, but thats pretty useless, we want to translate verbs too, and even whole sentences! How about we start with the verb to see. In Serbo-Croatian this is videti. Serbo-Croatian is a null-subject language, this means that it doesn't typically use personal pronouns before the conjugated form of the verb. English is not. So for example: I see in English would be translated as vidim in Serbo-Croatian.

* Vidim
* see<p1><sg>
* I see

Note: <p1> denotes first person

This will be important when we come to write the transfer rule for verbs. Other examples of null-subject languages include: Spanish, Romanian and Polish. The also has the effect that while we only need to add the verb in the Serbo-Croatian morphological dictionary, we need to add both the verb, and the personal pronouns in the English morpohlogical dictionary. We'll go through both of these.

The other forms of the verb videti are: vidiš, vidi, vidimo, vidite, and vide; which correspond to: you see (singular), he sees, we see, you see (plural), and they see.

There are two forms of you see, one is plural and formal singular (vidite) and the other is singular and informal (vidiš).

We're going to try and translate the sentence: "Vidim gramofoni" into "I see gramophones". In the interests of space, we'll just add enough information to do the translation and will leave filling out the paradigms (adding the other conjugations of the verb) as an exercise to the reader.

The astute reader will have realised by this point that we can't just translate vidim gramofoni because it is not a grammatically correct sentence in Serbo-Croatian. The correct sentence would be vidim gramofone, as the noun takes the accusative case. We'll have to add that form too, no need to add the case information for now though, we just add it as another option for plural. So, just copy the 'e' block for 'i' and change the 'i' to 'e' there.

First thing we need to do is add some more symbols. We need to first add a symbol for 'verb', which we'll call "vblex" (this means lexical verb, as opposed to modal verbs and other types). Verbs have 'person', and 'tense' along with number, so lets add a couple of those aswell. We need to translate "I see", so for person we should add "p1", or 'first person', and for tense "pri", or 'present indicative'.
<pre>
<sdef n="vblex"/>
<sdef n="p1"/>
<sdef n="pri"/>
</pre>
After we've done this, the same with the nouns, we add a paradigm for the verb conjugation. The first line will be:
<pre>
<pardef n="vid/eti__vblex">
</pre>
The '/' is used to demarcate where the stems (the parts between the <l> </l> tags) are added to.

Then the inflection for first person singular:
<pre>
<e>
<p>
<l>im</l>
<r>eti<s n="vblex"/><s n="pri"/><s n="p1"/><s n="sg"/></r>
</p>
</e>
</pre>
The 'im' denotes the ending (as in 'vidim'), it is necessary to add 'eti' to the <r> section, as this will be chopped off by the definition. The rest is fairly straightforward, 'vblex' is lexical verb, 'pri' is present indicative tense, 'p1' is first person and 'sg' is singular. We can also add the plural which will be the same, except 'imo' instead of 'im' and 'pl' instead of 'sg'.

After this we need to add a lemma, paradigm mapping to the main section:
<pre>
<e lm="videti"><i>vid</i><par n="vid/eti__vblex"/></e>
</pre>
Note: the content of <i> </i> is the root, not the lemma.

Thats the work on the Serbo-Croatian dictionary done for now. Lets compile it then test it.
<pre>
$ 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>$
</pre>
Ok, so now we do the same for the English dictionary (remember to add the same symbol definitions here as you added to the Serbo-Croatian one).

The paradigm is:
<pre>
<pardef n="s/ee__vblex">
</pre>
because the past tense is 'saw'. Now, we can do one of two things, we can add both first and second person, but they are the same form. In fact, all forms (except third person singular) of the verb 'to see' are 'see'. So instead we make one entry for 'see' and give it only the 'pri' symbol.
<pre>
<e>
<p>
<l>ee</l>
<r>ee<s n="vblex"/><s n="pri"/></r>
</p>
</e>
</pre>
and as always, an entry in the main section:
<pre>
<e lm="see"><i>s</i><par n="s/ee__vblex"/></e>
</pre>
Then lets save, recompile and test:
</pre>
$ 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>$
</pre>
Now for the obligatory entry in the bilingual dictionary:
<pre>
<e><p><l>videti<s n="vblex"/></l><r>see<s n="vblex"/></r></p></e>
</pre>
(again, don't forget to add the sdefs from earlier)

And recompile:
<pre>
$ 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
</pre>
Now to test:
<pre>
$ 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>$^@
</pre>
We get the analysis passed through correctly, but when we try and generate a surface form from this, we get a '#', like below:
<pre>
$ 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\@
</pre>
This '#' means that the generator cannot generate the correct lexical form because it does not contain it. Why is this?

Basically the analyses don't match, the 'see' in the dictionary is see<vblex><pri>, but the see delivered by the transfer is see<vblex><pri><p1><sg>. The Serbo-Croatian side has more information than the English side requires. You can test this by adding the missing symbols to the English dictionary, and then recompiling, and testing again.

However, a more paradigmatic way of taking care of this is by writing a rule. So, we open up the rules file (apertium-sh-en.trules-sh-en.xml in case you forgot).

We need to add a new category for 'verb'.
<pre>
<def-cat n="vrb">
<cat-item tags="vblex.*"/>
</def-cat>
</pre>
We also need to add attributes for tense and for person. We'll make it really simple for now, you can add p2 and p3, but I won't in order to save space.
<pre>
<def-attr n="temps">
<attr-item tags="pri"/>
</def-attr>

<def-attr n="pers">
<attr-item tags="p1"/>
</def-attr>
</pre>
We should also add an attribute for verbs.
<pre>
<def-attr n="a_verb">
<attr-item tags="vblex"/>
</def-attr>
</pre>
Now onto the rule:
<pre>
<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>
</pre>
Remember when you tried commenting out the 'clip' tags in the previous rule example and they disappeared from the transfer, well, thats pretty much what we're doing here. We take in a verb with a full analysis, but only output a partial analysis (lemma + verb tag + tense tag).

So now, if we recompile that, we get:
<pre>
$ 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>$^@
</pre>
and:
<pre>
$ 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\@
</pre>
Try it with 'vidimo' (we see) to see if you get the correct output.

Now try it with "vidim gramofone":
<pre>
$ 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\@
</pre>


==See also==


*[[Building dictionaries]]
*[[Finding_errors_in_dictionaries]]
*[[Cookbook]]
*[[Chunking]]
*[[Contributing to an existing pair]]


[[Category:Documentation]]
[[Category:Documentation]]
[[Category:HOWTO]]
[[Category:Writing dictionaries]]
[[Category:Quickstart]]

Latest revision as of 07:00, 16 February 2015

Uputstvo za novi jezički par za Apertium

Ovo uputstvo će objasniti kako započeti novi jezički par za Apertium mašinski prevod. Ne podrazumevamo poznavanje lingvistike ili mašinskog prevođenja - dovoljno je da znate da razlikujete različite vrste reči (imenice, glagole, prideve itd.)

Reč-dve o srpskohrvatskom prevodu[edit]

Ovaj prevod koristi Unicode prikaz slova Lj, Nj i Dž umesto Lj, Nj i Dž. Ukoliko ne vidite ta slova, instalirajte set slobodnih fontova koji podržavaju Unicode, kao što su DejaVu fontovi i postarajte se da gledate ovu stranicu u UTF8 kodnom rasporedu.

U prevodu takođe koristimo neke neologizme koji su se ustalili u upotrebi na srpskohrvatskom govornom području. Npr. file „prevodimo“ kao fajl umesto uobičajenog datoteka.

Uvod[edit]

Kao što ste možda primetili iz uvoda, Apertium je sistema mašinskog prevođenja. Preciznije, u pitanju je platforma za prevod koja obuhvata pokretački motor i alatke koje dozvoljavaju pravljenje ličnog sistema mašinskog prevođenja. Vi samo treba da unesete podatke. U osnovi, podaci se sastoje iz tri rečnika i nekoliko pravila koji se staraju za tačan red reči u rečenici i druge gramatičke zavrzlame.

Za detaljnije uputstvo o tome kako ovo sve radi, pročitajte dokumentaciju na sajtu projekta na apertium.sourceforge.net.

Trebaće Vam[edit]

  • lttoolbox (>= 3.0.0)
  • libxml utils (xmllint itd.)
  • apertium (>= 3.0.0)
  • editor teksta (ili specijalizovani uređivač za XML, ako Vam tako više odgovara)

Za instrukcije kako da instalirate ove programe pogledajte dokumentaciju na sajtu Apertiuma.

Od čega se sastoji jezički par?[edit]

Apertium koristi „plitki“ mašinski prevod, što znači da se koristi rečnicima i plitkim pravilima prenosa.

„Plitki prevod“ se razlikuje od „dubokog prevoda“ utoliko što se ne bavi punom sintatičkom obradom. Pravila se obično primenjuju na grupe leksičkih jedinica, umesto na razgranatu obradu. U osnovi postoje tri glavna rečnika.

  1. Morfološki rečnik za jezik xx: on sadrži pravila o tome kako se menjaju reči u jeziku xx. U našem primeru ovo ćemo zvati: apertium-sh-en.sh.dix.
  2. Morfološki rečnik za jezik yy: on sadrži pravila o tome kako se menjaju reči u jeziku yy. U našem primeru ovo ćemo zvati: apertium-sh-en.en.dix.
  3. Dvojezički rečnik: on sadrži odnos između reči i simbola dva jezika. U našem primeru ovo ćemo zvati: apertium-sh-en.sh-en.dix.

U paru za prevod, oba jezika mogu biti i izvor i cilj prevoda, te su ovi izrazi relativni.

Postoje i dva fajla za pravila prevoda i to su pravila o redu reči u rečenici, npr. chat noir → cat black → black cat. Takođe se staraju i o slaganju roda i broja i sl. Pravila se mogu koristiti i za ubacivanje i prisanje leksičkih stavki, a o tome ćemo kasnije. Fajlovi u pitanju su:

  • pravila prevoda jezika xx u jezik yy: ovaj fajl sadrži pravila po kojim će se jezik xx menjati u jezik yy. U našem primeru ovo ćemo zvati: apertium-sh-en.trules-sh-en.xml
  • pravila prevoda jezika yy u jezik xx: ovaj fajl sadrži pravila po kojim će se jezik yy menjati u jezik xx. U našem primeru ovo ćemo zvati: apertium-sh-en.trules-sh-en.xml

Iako u postojećim jezičkim parovima postoje i neki drugi fajlovi, ovi koje smo naveli su neophodni i dovoljni za funkcionalni sistem.

Jezički par[edit]

Možda ste već skapirali iz imena fajlova, ali ovo uputstvo će se koristiti prevod srpskohrvatskog u engleski radi objašnjenja kako da napravite osnovni sistem. Primer nije idealan, jer sistem bolje funkcioniše na srodnijim jezicima.

O terminologiji[edit]

Pre nego što nastavimo, bitno je da pojasnimo neke izraze:

Prvi izraz je lema. U pitanju je izvorni oblik reči, kakav se nalazi u rečniku. Recimo, nominativ jednine za imenice, te infinitiv za glagole. Glagol „raditi“ je lema, dok je „radim“ ili „radiš“ njegova inflikcija. Reč „mačke“ je inflikcija leme „mačka“

Drugi izraz je simbol. U našem kontekstvu, simbol je gramatička oznaka. Reč „mačke“ je množina imenice, te će imati simbole imenice i množine. Ova informacija se obično stavlja u kose zagrade, recimo:

  • <n>; za imenicu (od španskog nom)
  • <pl>; za množinu (od španskog plural).

Neki drugi simboli su <sg> jednina, <p1> prvo lice itd. Valja napomenuti da su u većini jezičkih parova korišćeni katalonski izrazi za simbole. Npr. vbhaver - od vb (verb) i haver (imati). Simboli su definisani u <sdef> tagovima i korišćeni u <s> tagovima.

Treća reč je paradigma. U našem kontekstu, paradigma označava primer kako se neka grupa reči menja. U morfološkim rečnicima leme su povezane s paradigmama koje nam dozvoljavaju da opišemo kako se data reč menja bez pisanja svakog pojedinačnog nastavka.

Recimo da želimo da opišemo komparaciju prideva „srećan“ i „dosadan“:

  • srećan, sreć (an, niji, naj - niji)
  • dosadan, dosad (an, niji, naj - niji)

Dovoljno je da napišemo jedno pravilo za pridev koje se primenjuje na mnogo drugih prideva. Paradigme se definišu u tagu <pardef>, a koriste u <par>.

Sâm početak[edit]

Jednojezički rečnici[edit]

Prvo ćemo napraviti rečnik za izvorni jezik, koji se nalazi u XML fajlu. Pokrenite tekst editor i ukucajte sledeće:

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

</dictionary>

Dakle, fajl do sada definiše našu želju da sačinimo novi rečnik. Da bi taj rečnik bio iole koristan, neophodno je da prvo dodamo abecedu - spisak slova koje ćemo koristiti u rečniku. Za srpskohrvatski:

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

Dodajte abecedu ispod <dictionary> taga.

Sada treba da definišemo neke simbole. Počnimo s jednostavnim - imenica (n) u jednini (sg) ili množini (pl).

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

Simboli ne moraju biti kratki, možete koristiti i ce izraz ukoliko želite. Ipak, pošto ćete to često pisati, ima smisla koristiti skraćenice.

Očigledno, nije sve tako jednostavno jer se reči deklinuju i konjuguju itd. ali ćemo za potrebe ovog primera pretpostaviti da je imenica muškog roda u jednini.

Sledeći zadatak je da definišemo paradigme:

<pardefs>

</pardefs>

i sekciju za rečnik:

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

</section>

Postoje dve vrste sekcija - prva je standardna, koja sadrži reči, enklitike itd. Drugi tip sadrži stvari kao što interpunkcija i ostale nezavisne simbole. Ovde tu sekciju nemamo, ali ćemo je kasnije demonstrirati.

Konačno, naš fajl će izgledati ovako:

<?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>

Pošto smo postavili temelj rečniku, možemo dodati imenicu. Igrom slučaja, izabrali smo da za demonstraciju koristimo imenicu „gramofon“.

Za početak treba da definišemo paradigmu.

Podrazumevamo imenicu muškog roda u nominativu. Jednina je „gramofon“, a množina „gramofoni“. Elem:

<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>

Pažnja: tag „<l/>“ (ekvivalent <l></l>) označava da ništa ne treba dodati korenu reči.

Tagovi kao što su <e>,

, <l> and <r> označavaju sledeće:

  • e, je za unos (entry).
  • p, je za par (pair).
  • l, je za levo (left).
  • r, je za desno (right).

Levo i desno imaju svoju svrhu. Naime, morfološki rečnici se kasnije kompajliraju u konačnu mašinu. Kompilacija s leva na desno proizvodi analizu iz reči, a s desna na levo proizvodi reč iz analize. Na primer:

* gramofoni → gramofon<n><pl> (analiza)
* gramofon<n><pl> ← gramofoni (generisanje)

Kada smo definisali paradigmu, treba je povezati sa lemom - gramofon. Stavićemo to u sekciju koju smo definisali.

Unos će biti ovakav:

<e lm="gramofon"><i>gramofon</i><par n="gramofon__n"/></e>

Objašnjenje prečica:

  • lm, je za lema
  • i, je za identitet (svejedno da li je levo ili desno).
  • par, je za paradigmu.

Ovaj unos navodi lemu reči (gramofon), koren reči (gramofon) i paradigmu kojom se menja (gramofon__n). Razlika između leme i korena je u tome što je lema oblik reči kako se navodi u rečniku, a koren je deo leme na koji se dodaju dodaci. Ovo će biti jasnije s primerom gde se lema i koren razlikuju.

Sada možemo da testiramo rečnik. Sačuvajte ga, te se vratite u shell. Prvo treba da ga kompajliramo (sa lt-comp), a onda da ga testiramo (sa lt-proc).

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

Treba da ispiše:

main@standard 12 12

Kako kompajliramo s leva na desno, pravimo analizator. Napravimo i generator:

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

Sada bi naredba treablo da dâ isti izlaz.

Da testiramo. Pokrenit lt-proc na analizatoru.

$ lt-proc sh-en.automorf.bin

Testirajte ga. Upišite gramofoni, pa pogledajte ispis:

^gramofoni/gramofon<n><pl>$

Uradimo isto i za engleski rečnik, ali zamenimo Englesku reč gramophone sa gramofon i promenimo menjanje u množini. Kasnije ćemo objasniti šta bi radili da želimo da koristimo formalniji izraz „record player“.

Sada bi trebalo da imate dva fajla u direktorijumu:

  • apertium-sh-en.sh.dix koji sadrži (veoma jednostavi) srpskohrvatski morfološki rečnik i
  • apertium-sh-en.en.dix koji sadrži (veoma jednostavi) engleski morfološki rečnik.

Dvojezički rečnik[edit]

Pošto imamo dva morfološka rečnika, možemo napraviti dvojezički rečnik, koji opisuje odnos između reči. Svi rečnici koriste isti format (detaljian u DTD, dix.dtd).

Napravite novi fajl, apertium-sh-en.sh-en.dix i dodajte kostur:

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

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

   </section>
</dictionary>

Sada nam treba unos za prevod između dve reči. Nešto kao:

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

Pišemo jedan unos po redu iz prostog razloga što će ih biti puno, pa da ne bi uništili čitljivost. I opet koristimo „l“ i „r“… Kompajliramo ga levo na desno da bi dobili srpskohrvatsko - engleski rečnik, a desno na levo za englesko - srpskohrvatski rečnik.

Nakon što ste to završili, pokrenite sledeće naredbe:

$ 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

… da generišete morfološki analizator (automorf), morfološki generator (autogen) i traženje reči (autobil). Bil je skraćeno za „bilingual“ (dvojezičko).

Pravila prevoda[edit]

Pošto imamo dva morfološka rečnika i dvojezički rečnik, potrebna su nam pravila prevoda za imenice. Pravila prevoda imaju svoj DTD (transfer.dtd), koji se može naći u paketu Apertiuma. Ako treba da implementirate pravila, poželjno je da prvo konsultujete pravila drugih parova jezika, jer se mnoga pravila daju reciklirati. Npr. pravila opisana dole važe za sve jezike gde se subjekat izostavlja:

Započnite skeletonom:

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

</transfer>

Trenutno, pošto ignorišemo padeže, treba nam samo pravilo koje prima unos gramatičkih simbola, te ih ponovo ispisuje.

Kao prvo, treba da definišemo kategorije i atribute, koji nam dozvoljavaju grupisanje gramatičkih simbola. Kategorijama možemo grupisati simbole radi pretrage (npr. „n.*“ su sve imenice). Atributima grupišemo simbole među kojima se može birati (npr. „sg“ i „pl“ mogu grupisati atribut „number“).

Dodajmo neophodne delove:

<section-def-cats>

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

</section-def-attrs>

Pošto vršimo samo inflikciju imenica u jednini i množini, neophodna nam je kategorija za imenice sa atributom broja. Nešto kao:

U section-def-cats dodajte:

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

Ovo će „uhvatiti“ sve imenice (leme iza kojih je <n>, pa bilo šta), a „obraćaće“ im se sa „nom“, što ćemo detaljnije proučiti kasnije.

U section section-def-attrs, dodajte:

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

te onda:

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

Prvo smo definisali atribute nbr (number - broj), koji može biti u jednini (sg) ili množini (pl).

Onda smo definisali atribut a_nom (atribut imenica).

Zatim nam treba sekcija za globalne promenljive.

<section-def-vars>

</section-def-vars>

Ove promenljive drže ili služe za transfer atributa među pravilima. Za sada nam treba samo jedan.

<def-var n="number"/>

Konačno, treba da dodamo pravilo kojim ćemo unešenu imenicu ispisati u tačnom obliku. Trebaće nam sekcija za pravila…

<section-rules>

</section-rules>

A sada, prvo pogledajmo sâm primer, koji ćemo kasnije objasniti.

<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>

Prvi je tag očigledan - definiše pravilo. Drugi tag govori: „primeni ovo pravilo ako je zadati niz za pretraga pronađen“. U ovom primeru zadati se niz sastoji od jedne imenice. Obratite pažnju da se nizovi za pretragu pronalaze „široko“, tj. prvo se nalazi najduži niz. Ako imate tri pravila, prvo pravilo će pronaći „<prn><vblex><n>“, drugo pravilo će pronaći „<prn><vblex>“, a treće će pronaći „<n>“, pa će samo prvo pravilo biti uzeto u obzir.

Za svaki niz pretrage postoji i odgovarajuća akcija koja proizvodi odgovarajući ispis. Ispis je leksička jedinica (lu).

Atributi i izvornog jezika (side="sl") i ciljnog jezika (side="sl") se mogu manipulisati „clip“ tagovima.

Sada možemo kompajlirati i testirati program. Pravila prenosa se kompajliraju komandom:

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

koja će generisati fajl trules-sh-en.bin.

Sada smo spremni isprobati naš automatizirani sustav za prevođenje. Fali nam još jedan ključni dio, a to je „part-of-speech“ (PoS) navodioc, ali to će biti uskoro objašnjeno. Za sada možemo izvršiti probu ovako kako jest.

Prvo, analizirajmo riječ, gramofoni:

$ echo "gramofoni" | lt-proc sh-en.automorf.bin

^gramofon/gramofon<n><pl>$

Ovdje bi inače POS navodioc odabrao ispravnu verziju baziranu na dijelu govora, ali pošto za sada još ne koristimo POS navodioc, pa možemo koristiti ovu mali „gawk“ skriptu (pohvala Sergiu) koja će jednostavno ispisati prvu dobivenu stavku.

$ 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>$

Ajmo sad to procesirati sa transfernom naredbom:

$ 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

Ispis će biti:

^gramophone<n><pl>$^@
  • 'gramophone' je ciljani jezik (side="tl") lema (lem) na poziciji 1 (pos="1").
  • '<n>' je ciljani jezik a_nom na poziciji 1.
  • '<pl>' jest ciljani jezični brojčani atribut (nbr) na poziciji 1.

Pokušajte kometirati iz ovih izdvojanih naredbi, rekompilirajte i vidite što se događa.

Sad posjedujemo ispis iz transfera, jedino što nam još nedostaje je sklonidba ciljanog jezika. Radi ovoga imamo lt-proc, ali to je kod generiranja (-g), a ne u analitičkom načinu rada.

$ 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\@

I „c'est ca“. Sada posjedujete automatizirani sustav za prevođenje koji može prevesti Srpsko-Hrvatsku imanicu u Englesku imenicu. Naravno da ovo nije od neke koristi, ali uskoro prelazimo na kompliciranije stvari. I ne brinite za '@' symbol, I to će vam biti uskoro objašnjeno.

Sjetite se nekih drugih riječi kao što je „gramofon“. Možete njih uključiti. Ne moramo pridodati obrazce, jedino unose u glavnoj sekciji u monolingvističkim te bilingvističkim rječnicima.

Bring on the verbs[edit]

Ok, so we have a system that translates nouns, but thats pretty useless, we want to translate verbs too, and even whole sentences! How about we start with the verb to see. In Serbo-Croatian this is videti. Serbo-Croatian is a null-subject language, this means that it doesn't typically use personal pronouns before the conjugated form of the verb. English is not. So for example: I see in English would be translated as vidim in Serbo-Croatian.

  • Vidim
  • see<p1><sg>
  • I see

Note: <p1> denotes first person

This will be important when we come to write the transfer rule for verbs. Other examples of null-subject languages include: Spanish, Romanian and Polish. The also has the effect that while we only need to add the verb in the Serbo-Croatian morphological dictionary, we need to add both the verb, and the personal pronouns in the English morpohlogical dictionary. We'll go through both of these.

The other forms of the verb videti are: vidiš, vidi, vidimo, vidite, and vide; which correspond to: you see (singular), he sees, we see, you see (plural), and they see.

There are two forms of you see, one is plural and formal singular (vidite) and the other is singular and informal (vidiš).

We're going to try and translate the sentence: "Vidim gramofoni" into "I see gramophones". In the interests of space, we'll just add enough information to do the translation and will leave filling out the paradigms (adding the other conjugations of the verb) as an exercise to the reader.

The astute reader will have realised by this point that we can't just translate vidim gramofoni because it is not a grammatically correct sentence in Serbo-Croatian. The correct sentence would be vidim gramofone, as the noun takes the accusative case. We'll have to add that form too, no need to add the case information for now though, we just add it as another option for plural. So, just copy the 'e' block for 'i' and change the 'i' to 'e' there.

First thing we need to do is add some more symbols. We need to first add a symbol for 'verb', which we'll call "vblex" (this means lexical verb, as opposed to modal verbs and other types). Verbs have 'person', and 'tense' along with number, so lets add a couple of those aswell. We need to translate "I see", so for person we should add "p1", or 'first person', and for tense "pri", or 'present indicative'.

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

After we've done this, the same with the nouns, we add a paradigm for the verb conjugation. The first line will be:

<pardef n="vid/eti__vblex">

The '/' is used to demarcate where the stems (the parts between the <l> </l> tags) are added to.

Then the inflection for first person singular:

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

The 'im' denotes the ending (as in 'vidim'), it is necessary to add 'eti' to the <r> section, as this will be chopped off by the definition. The rest is fairly straightforward, 'vblex' is lexical verb, 'pri' is present indicative tense, 'p1' is first person and 'sg' is singular. We can also add the plural which will be the same, except 'imo' instead of 'im' and 'pl' instead of 'sg'.

After this we need to add a lemma, paradigm mapping to the main section:

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

Note: the content of is the root, not the lemma.

Thats the work on the Serbo-Croatian dictionary done for now. Lets compile it then test it.

$ 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>$

Ok, so now we do the same for the English dictionary (remember to add the same symbol definitions here as you added to the Serbo-Croatian one).

The paradigm is:

<pardef n="s/ee__vblex">

because the past tense is 'saw'. Now, we can do one of two things, we can add both first and second person, but they are the same form. In fact, all forms (except third person singular) of the verb 'to see' are 'see'. So instead we make one entry for 'see' and give it only the 'pri' symbol.

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

and as always, an entry in the main section:

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

Then lets save, recompile and test:

$ 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>$

Now for the obligatory entry in the bilingual dictionary:

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

(again, don't forget to add the sdefs from earlier)

And recompile:

$ 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

Now to test:

$ 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>$^@

We get the analysis passed through correctly, but when we try and generate a surface form from this, we get a '#', like below:

$ 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\@

This '#' means that the generator cannot generate the correct lexical form because it does not contain it. Why is this?

Basically the analyses don't match, the 'see' in the dictionary is see<vblex><pri>, but the see delivered by the transfer is see<vblex><pri><p1><sg>. The Serbo-Croatian side has more information than the English side requires. You can test this by adding the missing symbols to the English dictionary, and then recompiling, and testing again.

However, a more paradigmatic way of taking care of this is by writing a rule. So, we open up the rules file (apertium-sh-en.trules-sh-en.xml in case you forgot).

We need to add a new category for 'verb'.

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

We also need to add attributes for tense and for person. We'll make it really simple for now, you can add p2 and p3, but I won't in order to save space.

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

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

We should also add an attribute for verbs.

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

Now onto the rule:

<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>

Remember when you tried commenting out the 'clip' tags in the previous rule example and they disappeared from the transfer, well, thats pretty much what we're doing here. We take in a verb with a full analysis, but only output a partial analysis (lemma + verb tag + tense tag).

So now, if we recompile that, we get:

$ 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>$^@

and:

$ 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\@

Try it with 'vidimo' (we see) to see if you get the correct output.

Now try it with "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\@


See also[edit]