Difference between revisions of "Crearea unui dictionar folosind HFST"

From Apertium
Jump to navigation Jump to search
 
(23 intermediate revisions by 2 users not shown)
Line 1: Line 1:
{{TOCD}}
{{TOCD}}
:''Pentru mai multe informaţii despre instalarea formatului HFST, faceţi click pe următorul link: [[HFST]]''
:''Pentru mai multe informaţii despre instalarea formatului HFST, apăsaţi [[HFST|aici]].''


This page is going to describe how to start a new language with [[HFST]]. There are some great references out there to the [[lexc]] and [[twol]] formalisms, for example the [http://www.fsmbook.com FSMBook], but a lot of them deal with the proprietary Xerox implementations, not the free HFST implementation.
Această pagină va prezenta cum creaţi un nou dicţionar folosind [[HFST]]. Se pot găsi şi referinţe foarte utile cu privire la formalismele [[lexc]] şi [[twol]], precum [http://www.fsmbook.com FSMBook], dar majoritatea lor folosesc implementaţia Xerox, nu cea gratuită oferită de HFST.


Deşi formalismele actuale sunt mai mult sau mai puţin asemănătoare, comenzile folosite pentru compilarea lor nu sunt tot timpul
While the actual formalisms are more or less identical, the commands used to compile them are not necessarily the same. HFST has a much more Unix-compatible philosophy. So we're going to take advantage of this. As most Indo-European languages, and isolating languages can be dealt with fairly easily in [[lttoolbox]], we're going to deal with a language that is not from this family, and one that has more complex morphology that isn't easily dealt with in [[lttoolbox]].
aceleași. HFST este bazat pe compatibilitatea cu sistemele de operare Unix. Noi vom profita de acest avantaj. Deoarece la majoritatea limbilor indo-europene şi cele simpliste pot fi tratate cu uşurinţă de [[lttoolbox]], noi vom încerca să abordăm o limbă care nu face parte din această familie, una care are o morfologie complexă şi nu poate fi tratată cu uşurinţă de [[lttoolbox]].


==Preliminaries==
==Introducere==


Un [http://wiki.apertium.org/wiki/Morphological_dictionaries#Transducers transductor morfologic] HFST are două fişiere cu reguli, unul dintre ele este <code>lexc</code>. Acesta defineşte modul în care sunt formate cuvintele din [http://ro.wikipedia.org/wiki/Morfem morfeme]. De exemplu, cuvântul <code>lup + i</code> devine <code>lupi</code>.
A morphological transducer in HFST has two principle files, one is a <code>lexc</code> file. This defines how morphemes in the language are joined together, ''morphotactics''. The other file can be a <code>twol</code> (two-level rules) or <code>xfst</code> (sequential rewrite rules) file. These describe what changes happen when these morphemes are joined together, ''morphographemics'' (or ''morphophonology''). For example,
Cel de-al doilea fişier poate fi unul <code>twol</code> (two-level rules) sau unul <code>xfst</code> (reguli de rescriere secvenţiale). Acestea prezintă ce se întâmplă când morfemele formează cuvântul. Ca exemplu poate fi folosit <code>lup<n><pl></code> → <code>lup + i</code>.


Noi vom lucra pe această pagină cu tipul <code>twol</code>, cel cu reguli pe două nivele. Dacă sunteţi interesat de <code>xfst</code>, puteţi găsi un [http://foma.sourceforge.net/dokuwiki/doku.php?id=wiki:morphtutorial tutorial] pe [Foma această pagină].
:Morphotactics: <code>wolf<n><pl></code> → <code>wolf + s</code>
:Morphographemics: <code>wolf + s</code> → <code>wolves</code>


În următoarele secţiuni vom începe cu vocabularul (fişierul <code>lexc</code>), iar apoi vom trece la fişierul <code>twol</code>.
Here we're going to deal with <code>twol</code>, the two-level rules. If you're interested in <code>xfst</code>, there is a nice [http://foma.sourceforge.net/dokuwiki/doku.php?id=wiki:morphtutorial tutorial] on the [[Foma]] site.


Mai întâi este necesar să compilaţi [[Hfst#Compiling_HFST3|HFST3]].
In the next sections we're going to start with the lexicon (<code>lexc</code> file) then progress onto the morphographemics (<code>twol</code> file).


==Limba==
Make sure you have [[Hfst#Compiling_HFST3|HFST3]] compiled.


Limba pe care o vom folosi este cea vorbită în Turkmenistan, o limbă derivată din cea turcă. Vom lucra pe perechea de limbi turcă-turkmenistană. Vom încerca să schimbăm numărul şi cazul substantivelor. Substantivul în turkmenistană poate avea şase cazuri, 2 genuri şi posesiv. Sufixele pot avea forme diferite în funcţie de sfârşitul cuvântului de bază: dacă e vocală sau consoană.
==The language==


===Armonia vocalică===
The language we're going to model today &mdash; well, start to model &mdash; is Turkmen, a Turkic language spoken in Turkmenistan. The language pair we will supposedly be working on is Turkish--Turkmen. We're going to try and model the basic inflection (number, case) of the category of nouns. The basic inflection for Turkmen nouns is: Six cases, two numbers, and possessive. Suffixes can have different forms depending on if they are attached to a vowel ending stem, or a consonant ending stem.


Simplificând mult, deoarece <ref>Acest subiect este foarte complicat, dar pentru un exemplu didactic, este de ajuns</ref>, se poate spune că în limba turkmenistană cuvintele de bază pot fi de două tipuri: care conţin [http://ro.wikipedia.org/wiki/Vocal%C4%83_posterioar%C4%83 vocale superioare] sau conţin [[http://ro.wikipedia.org/wiki/Vocal%C4%83_anterioar%C4%83 vocale anterioare]]. De exemplu ''mugallym'' "profesor" are doar vocale anterioare, iar ''kädi'' "dovleac" are doar vocale posterioare. Vocalele anterioare sunt: ''a, y, o,'' şi ''u''. Cele posterioare sunt: '' ä, e, i, ö,'' şi ''ü''.
===Vowel harmony===


Deci, când adăugam unui cuvânt de bază un sufix, trebuie să ştim ce tip de vocale conţine cuvântul pentru a alege vocala potrivită pentru sufix.
Simplifying a lot,<ref>This is actually supercomplicated, but for this didactic example, it'll do</ref> we can say that stems in Turkmen can be one of two types, back-vowel stems, or front-vowel stems. Back-vowel stems, such as ''mugallym'' "teacher" only have back vowels, and front-vowel stems, such as ''kädi'' "pumpkin" have only front vowels. The back vowels in Turkmen are: ''a, y, o,'' and ''u''. The front vowels are: '' ä, e, i, ö,'' and ''ü''.


===Numărul===
So, when adding a suffix to a stem, we need to know what vowels are in the stem in order to choose the right vowel to put in the suffix.


Numărul în turkmenistană poate să fie singular (în cazurile în care nu prezintă sufix) sau plural, unde sufixul este ''-lar'' sau ''-ler''. Primul este folosit pentru cuvintele cu vocale anterioare, iar cel de-al doilea este folosit pentru cuvintele cu vocale posterioare.
===Number===


===Cazurile===
Number in Turkmen can either be undefined (where there is no suffix) or plural, where the suffix is ''-lar'' or ''-ler''. The first is used with back vowels, and the second with front vowels.


Noi am folosit o metodă compactă pentru a prezenta sufixele pentru cazuri. Între ''{'' şi ''}'' se află vocalele care pot fi folosite în sufixe, iar între ''('' şi '')'' sunt [http://en.wikipedia.org/wiki/Epenthetic sunete adăugate].
===Case===

We use a more compact representation below to show the suffixes for case. In between ''{'' and ''}'' are vowel alternations in the suffixes, and in between ''('' and '')'' are [http://en.wikipedia.org/wiki/Epenthetic epentheses].


{|class=wikitable
{|class=wikitable
! Case !!colspan=2| Suffix !! Usage !!colspan=2| Example
! Caz !!colspan=2| Sufix !! Utilizare !!colspan=2| Exemple
|-
|-
! !! V !! C !! !! V !! C
! !! V !! C !! !! V !! C
|-
|-
| Nominative || || || Indicates the subject of the sentence || pagta || gazan
| Nominativ || || || Subiectul propoziţiei || pagta || gazan
|-
|-
| Genitive || ''-n{y,i,u,ü}ň'' || ''-{y,i,u,ü}ň'' || Indicates possession || pagta<u>nyň</u> || gaza<u>nyň</u>
| Genitiv || ''-n{y,i,u,ü}ň'' || ''-{y,i,u,ü}ň'' || Arată posesiunea || pagta<u>nyň</u> || gaza<u>nyň</u>
|-
|-
| Dative || ''-{a,ä} , -n{a,e}'' || ''-{a,e}'' || Indirect object (directed action) || pagta || gazan<u>a</u>
| Dativ || ''-{a,ä} , -n{a,e}'' || ''-{a,e}'' || Complement indirect || pagta || gazan<u>a</u>
|-
|-
| Accusative || ''-n{y,i}'' || ''-{y,i}'' || Direct object || pagta<u>ny</u> || gaza<u>ny</u>
| Acuzativ || ''-n{y,i}'' || ''-{y,i}'' || Complement direct || pagta<u>ny</u> || gaza<u>ny</u>
|-
|-
| Inessive || ''-(n)d{a,e}'' || ''-d{a,e}'' || Time/place || pagta<u>da</u> || gazan<u>da</u>
| Inesiv || ''-(n)d{a,e}'' || ''-d{a,e}'' || Timp/loc || pagta<u>da</u> || gazan<u>da</u>
|-
|-
| Instrumental || ''-(n)d{a,e}n'' || ''-d{a,e}n'' || Origin || pagta<u>dan</u> || gazan<u>dan</u>
| Instrumental || ''-(n)d{a,e}n'' || ''-d{a,e}n'' || Prin intermediul acestuia subiectul face acţiunea || pagta<u>dan</u> || gazan<u>dan</u>
|-
|-
|}
|}


===Full paradigm===
===Alte exemple===


Notă: Acestea nu includ cazul posesiv.
Note: This does not include the possessive.


{|class=wikitable
{|class=wikitable
!colspan=3|''maşgala'' "family"
!colspan=3|''maşgala'' "familie"
|-
|-
! Case !! Singular !! Plural
! Caz !! Singular !! Plural
|-
|-
| '''Nominative''' || maşgala || maşgalalar
| '''Nominativ''' || maşgala || maşgalalar
|-
|-
| '''Genitive''' || maşgalanyň || maşgalalaryň
| '''Genitiv''' || maşgalanyň || maşgalalaryň
|-
|-
| '''Dative''' || maşgala || maşgalalara
| '''Dativ''' || maşgala || maşgalalara
|-
|-
| '''Accusative''' || maşgalany || maşgalalary
| '''Acuzativ''' || maşgalany || maşgalalary
|-
|-
| '''Inessive''' || maşgalada || maşgalalarda
| '''Inesiv''' || maşgalada || maşgalalarda
|-
|-
| '''Instrumental''' || maşgaladan || maşgalalardan
| '''Instrumental'''|| maşgaladan || maşgalalardan
|-
|-
|}
|}


{|class=wikitable
{|class=wikitable
!colspan=3|''esger'' "soldier"
!colspan=3|''esger'' "soldat"
|-
|-
! Case !! Singular !! Plural
! Caz !! Singular !! Plural
|-
|-
| '''Nominative''' || esger || esgerler
| '''Nominativ''' || esger || esgerler
|-
|-
| '''Genitive''' || esgeriň || esgerleriň
| '''Genitiv''' || esgeriň || esgerleriň
|-
|-
| '''Dative''' || esgere || esgerlere
| '''Dativ''' || esgere || esgerlere
|-
|-
| '''Accusative''' || esgeri || esgerleri
| '''Acuzativ''' || esgeri || esgerleri
|-
|-
| '''Inessive''' || esgerde || esgerlerde
| '''Inesiv''' || esgerde || esgerlerde
|-
|-
| '''Instrumental''' || esgerden || esgerlerden
| '''Instrumental''' || esgerden || esgerlerden
Line 98: Line 97:
|}
|}


==Lexicon==
==Vocabularul==


So, after going through the little description above, let's start with the lexicon. The file we're going to make is called <code>apertium-tr-tk.tk.lexc</code>, and it will contain the lexicon of the transducer. So open up your text editor.
Deci, după descrierea de mai sus, începem cu vocabularul (lexicon în limba engleză). Vom crea un fişier numit <code>apertium-tr-tk.tk.lexc</code>, care va conţine vocabularul transductorului. Deschideţi editorul de texte.


===The basics===
===Începutul===


The first thing we need to define are the tags that we want to produce. In [[lttoolbox]], this is done through the <code><sdefs></code> section of the <code>.dix</code> file.
Primul lucru pe care trebuie îl facem este definirea etichetelor pe care vrem să le folosim. În [[lttoolbox]], aceasta este făcută în secţiunea <code><sdefs></code> a fişierului <code>.dix</code>.


<pre>
<pre>
Multichar_Symbols
Multichar_Symbols


%<n%> ! Noun
%<n%> ! Substantiv
%<nom%> ! Nominative
%<nom%> ! Nominativ
%<pl%> ! Plural
%<pl%> ! Plural
</pre>
</pre>


The symbols <code>&lt;</code> and <code>&gt;</code> are reserved in <code>lexc</code>, so we need to escape them with <code>%</code>
Simbolurile <code>&lt;</code> şi <code>&gt;</code> sunt rezervate în <code>lexc</code>, deci trebuie le introducem prin <code>%</code>.


We also need to define a <code>Root</code> lexicon, which is going to point to a list of stems in the lexicon <code>NounStems</code>. The <code>Root</code> lexicon is analagous to the <code><section id="main" type="standard"></code> in [[lttoolbox]]:
De asemenea, trebuie definim un vocabular principal (<code>Root</code>), care va cuprinde mai multe cuvinte ale vocabularului <code>NounStems</code>. Vocabularul <code>Root</code> este echivalent cu <code><section id="main" type="standard"></code> din [[lttoolbox]]:


<pre>
<pre>
Line 126: Line 125:
</pre>
</pre>


Acum vom adăuga cele două cuvinte ale noastre:
Now let's add our two words:


<pre>
<pre>
LEXICON NounStems
LEXICON NounStems


maşgala Ninfl ; ! "family"
maşgala Ninfl ; ! "familie"
esger Ninfl ; ! "soldier"
esger Ninfl ; ! "soldat"
</pre>
</pre>


First we put the stem, then we put the ''paradigm'' (or ''continuation class'') that it belongs to, in this case <code>Ninfl</code>, and finally, in a comment (the comment symbol is <code>!</code>) we put the translation.
Prima dată scriem cuvântul de bază, apoi adăugăm categoria din care face parte, în cazul nostru <code>Ninfl</code>, şi, în final, adăugăm un comentariu (folosind simbolul <code>!</code>) în care scriem traducerea.


Apoi definim principala regulă de modificare a cuvântului, prin etichetarea cuvântului de bază cu <code><n></code> pentru a indica faptul că e vorba de substantive:
And define the most basic of inflection, that is, tagging the bare stem with <code><n></code> to indicate a noun:


<pre>
<pre>
Line 145: Line 144:
</pre>
</pre>


This <code>LEXICON</code> should go ''before'' the <code>NounStems</code> lexicon. The <code>#</code> symbol is the end-of-word boundary. It is very important to have this, as it tells the transducer where to stop.
Acest <code>LEXICON</code> ar trebui pus ''înaintea'' vocabularului <code>NounStems</code>. Simbolul <code>#</code> indică sfârşitul cuvântului. Este important îl includem, pentru că îi spune transductorului unde se oprească.


===Compiling===
===Compilarea===


So, now we've got our basic lexicon, let's compile it and test it. We compile with <code>hfst-lexc</code>:
Deci, acum avem vocabularul principal, putem să-l compilăm şi să-l testăm. Îl putem compila folosind <code>hfst-lexc</code>:


<pre>
<pre>
Line 155: Line 154:
</pre>
</pre>


And we can test it both with <code>hfst-fst2strings</code>:
Şi îl putem testa folosind <code>hfst-fst2strings</code>:


<pre>
<pre>
Line 165: Line 164:
===Continuation lexica===
===Continuation lexica===


So, we've managed to describe that ''maşgala'' and ''esger'' are nouns, but what about the inflection. This is where ''continuation lexica'' come in. These are like ''paradigms'' in [[lttoolbox]].
Am reuşit implementăm ''maşgala'' şi ''esger'' sunt substantive, dar cum rămâne cu schimbarea numărului şi a cazului? Aici intervine ''continuation lexica''. Acestea sunt ca şi ''paradigm-urile'' din [[lttoolbox]], adică legături între atributele substantivului (cazul/numărul/etc.) şi morfemul corespunzătoare acestora.


Principalul mod de a forma cuvintele din morfeme este în limba turkmenistană este:
The basic morphotactics of the Turkmen noun is:


:{{sc|stem}} {{sc|plural?}} {{sc|possessive?}} {{sc|case}} {{sc|copula?}}
:{{sc|Cuvânt de bază}} {{sc|plural?}} {{sc|posesiv?}} {{sc|caz}} {{sc|copulativ?}}


Where <code>?</code> denotes optionality. We're just working with number and case here, so let's describe the inflection, first we can start with number. In the section of the file <code>LEXICON Ninfl</code>, add the following line:
Unde <code>?</code> arată unele sufixe sunt opţionale. Nu e vorba doar de număr şi caz. Pentru a descrie noua formă, trebuie începem cu numărul. În secţiunea <code>LEXICON Ninfl</code> a fişierului, adăugaţi:


<pre>
<pre>
Line 177: Line 176:
</pre>
</pre>


Pare cam complicat! Probabil, dar fiecare parte este necesară. Ele pot fi descrise astfel:
Phew, that looks pretty complicated!! Well, perhaps, but each part has it's reason, let's describe them:


{|class=wikitable
{|class=wikitable
! Part !! Description
! Parte !! Descriere
|-
|-
| <code>%&lt;n%&gt;%&lt;pl%&gt;</code> || The part on the left side defines the analysis, in this case noun, plural. Note, this is in contrast to lttoolbox, where the analysis is usually on the right side.
| <code>%&lt;n%&gt;%&lt;pl%&gt;</code> || În stânga se defineşte analiza, în cazul nostru substantiv, plural. Spre deosebire de HFST, în lttoolbox analiza este definită în dreapta.
|-
|-
| <code>:</code> || The symbol <code>:</code> delimits the left and right sides (or surface side, and lexical side)
| <code>:</code> || Simbolul <code>:</code> delimitează jumătatea stângă de cea dreaptă (sau atributele cuvântului de morfemul corespunzător acestora)
|-
|-
| <code>%&gt;%&gt;l%{A%}r</code> || This is the surface form, which is split into:
| <code>%&gt;l%{A%}r</code> || Aici este prezentat sufixul formei de plural a substantivelor. Poate fi împărţit în:
|-
|-
|&nbsp;&nbsp;&nbsp; <code>%&gt;</code> || The morpheme boundary delimiter (we'll talk about this later, but you put it in between morphemes where changes might happen.
|&nbsp;&nbsp;&nbsp; <code>%&gt;</code> || Delimitatorul de morfeme (vom reveni la acestea mai târziu, dar, în principiu, sunt puse unde între morfeme, în locurile în care ar putea avea loc schimbări).
|-
|-
|&nbsp;&nbsp;&nbsp; <code>l%{A%}r</code> || The surface morpheme, in this case ''-lar'' or ''-ler''
|&nbsp;&nbsp;&nbsp; <code>l%{A%}r</code> || Morfemul corespunzător formei, în cazul nostru''-lar'' sau ''-ler''
|-
|-
|&nbsp;&nbsp;&nbsp; <code>%{A%}</code> || An "archivowel"... a placeholder for a vowel that can be either ''a'' or ''e''
|&nbsp;&nbsp;&nbsp; <code>%{A%}</code> || O "arhivocală"... un înlocuitor pentru o vocală care poate fi ori ''a'', ori ''e''
|-
|-
| <code>#</code> || The end of word boundary
| <code>#</code> || Sfârşitul legăturii
|-
|-
| <code>;</code> || End of line
| <code>;</code> || Sfârşitul liniei
|-
|-
|}
|}


Part of the reason it looks complicated is all of the <code>%</code> symbols. If we remove them it looks far more readable:
Pare complicat mai ales datorită folosirii repetate a simbolului <code>%</code>. Dacă le scoatem devine mult mai lizibil:


<pre>
<pre>
Line 206: Line 205:
</pre>
</pre>


(Totuşi, ele sunt obligatorii)
(You need to have them though)


For comparison, in lttoolbox (using · for morpheme boundary and <s n="A"/> for the {A}) for , this would look something like:
Pentru a face o comparaţie, în lttoolbox (se notează cu simbolul · legătura dintre morfem şi atribute, iar <s n="A"/> este echivalentul lui {A}), aceasta ar arăta cam aşa:


<pre>
<pre>
Line 214: Line 213:
</pre>
</pre>


So, we've added the first of our inflections, the plural. We need to do two things before we can test it. First we need to add <code>%{A%}</code> to the <code>Multichar_Symbols</code> section of the file, so scroll to the top and add it, you should get something like:
Deci, acum am adăugat prima legătură, pluralul. Trebuie mai facem două lucruri înainte de a o testa. În primul rând, trebuie să adăugăm <code>%{A%}</code> la secţiunea fişierului <code>Multichar_Symbols</code>, aşa mergeţi înapoi şi faceţi schimbarea. Ar trebui arate cam aşa:


<pre>
<pre>
Multichar_Symbols
Multichar_Symbols


%<n%> ! Noun
%<n%> ! Substantiv
%<nom%> ! Nominative
%<nom%> ! Nominativ
%<pl%> ! Plural
%<pl%> ! Plural


%{A%} ! Archivowel 'a' or 'e'
%{A%} ! Arhivocală 'a' sau 'e'
</pre>
</pre>


Salvaţi fişierul. Apoi compilaţi din nou:
Now save the file. The next thing we need to do is compile again:


<pre>
<pre>
Line 232: Line 231:
</pre>
</pre>


Şi putem testa:
And then we can test:


<pre>
<pre>
Line 242: Line 241:
</pre>
</pre>


Ok, so this is cool, but it also kind of sucks, these aren't real surface forms. We'll never see ''esger>l{A}r'' in any text. The surface form we're looking for is ''esgerler''. So how do we get that ?
Ok, asta e destul de tare, dar pe de altă parte, acestea nu sunt chiar formele reale. Nu există în niciun text ''esger>l{A}r''. Noi vrem obţinem forma ''esgerler''. Dar cum o putem face?


==Enter <code>twol</code>==
==Folosirea <code>twol</code>==


The idea of <code>twol</code> is to take the surface forms produced by lexc and apply rules to them to change them into real surface forms. So, this is where we change ''-l{A}r'' into ''-lar'' or ''-ler''.
Fişierul <code>twol</code> are rolul de a lua formele produse le lexc şi, prin aplicarea unor reguli, le transforme în forme reale ale cuvintelor. Deci, aici vom schimba ''-l{A}r'' în ''-lar'' sau ''-ler''.


Noi vrem ca dacă acel cuvânt de bază conţine vocale posterioare, atunci dorim să adăugăm terminaţia pentru vocale posterioare, iar dacă conţine vocale anterioare, să adaugăm terminaţia pentru vocale anterioare. În acelaşi timp, dorim să înlăture legătura morfemului.
What we basically want to say is "if the stem contains front vowels, then we want the front vowel alternation, if it contains back vowels then we want the back vowel alternation". And at the same time, remove the morpheme boundary. So let's give it a shot.


We're going to make a new file <code>apertium-tr-tk.tk.twol</code>.
Vom face un nou fişier numit <code>apertium-tr-tk.tk.twol</code>.


Prima dată trebuie să definim alfabetul:
First we need to define the alphabet:


<pre>
<pre>
Line 261: Line 260:
</pre>
</pre>


You don't have to define the upper and lower case on separate lines, but it can help make it clearer.
Nu este neapărat scrieţi literele mari şi mici pe linii separate, dar scriindu-le astfel este mai lizibil.


We also want to define at this point, that whatever happens, we want to remove the morpheme boundaries <code>%&gt;</code> from the surface forms, so add the following line just below the last line of lower case letters, and before the <code>;</code>:
De asemenea, dorim înlăturăm legăturile <code>%&gt;</code> din cuvântul nostru, indiferent de ce s-ar întâmpla, deci adăugaţi următoarea linie sub ultima linie care conţine literele mici, înainte de <code>;</code>:


<pre>
<pre>
Line 269: Line 268:
</pre>
</pre>


Here, the left side is the morphotactic form, and the right side is the surface form. Doing <code>%&gt;:0</code> changes <code>%&gt;</code> into <code>0</code>, which is the same as deleting it. The <code>0</code> symbol is not output.
Aici, partea din stânga este forma primită de la lexc, iar în cea dreaptă este forma pe care o dorim. Comanda <code>%&gt;:0</code> înlocuieşte <code>%&gt;</code> cu <code>0</code>, care e acelaşi lucru cu ştergerea. Simbolul <code>0</code> nu se afişează.


So, the final alphabet section will look like this:
So, the final alphabet section will look like this:
Line 280: Line 279:
</pre>
</pre>


Acum trebuie să definim nişte "seturi" cu care să lucrăm, care, în principiu, au rolul de a numi unele grupe de litere, precum "vocală posterioară" şi "vocală anterioară", pe care le vom folosi mai târziu în reguli:
Next we need to define some "sets" to work with, these are basically for giving mnemonics to features, like "front vowel" and "back vowel" which we want to refer to later in the rules:


<pre>
<pre>
Sets
Sets


Consonant = B Ç D F G H J Ž K L M N Ň P R S Ş T W Z
Consoana = B Ç D F G H J Ž K L M N Ň P R S Ş T W Z
b ç d f g h j ž k l m n ň p r s ş t w z ;
b ç d f g h j ž k l m n ň p r s ş t w z ;
Vowel = A E Ä I O Ö U Ü Y Ý
Vocala = A E Ä I O Ö U Ü Y Ý
a e ä i o ö u ü y ý ;
a e ä i o ö u ü y ý ;
FrontVowel = Ä E I Ö Ü ä e i ö ü ;
VocalaPosterioara = Ä E I Ö Ü ä e i ö ü ;
BackVowel = A Y O U a y o u ;
VocalaAnterioara = A Y O U a y o u ;
NuPosterioară = Consoana VocalaPosterioara %> ;
NonBack = Consonant FrontVowel %> ;
NonFront = Consonant BackVowel %> ;
NuAnterioară = Consoana VocalaAnterioara %> ;
</pre>
</pre>


So now we've got everything set up, to add the rule, there is a new section, <code>Rules</code>:
Acum avem totul pregătit, pentru a adăuga regulile creăm o nouă secţiune: <code>Rules</code>:


<pre>
<pre>
Rules
Rules
"Înlocuirea în cazul vocalelor posterioare"
"Front harmony in suffixes"
%{A%}:e <=> FrontVowel: NonBack:* %>: NonBack:* _ ;
%{A%}:e <=> VocalăPosterioară: NuPosterioară:* %>: NuAnterioară:* _ ;


</pre>
</pre>


Această regulă înlocuieşte {A} cu e dacă ultimele litere sunt orice în afară de vocale anterioare, atunci este o legătură de morfeme, nu sunt vocale anterioare şi există pe undeva o vocală posterioară.
The rule is basically saying: "Substitute {A} with e if the previous letters are anything except back vowels, then there is a morpheme boundary, then there are no back vowels, and at some point there is a front vowel"


Urmează să compilăm regula şi să o testăm:
Next up, to compile the rule and test it:


<pre>
<pre>
Line 321: Line 320:
</pre>
</pre>


===Intersectarea fişierelor===
===With the power of intersecting composition!===


In order to get the final transducer, what we need to do is combine the morphotactic model (<code>lexc</code>) with the morphographemic model (<code>twol</code>). There is a way of doing this called "intersecting composition" which is fairly efficient. There is also a tool in HFST called <code>hfst-compose-intersect</code> which is what we'll be using.
Pentru a obţine transductorul final trebuie combinăm cele două modele din fişierele <code>lexc</code> şi <code>twol</code>. Această operaţie se face prin intermediul unei intersecţii. Intersecţia e realizată folosind comanda <code>hfst-compose-intersect</code> pe care o vom folosi mai departe.


<pre>
<pre>
Line 329: Line 328:
</pre>
</pre>


Now we can test the final transducer:
Acum testăm transductorul final:


<pre>
<pre>
Line 339: Line 338:
</pre>
</pre>


Excelent!! Acum avem formele corecte ale substantivelor.
Great!! We have the desired forms.


==Analysis and generation==
==Analiză şi generare==


The transducer we made above was for generation, but we can't yet use it with <code>hfst-proc</code> because of the format. If we want to use it with <code>hfst-proc</code>, all we need to do is change the format, with the following command:
Transductorul creat de noi avea scopul de a genera şi nu putem folosi <code>hfst-proc</code> datorită formatului. Dacă dorim îl executăm cu <code>hfst-proc</code>, atunci tot ce trebuie facem e schimbăm formatul:


<pre>
<pre>
Line 349: Line 348:
</pre>
</pre>


Acum ar trebui să putem genera ambele plurale:
Now we should be able to generate both of our plurals:


<pre>
<pre>
Line 356: Line 355:
</pre>
</pre>


and
şi


<pre>
<pre>
Line 363: Line 362:
</pre>
</pre>


Dar dacă vrem să analizăm cuvinte? Ei bine, atunci ar trebui să ''inversăm'' transductorul. Aceasta înseamnă schimbarea părţii stângi cu cea dreaptă şi reciproc. Pentru a vedea rezultatele, haideţi să îl inversăm în două etape. În primul rând:
But what if we want to analyse some words ? Well, then we need to ''invert'' the transducer. This is changing the left side to the right side, and the right side to the left side, let's do it in two stages so we can see the results:


<pre>
<pre>
Line 375: Line 374:
</pre>
</pre>


Acum partea stângă arată cuvântul actual, iar cea dreaptă analiza. Apoi, convertim analizatorul pentru a arăta analiza unui singur cuvânt:
As we can see, now the left side is the surface form, and the right side the analysis. Now just to convert the analyser to ''optimised lookup'' format:


<pre>
<pre>
Line 381: Line 380:
</pre>
</pre>


Şi analiza:
And do some analysis:


<pre>
<pre>
Line 391: Line 390:
</pre>
</pre>


==Dacă apar erori==
==Troubleshooting==


Greşeli generale care cauzează erori:
Here is a brief troubleshooting checklist for when you do something, but it isn't working:


* Are all your ''multicharacter symbols'' defined ? Including archivowels/consonants. If you think you added them, triple check. This goes for problems in <code>twol</code> as well as in <code>lexc</code>.
* Aţi definit toate ''multicharacter symbols'', cu tot cu arhivocalele şi consoanele? Dacă ştiţi sunt acolo, mai verificaţi o dată. Această eroare poate apărea atât în fişierul <code>twol</code> cât şi în <code>lexc</code>.


==Notes==
==Notes==
Line 403: Line 402:


[[Category:HFST]]
[[Category:HFST]]
[[Category:Documentation in Romanian]]

Latest revision as of 06:42, 8 April 2013

Pentru mai multe informaţii despre instalarea formatului HFST, apăsaţi aici.

Această pagină vă va prezenta cum să creaţi un nou dicţionar folosind HFST. Se pot găsi şi referinţe foarte utile cu privire la formalismele lexc şi twol, precum FSMBook, dar majoritatea lor folosesc implementaţia Xerox, nu cea gratuită oferită de HFST.

Deşi formalismele actuale sunt mai mult sau mai puţin asemănătoare, comenzile folosite pentru compilarea lor nu sunt tot timpul aceleași. HFST este bazat pe compatibilitatea cu sistemele de operare Unix. Noi vom profita de acest avantaj. Deoarece la majoritatea limbilor indo-europene şi cele simpliste pot fi tratate cu uşurinţă de lttoolbox, noi vom încerca să abordăm o limbă care nu face parte din această familie, una care are o morfologie complexă şi nu poate fi tratată cu uşurinţă de lttoolbox.

Introducere[edit]

Un transductor morfologic HFST are două fişiere cu reguli, unul dintre ele este lexc. Acesta defineşte modul în care sunt formate cuvintele din morfeme. De exemplu, cuvântul lup + i devine lupi. Cel de-al doilea fişier poate fi unul twol (two-level rules) sau unul xfst (reguli de rescriere secvenţiale). Acestea prezintă ce se întâmplă când morfemele formează cuvântul. Ca exemplu poate fi folosit lup<n><pl>lup + i.

Noi vom lucra pe această pagină cu tipul twol, cel cu reguli pe două nivele. Dacă sunteţi interesat de xfst, puteţi găsi un tutorial pe [Foma această pagină].

În următoarele secţiuni vom începe cu vocabularul (fişierul lexc), iar apoi vom trece la fişierul twol.

Mai întâi este necesar să compilaţi HFST3.

Limba[edit]

Limba pe care o vom folosi este cea vorbită în Turkmenistan, o limbă derivată din cea turcă. Vom lucra pe perechea de limbi turcă-turkmenistană. Vom încerca să schimbăm numărul şi cazul substantivelor. Substantivul în turkmenistană poate avea şase cazuri, 2 genuri şi posesiv. Sufixele pot avea forme diferite în funcţie de sfârşitul cuvântului de bază: dacă e vocală sau consoană.

Armonia vocalică[edit]

Simplificând mult, deoarece [1], se poate spune că în limba turkmenistană cuvintele de bază pot fi de două tipuri: care conţin vocale superioare sau conţin [vocale anterioare]. De exemplu mugallym "profesor" are doar vocale anterioare, iar kädi "dovleac" are doar vocale posterioare. Vocalele anterioare sunt: a, y, o, şi u. Cele posterioare sunt: ä, e, i, ö, şi ü.

Deci, când adăugam unui cuvânt de bază un sufix, trebuie să ştim ce tip de vocale conţine cuvântul pentru a alege vocala potrivită pentru sufix.

Numărul[edit]

Numărul în turkmenistană poate să fie singular (în cazurile în care nu prezintă sufix) sau plural, unde sufixul este -lar sau -ler. Primul este folosit pentru cuvintele cu vocale anterioare, iar cel de-al doilea este folosit pentru cuvintele cu vocale posterioare.

Cazurile[edit]

Noi am folosit o metodă compactă pentru a prezenta sufixele pentru cazuri. Între { şi } se află vocalele care pot fi folosite în sufixe, iar între ( şi ) sunt sunete adăugate.

Caz Sufix Utilizare Exemple
V C V C
Nominativ Subiectul propoziţiei pagta gazan
Genitiv -n{y,i,u,ü}ň -{y,i,u,ü}ň Arată posesiunea pagtanyň gazanyň
Dativ -{a,ä} , -n{a,e} -{a,e} Complement indirect pagta gazana
Acuzativ -n{y,i} -{y,i} Complement direct pagtany gazany
Inesiv -(n)d{a,e} -d{a,e} Timp/loc pagtada gazanda
Instrumental -(n)d{a,e}n -d{a,e}n Prin intermediul acestuia subiectul face acţiunea pagtadan gazandan

Alte exemple[edit]

Notă: Acestea nu includ cazul posesiv.

maşgala "familie"
Caz Singular Plural
Nominativ maşgala maşgalalar
Genitiv maşgalanyň maşgalalaryň
Dativ maşgala maşgalalara
Acuzativ maşgalany maşgalalary
Inesiv maşgalada maşgalalarda
Instrumental maşgaladan maşgalalardan
esger "soldat"
Caz Singular Plural
Nominativ esger esgerler
Genitiv esgeriň esgerleriň
Dativ esgere esgerlere
Acuzativ esgeri esgerleri
Inesiv esgerde esgerlerde
Instrumental esgerden esgerlerden

Vocabularul[edit]

Deci, după descrierea de mai sus, să începem cu vocabularul (lexicon în limba engleză). Vom crea un fişier numit apertium-tr-tk.tk.lexc, care va conţine vocabularul transductorului. Deschideţi editorul de texte.

Începutul[edit]

Primul lucru pe care trebuie să îl facem este definirea etichetelor pe care vrem să le folosim. În lttoolbox, aceasta este făcută în secţiunea <sdefs> a fişierului .dix.

Multichar_Symbols

%<n%>   ! Substantiv
%<nom%> ! Nominativ
%<pl%>  ! Plural

Simbolurile < şi > sunt rezervate în lexc, deci trebuie să le introducem prin %.

De asemenea, trebuie să definim un vocabular principal (Root), care va cuprinde mai multe cuvinte ale vocabularului NounStems. Vocabularul Root este echivalent cu <section id="main" type="standard"> din lttoolbox:


LEXICON Root

NounStems ;

Acum vom adăuga cele două cuvinte ale noastre:

LEXICON NounStems

maşgala Ninfl ; ! "familie"
esger Ninfl ;   ! "soldat"

Prima dată scriem cuvântul de bază, apoi adăugăm categoria din care face parte, în cazul nostru Ninfl, şi, în final, adăugăm un comentariu (folosind simbolul !) în care scriem traducerea.

Apoi definim principala regulă de modificare a cuvântului, prin etichetarea cuvântului de bază cu <n> pentru a indica faptul că e vorba de substantive:

LEXICON Ninfl

%<n%>: # ;

Acest LEXICON ar trebui pus înaintea vocabularului NounStems. Simbolul # indică sfârşitul cuvântului. Este important să îl includem, pentru că îi spune transductorului unde să se oprească.

Compilarea[edit]

Deci, acum că avem vocabularul principal, putem să-l compilăm şi să-l testăm. Îl putem compila folosind hfst-lexc:

$ hfst-lexc apertium-tr-tk.tk.lexc > tk-tr.lexc.hfst

Şi îl putem testa folosind hfst-fst2strings:

$ hfst-fst2strings tk-tr.lexc.hfst 
maşgala<n>:maşgala
esger<n>:esger

Continuation lexica[edit]

Am reuşit să implementăm că maşgala şi esger sunt substantive, dar cum rămâne cu schimbarea numărului şi a cazului? Aici intervine continuation lexica. Acestea sunt ca şi paradigm-urile din lttoolbox, adică legături între atributele substantivului (cazul/numărul/etc.) şi morfemul corespunzătoare acestora.

Principalul mod de a forma cuvintele din morfeme este în limba turkmenistană este:

Cuvânt de bază plural? posesiv? caz copulativ?

Unde ? arată că unele sufixe sunt opţionale. Nu e vorba doar de număr şi caz. Pentru a descrie noua formă, trebuie să începem cu numărul. În secţiunea LEXICON Ninfl a fişierului, adăugaţi:

%<n%>%<pl%>:%>l%{A%}r # ;

Pare cam complicat! Probabil, dar fiecare parte este necesară. Ele pot fi descrise astfel:

Parte Descriere
%<n%>%<pl%> În stânga se defineşte analiza, în cazul nostru substantiv, plural. Spre deosebire de HFST, în lttoolbox analiza este definită în dreapta.
: Simbolul : delimitează jumătatea stângă de cea dreaptă (sau atributele cuvântului de morfemul corespunzător acestora)
%>l%{A%}r Aici este prezentat sufixul formei de plural a substantivelor. Poate fi împărţit în:
    %> Delimitatorul de morfeme (vom reveni la acestea mai târziu, dar, în principiu, sunt puse unde între morfeme, în locurile în care ar putea avea loc schimbări).
    l%{A%}r Morfemul corespunzător formei, în cazul nostru-lar sau -ler
    %{A%} O "arhivocală"... un înlocuitor pentru o vocală care poate fi ori a, ori e
# Sfârşitul legăturii
; Sfârşitul liniei

Pare complicat mai ales datorită folosirii repetate a simbolului %. Dacă le scoatem devine mult mai lizibil:

<n><pl>:>l{A}r # ;

(Totuşi, ele sunt obligatorii)

Pentru a face o comparaţie, în lttoolbox (se notează cu simbolul · legătura dintre morfem şi atribute, iar este echivalentul lui {A}), aceasta ar arăta cam aşa:

<e><p><l>·l<s n="A"/>r</l><r><s n="n"/><s n="pl"/></e>

Deci, acum am adăugat prima legătură, pluralul. Trebuie să mai facem două lucruri înainte de a o testa. În primul rând, trebuie să adăugăm %{A%} la secţiunea fişierului Multichar_Symbols, aşa că mergeţi înapoi şi faceţi schimbarea. Ar trebui să arate cam aşa:

Multichar_Symbols

%<n%>   ! Substantiv
%<nom%> ! Nominativ
%<pl%>  ! Plural

%{A%}   ! Arhivocală 'a' sau 'e'

Salvaţi fişierul. Apoi compilaţi din nou:

$ hfst-lexc apertium-tr-tk.tk.lexc > tk-tr.lexc.hfst

Şi putem testa:

$ hfst-fst2strings tk-tr.lexc.hfst 
maşgala<n><pl>:maşgala>l{A}r
maşgala<n>:maşgala
esger<n><pl>:esger>l{A}r
esger<n>:esger

Ok, asta e destul de tare, dar pe de altă parte, acestea nu sunt chiar formele reale. Nu există în niciun text esger>l{A}r. Noi vrem să obţinem forma esgerler. Dar cum o putem face?

Folosirea twol[edit]

Fişierul twol are rolul de a lua formele produse le lexc şi, prin aplicarea unor reguli, să le transforme în forme reale ale cuvintelor. Deci, aici vom schimba -l{A}r în -lar sau -ler.

Noi vrem ca dacă acel cuvânt de bază conţine vocale posterioare, atunci dorim să adăugăm terminaţia pentru vocale posterioare, iar dacă conţine vocale anterioare, să adaugăm terminaţia pentru vocale anterioare. În acelaşi timp, dorim să înlăture legătura morfemului.

Vom face un nou fişier numit apertium-tr-tk.tk.twol.

Prima dată trebuie să definim alfabetul:

Alphabet
 A B Ç D E Ä F G H I J Ž K L M N Ň O Ö P R S Ş T U Ü W Y Ý Z
 a b ç d e ä f g h i j ž k l m n ň o ö p r s ş t u ü w y ý z
 %{A%}:a ;

Nu este neapărat să scrieţi literele mari şi mici pe linii separate, dar scriindu-le astfel este mai lizibil.

De asemenea, dorim să înlăturăm legăturile %> din cuvântul nostru, indiferent de ce s-ar întâmpla, deci adăugaţi următoarea linie sub ultima linie care conţine literele mici, înainte de ;:

 %>:0 

Aici, partea din stânga este forma primită de la lexc, iar în cea dreaptă este forma pe care o dorim. Comanda %>:0 înlocuieşte %> cu 0, care e acelaşi lucru cu ştergerea. Simbolul 0 nu se afişează.

So, the final alphabet section will look like this:

Alphabet
 A B Ç D E Ä F G H I J Ž K L M N Ň O Ö P R S Ş T U Ü W Y Ý Z
 a b ç d e ä f g h i j ž k l m n ň o ö p r s ş t u ü w y ý z
 %{A%}:a %>:0  ;

Acum trebuie să definim nişte "seturi" cu care să lucrăm, care, în principiu, au rolul de a numi unele grupe de litere, precum "vocală posterioară" şi "vocală anterioară", pe care le vom folosi mai târziu în reguli:

Sets

Consoana = B Ç D F G H J Ž K L M N Ň P R S Ş T W Z
           b ç d f g h j ž k l m n ň p r s ş t w z ; 
Vocala =    A E Ä I O Ö U Ü Y Ý 
            a e ä i o ö u ü y ý ;
VocalaPosterioara = Ä E I Ö Ü ä e i ö ü ;  
VocalaAnterioara = A Y O U a y o u ;
NuPosterioară = Consoana VocalaPosterioara %> ;
NuAnterioară  = Consoana VocalaAnterioara %> ; 

Acum că avem totul pregătit, pentru a adăuga regulile creăm o nouă secţiune: Rules:

Rules
  
"Înlocuirea în cazul vocalelor posterioare"
%{A%}:e <=> VocalăPosterioară: NuPosterioară:* %>: NuAnterioară:* _ ;

Această regulă înlocuieşte {A} cu e dacă ultimele litere sunt orice în afară de vocale anterioare, atunci este o legătură de morfeme, nu sunt vocale anterioare şi există pe undeva o vocală posterioară.

Urmează să compilăm regula şi să o testăm:

$ hfst-twolc -R -i apertium-tr-tk.tk.twol -o tk-tr.twol.hfst
Reading input from tk.twol.
Writing output to tk.twol.hfst.
Reading alphabet.
Reading sets.
Reading rules and compiling their contexts and centers.
Compiling and storing rules.
Compiling rules.
Storing rules.

Intersectarea fişierelor[edit]

Pentru a obţine transductorul final trebuie să combinăm cele două modele din fişierele lexc şi twol. Această operaţie se face prin intermediul unei intersecţii. Intersecţia e realizată folosind comanda hfst-compose-intersect pe care o vom folosi mai departe.

$ hfst-compose-intersect -1 tr-tk.lexc.hfst -2 tr-tk.twol.hfst -o tr-tk.autogen.hfst

Acum să testăm transductorul final:

$ hfst-fst2strings tr-tk.autogen.hfst
maşgala<n>:maşgala
maşgala<n><pl>:maşgalalar
esger<n>:esger
esger<n><pl>:esgerler

Excelent!! Acum avem formele corecte ale substantivelor.

Analiză şi generare[edit]

Transductorul creat de noi avea scopul de a genera şi nu putem folosi hfst-proc datorită formatului. Dacă dorim să îl executăm cu hfst-proc, atunci tot ce trebuie să facem e să schimbăm formatul:

$ hfst-fst2fst -O -i tr-tk.autogen.hfst -o tr-tk.autogen.hfst.ol

Acum ar trebui să putem genera ambele plurale:

$ echo "^maşgala<n><pl>$" | hfst-proc -g tr-tk.autogen.hfst.ol
maşgalalar

şi

$ echo "^esger<n><pl>$" | hfst-proc -g tr-tk.autogen.hfst.ol
esgerler

Dar dacă vrem să analizăm cuvinte? Ei bine, atunci ar trebui să inversăm transductorul. Aceasta înseamnă schimbarea părţii stângi cu cea dreaptă şi reciproc. Pentru a vedea rezultatele, haideţi să îl inversăm în două etape. În primul rând:

$ hfst-invert -i tr-tk.autogen.hfst -o tk-tr.automorf.hfst

$ hfst-fst2strings tk-mor.hfst
maşgala:maşgala<n>
maşgalalar:maşgala<n><pl>
esger:esger<n>
esgerler:esger<n><pl>

Acum partea stângă arată cuvântul actual, iar cea dreaptă analiza. Apoi, convertim analizatorul pentru a arăta analiza unui singur cuvânt:

$ hfst-fst2fst -O -i tk-tr.automorf.hfst -o tk-tr.automorf.hfst.ol

Şi analiza:

$ echo "maşgalalar" | hfst-proc tk-tr.automorf.hfst.ol
^maşgalalar/maşgala<n><pl>$

$ echo "esgerler" | hfst-proc tk-tr.automorf.hfst.ol
^esgerler/esger<n><pl>$

Dacă apar erori[edit]

Greşeli generale care cauzează erori:

  • Aţi definit toate multicharacter symbols, cu tot cu arhivocalele şi consoanele? Dacă ştiţi că sunt acolo, mai verificaţi o dată. Această eroare poate apărea atât în fişierul twol cât şi în lexc.

Notes[edit]

  1. Acest subiect este foarte complicat, dar pentru un exemplu didactic, este de ajuns

Further reading[edit]