Kiel aldoni novan lingvoparon

From Apertium
Revision as of 22:20, 16 December 2009 by 95.25.36.204 (talk) (→‎El kio konsistas lingva duo?: forigis erar·areton)
Jump to navigation Jump to search

Ĉi tiu paĝo estas tradukata. Bonvolu helpi!

Tiu dokumento priskribas kiel oni komencas aldoni novan lingvan duon por la maŝintraduka sistemo de Apertium komencante de nenio.

La dokumento ne antaŭsupozas ian scion de lingvoscienco, aŭ maŝintraduko preter ke vi povas distingi inter nomoj, verboj, prepozicioj k.t.p.

Enkonduko

Apertium estas, kiel vi eble jam komprenis, maŝintradukan sistemon. Nu, ne tute; ĝi estas maŝintraduka estrado. Ĝi provizas motoron kaj ilaron, kiujn vi povas uzi por krei vian propran maŝintradukajn sistemojn. Vi devas sole provizi la datumojn. La datumoj je baza nivelo, konsistas el tri vortaroj kaj iuj regoj (por reordoni vortojn kaj aliajn gramatikajn aferojn).

Por pli detala enkonduko pri kiel ĝi funkcias, vi povas trovi iujn bonegajn artikolojn ĉe la projekta retejo apertium.sourceforge.net.

Vi bezonos

  • lttoolbox (>= 3.0.0)
  • libxml utils (xmllint etc.)
  • apertium (>= 3.0.0)
  • teksta redaktilo (aŭ specialiga XML redaktilo se vi preferas ĝin)

Tiu dokumento ne priskribas kiel oni instalas ĉi tiujn enpakojn. Por pli informo pri tio, bonvolu rigardu la dokumentadan parton de la Apertium retejo.

El kio konsistas lingva duo?

La Apertium maŝintraduka sistemo estas de la malprofunda-transira tipo. Tio simple signifas ke ĝi uzas vortarojn kaj malprofundajn transigajn regularojn. Malprofunda transiro estas malsama ol "profunda transiro" pro tio ke ĝi ne faras plenan sintaksan analizon; la reguloj estas tipe operacioj sur grupoj de leksikaj unuoj, anstataŭ operacioj sur analizilaj arboj. Je baza nivelo, estas tri ĉefaj vortaroj:

  1. La morfema vortaro por lingvo xx: tiu ĉi enhavas la deklinaciajn regulojn de lingvo xx. En tiu ĉi ekzemplo, ĝi nomiĝas apertium-sh-en.sh.dix
  2. La morfema vortaro por lingvo yy: tiu ĉi enhavas la deklinaciajn regulojn de lingvo yy. En tiu ĉi ekzemplo, ĝi nomiĝas apertium-sh-en.en.dix
  3. Dulingva vortaro: ĝi enhavas rilatoj inter la vortoj kaj simboloj de la du lingvoj. En tiu ekzemplo, ĝi nomiĝas apertium-sh-en.sh-en.dix

Por traduka duo, oni povas uzi ambaŭ lingvoj kiel fonto aŭ celo por traduki.

Ekzistas ankaŭ du dosieroj por transiraj reguloj. Tiuj ĉi estas la reguloj kiuj priskribas vorta reordonado en frazoj: ekzemple chat noir -> kato nigra -> nigra kato. Ĝi priskribas ankaŭ la akordo de sekso, numero, k.t.p. Oni povas ankaŭ uzi la reguloj por enmeti aŭ forviŝi leksikajn erojn, priskribota malfrue. Tiuj ĉi dosieroj estas:

  • Transiraj reguloj por lingvo xx al lingvo yy: tiu ĉi dosiero enhavas reguloj por ŝanĝi lingvon xx al lingvon yy. En tiu ekzemplo, ĝi estos: apertium-sh-en.trules-sh-en.xml
  • Transiraj reguloj por lingvo yy al lingvo xx: tiu ĉi dosiero enhavas reguloj por ŝanĝi lingvon yy al lingvon xx. En tiu ekzemplo, ĝi estos: apertium-sh-en.trules-en-sh.xml

Multaj lingvaj duoj nuntempe disponigitaj havas ankaŭ aliajn dosierojn, sed ni ne priskribas tiujn dosierojn tie ĉi. Oni bezonas sole la menciitajn dosierojn por krei funkciadan sistemon.

Lingva duo

Oni povus vidi per la dosieraj nomoj ke tiu ĉi klarigo uzas la ekzemplon pri la traduko de serba-kroata al angla por klarigi kiel oni kreas bazan sistemon. Tiu ĉi duo ne estas ideala, pro tio ke la Apertium sistemo funkcias pli bone por pli proksime parencaj lingvoj; por la simplaj ekzemploj en tiu ĉi dokumento, ne gravas.

Mallonga noto pri terminoj

Estas numero da terminoj kiuj oni devas kompreni antaŭ kontinui.

La unua estas lemo. Lemo estas la citaĵa formo de vorto. Ĝi estas la vorto sen ia gramatika informaĵo. Ekzemple, la lemo de la vorto katojn estas kato. En Esperanto, substantivoj estas tipe en la singulara, nominativa formo. Por verboj, la lemo estas la infinitivo sen -i; ekzemple la lemo de amis estas am.

La dua estas simbolo. En la kunteksto de la Apertium sistemo, simbolo signifas gramatikan etikedon. La vorto katoj estas plurala substantivo; do ĝi havos substantivan simbolon kaj pluralan simbolon. Je la enigo kaj eligo de Apertium modjuloj, tiuj etikedoj aperas inter angulaj krampoj, kiel sekve:

  • <n>; por substantivo.
  • <pl>; por plurala.

Aliaj ekzemploj de simboloj estas <sg>; singulara, <p1> unua persono, <pri> indika estanteco, k.t.p. Simbolo inter krampoj nomiĝas ankaŭ etikedo. Estas notinda ke en multaj da la nuntempe disponigitaj lingvaj duoj, la simbolaj difinoj estas akronimoj aŭ mallongigitoj de katalunaj vortoj. Ekzemple, vbhaver devenas el vb (verbo) kaj haver ("havi" en kataluna). Simboloj estas difinitaj inter <sdef> etikedoj kaj uzitaj inter <s> etikedojn.

La tria vorto estas paradigmo. En la kunteksto de la Apertiuma sistemo, paradigmo priskribas la fleksion de vortaj aroj. En la morfema vortaro, lemo (vidu supre) estas ligita al paradigmo kiu priskribas la fleksion de la lemo; do oni ne devas provizas ĉiujn finaĵojn de la lemo.

Konsideru la sekvan ekzemplon kiu montras la utilon de tiu ĉi skemo: oni volas konservi la anglajn adjektivojn happy kaj lazy; anstataŭ konservi du tre similajn vortajn arojn kiel:

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

oni simple konservas la ŝablonon de unu (ekzemple happy) kaj tiam signifas ke "lazy fleksias kiel happy", kaj "friendly fleksias kiel happy", "naughty fleksias kiel happy" k.t.p. En tiu ĉi ekzemplo, happy estas la ŝablono aŭ paradigmo kiu priskribas la fleksion de la aliaj vortoj. La preciza priskribo de la paradigma difino estas baldaŭ priskribota. Paradigmoj estas difinitaj inter <pardef> etikedoj, kaj uzita inter <par> etikedoj.

Kiel komenci

Unulingvaj vortaroj

Ni komencu per fari nian unuan fontlingvan vortaron. La vortaro estas XML dosiero. Ruligu vian tekstilon kaj tajpu la sekvajn:

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

</dictionary>

Nu, la dosiero difinas ke ni volas komenci vortaron. Por fari ĝin utilan, ni devas aldoni iujn enskribigojn. La unua estas la alfabeto: tiu ĉi difinas la signaron kiun oni uzos en la vortaro (serba-kroata tiukaze). Ĝi aperos kiel la sekvajn (enhavita ĉiujn da la signoj en la serba-kroata alfabeto)

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

Metu la alfabeto malsupre de la <dictionary> etikedo.

Sekve, ni devas difini iujn simbolojn. Ni komencu per la simplaj aĵoj: singularaj (sg) kaj pluralaj (pl) substantivoj (n):

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

La simbolaj nomoj ne devas esti tiel malgrandaj. Fakte, oni povas plene skribi tiujn ĉi. Tamen, vi ofte tajpos tiujn ĉi, do estas prudenta mallongigi.

Bedaŭrinde, ĝi ne estas tiel simpla. Substantivoj en serba-kroata fleksias laŭ pli ol sole numero; ili fleksias ankaŭ laŭ genro kaj kazo. Tamen, ni alprenu por tiu ekzemplo ke la substantivo estas vira kaj en la nominativa kazo (kompleta ekzemplo troviĝas je la fino de tiu ĉi dokumento).

Sekve, ni devas difini parto por la paradigmoj:

<pardefs>

</pardefs>

kaj vortara parto:

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

</section>

Estas du tipoj de partoj:

  1. Standarda parto kiu enhavas vortojn, enklitojn (kiuj estas tipoj de postafiksoj), k.t.p.,
  2. Nestata parto kiu tipe enhavas interpunkcio k.t.p. Ni ne havas nestatn parton tie ĉi, kvankam ni vidos ĝin pli poste.

Do, nia dosiero devus nun aperi iom kiel:

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

Nun ni havas la vortara ostaro kaj ni povas komenci per aldoni substantivon. Ni uzu 'gramofon' (kiuj signifas 'gramofono').

Pro tio ke ni havas neniun paradigmon, ni devas difini paradigmon.

Memoru ke ni alprenas ke substantivoj havas virajn genrojn kaj nominativajn kazojn. La singulara formo de la substantivo estas 'gramofon' kaj la plurala estas 'gramofoni'. Do:

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

Rimarku: la '<l/>' (egalvalora ol <l></l>) signifas ke ne estas pluaj aĵoj kiuj estas aldonota al la radiko de la singulara.

Tio ĉi eble ŝajnas kiel iom longa maniero por priskribi ĝin, sed estas bonaj rezonoj kaj ĝi iĝas baldaŭ pli naturan. Vi eble scivolas kion signifas la <e>,

, <l> kaj <r>. Nu:

  • e, signifas enskribigo.
  • p, signifas duon ("pair" en angla).
  • l, signifas maldekstro ("left" en angla).
  • r, signifas dekstro ("right" en angla).

Kiel dekstro kaj maldekstro? Nu, la morfemaj vortaroj estas kompilota al finiaj ŝtataj maŝinoj. Kompili tiujn ĉi de maldekstro al dekstro kreas analizojn el vortoj, kaj de dekstro al maldekstro kreas vortojn el analizoj. Ekzemple:

* gramofoni (maldekstro al dekstro) gramofon<n><pl> (analizo)
* gramofon<n><pl> (dekstro al maldekstro) gramofoni (vorto)

Nun, ni ĵus difinis paradigmon kaj ni devas ligi ĝin al sia lemo, gramafon. Ni metu tiun ĉi en la parto kiun ni difinis.

Oni devas meti la sekvan enskribon en </dictionary>

Nun ni devas aldoni enskribon por traduki inter du vortoj. Io kiel:

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

Pro tio ke ekzistas multaj da tiuj enskriboj, oni skribas ĝin je unu linio por faciligi lego de tiu ĉi dosiero. Denove, uzante la 'l' kaj 'r' ĉu ne? Nu, oni kompilas ĝin maldekstre al dekstre por fari la serba-kroatan → anglan vortaron kaj dekstre al maldekstre por fari la anglan → serba-kroatan vortaron.

Do, kiam vi faris ĝin, ruligu la sekvitajn ordonojn:

$ 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

Por generi la morfemajn analizilojn (automorf), la morfemajn generilojn (autogen) kaj la vortaj interrilataj tabloj (autobil), la "bil" estas por "bilingual" (t.e. dulingva).

Transiraj reguloj

Do, nun ni havas du morfemajn vortarojn, kaj dulingvan vortaron. Ni devas sole doni la transirajn regulojn por substantivoj. Transiraj regulaj dosieroj havas siajn proprajn DTD-on (transfer.dtd) kiujn oni povas trovi en la Apertium-a enpako. Se vi bezonas krei regulon, estas ofte bona ideo unue konsideri la regulajn dosierojn de aliaj lingvaj duojn. Oni povas reuzi multe da reguloj inter malsamaj lingvaj duoj. Ekzemple, la regulo malsupre estus utila por iu ajn nul-subjekta lingvo.

Komencu kiel ĉiuj da la aliaj kun baza ostaro:

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

</transfer>

At the moment, because we're ignoring case, we just need to make a rule that takes the grammatical symbols input and outputs them again.

We first need to define categories and attributes. Categories and attributes both allow us to group grammatical symbols. Categories allow us to group symbols for the purposes of matching (for example 'n.*' is all nouns). Attributes allow us to group a set of symbols that can be chosen from. For example ('sg' and 'pl' may be grouped a an attribute 'number').

Lets add the necessary sections:

<section-def-cats>

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

</section-def-attrs>

As we're only inflecting, nouns in singular and plural then we need to add a category for nouns, and with an attribute of number. Something like the following will suffice:

Into section-def-cats add:

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

This catches all nouns (lemmas followed by <n> then anything) and refers to them as "nom" (we'll see how thats used later).

Into the section section-def-attrs, add:

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

and then

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

The first defines the attribute nbr (number), which can be either singular (sg) or plural (pl).

The second defines the attribute a_nom (attribute noun).

Next we need to add a section for global variables:

<section-def-vars>

</section-def-vars>

These variables are used to store or transfer attributes between rules. We need only one for now,

<def-var n="number"/>

Finally, we need to add a rule, to take in the noun and then output it in the correct form. We'll need a rules section...

<section-rules>

</section-rules>

Changing the pace from the previous examples, I'll just paste this rule, then go through it, rather than the other way round.

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

The first tag is obvious, it defines a rule. The second tag, pattern basically says: "apply this rule, if this pattern is found". In this example the pattern consists of a single noun (defined by the category item nom). Note that patterns are matched in a longest-match first. So if you have three rules, the first catches "<prn><vblex><n>", the second catches "<prn><vblex>" and the third catches "<n>", the pattern matched, and rule executed will be the first.

For each pattern, there is an associated action, which produces an associated output, out. The output, is a lexical unit (lu).

The clip tag allows a user to select and manipulate attributes and parts of the source language (side="sl"), or target language (side="tl") lexical item.

Let's compile it and test it. Transfer rules are compiled with:

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

Which will generate a trules-sh-en.bin file.

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:

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

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.

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

Now let's process that with the transfer rule:

$ 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

It will output:

^gramophone<n><pl>$^@
  • '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.

Try commenting out one of these clip statements, recompiling and seeing what happens.

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.

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

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.

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.

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

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

But what about personal pronouns?

Well, thats great, but we're still missing the personal pronoun that is necessary in English. In order to add it in, we first need to edit the English morphological dictionary.

As before, the first thing to do is add the necessary symbols:

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

Of the two symbols, prn is pronoun, and subj is subject (as in the subject of a sentence).

Because there is no root, or 'lemma' for personal subject pronouns, we just add the pardef as follows:

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

With 'prsubj' being 'personal subject'. The rest of them (You, We etc.) are left as an exercise to the reader.

We can add an entry to the main section as follows:

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

So, save, recompile and test, and we should get something like:

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

(Note: its in capitals because 'I' is in capitals).

Now we need to amend the 'verb' rule to output the subject personal pronoun along with the correct verb form.

First, add a category (this must be getting pretty pedestrian by now):

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

Now add the types of pronoun as attributes, we might as well add the 'obj' type as we're at it, although we won't need to use it for now:

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

And now to input the rule:

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

This is pretty much the same rule as before, only we made a couple of small changes.

We needed to output:

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

so that the generator could choose the right pronoun and the right form of the verb.

So, a quick rundown:

  • <lit>, prints a literal string, in this case "prpers"
  • <lit-tag>, prints a literal tag, because we can't get the tags from the verb, we add these ourself, "prn" for pronoun, and "subj" for subject.
  • , prints a blank, a space.

Note that we retrieved the information for number and tense directly from the verb.

So, now if we recompile and test that again:

$ 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

Which, while it isn't exactly prize-winning prose (much like this HOWTO), is a fairly accurate translation.

Do rakontu min pri la gramofono (Multvortoj)

Dum 'gramopone' estas angla vorto, ĝi ne estas la pli bona traduko. Oni uzas 'gramophone' tipe por la tre malnova speco kun la nadlo anstataŭ la grifelo kaj nenio plilaŭtigo. Pli bona traduko estus 'record player'. Kvankam oni havas pli ol unu vorto, ni povas trakti ĝin kvazaŭ estas unu vorto per uzi multvortajn (multipalabra) konstruojn.

Ni ne devas tuŝi la serba-kroatan vortaron - sole la anglan kaj dulingvan. Do malfermu ilin.

La pluralo de 'record player' estas 'record players', do ĝi uzas la saman paradigmon kiel 'gramophone' (gramophone__n); ni aldonu sole 's'. Nu, ni sole devu aldoni novan eron al la ĉefa sekcio.

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

La sola aĵo kiu malsamas, estas la uzo de la etikedo, kvankam ĝi ne estas tute novo, pro tio ke ni vidis ĝin je la regla dosiero.

Nu, rekompilu kaj testu laŭ la ortodoksa maniero:

$ 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

Bonege. Granda bono de la uzo de multvortoj estas ke oni povas traduki idiomajn esprimojn laŭvorte. Ekzemple, la angla frazo "at the moment" tradukus al serba-kroata kiel "trenutno"('trenutak' = moment kaj 'trenutno' estas adverba formo) — ne estus ebla traduki ĝin vorte-per-vorte al serba-kroata.

Dealing with minor variation

Serbo-Croatian typically has a few ways of writing each word because of dialectal variation. It has a cool phonetic writing system so you write how you speak. For example, people speaking in Ijekavian would say "rječnik", while someone speaking Ekavian would say "rečnik", which reflects the differences in pronunciation of the proto-Slavic vowel yat.

Analysis

There should be a fairly easy way of dealing with this, and there is, using paradigms again. Paradigms aren't only used for adding grammatical symbols, but they can also be used to replace any character/symbol with another. For example, here is a paradigm for accepting both "e" and "je" in the analysis. The paradigm should, as with the others go into the monolingual dictionary for Serbo-Croatian.

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

Then in the "main section":

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

This only allows us to analyse both forms however... more work is necessary if we want to generate both forms.

Generation

See also