Come scrivere una nuova coppia di lingue Apertium

From Apertium
Revision as of 09:15, 27 November 2010 by Cescus (talk | contribs) (Created page with '{{TOCD}} Come scrivere una nuova coppia di lingue per Apertium Questa guida mostra come procedere alla creazione di una nuova coppia di lingue per il traduttore automatico Apert…')
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Come scrivere una nuova coppia di lingue per Apertium

Questa guida mostra come procedere alla creazione di una nuova coppia di lingue per il traduttore automatico Apertium a partire da zero.

Per procedere non è necessario conoscere il funzionamento del traduttore automatico ma è presupposta la capacità di distinguere le varie componenti grammaticali di una lingua (verbi, sostantivi, preposizioni, ecc.)

Introduzione

Apertium è, come probabilmente hai capito, una piattaforma di traduzione automatica. Apertium è composto dal traduttore vero e proprio e da un set di utilities che permettono di creare un sistema personalizzato di traduzione automatica. L'unica cosa necessaria da fare è scrivere tre file dizionario e poche altre regole grammaticali (queste stabiliranno, per esempio, l'ordine delle parole o cose simili).

Per ottenere informazioni più dettagliate riguardo il funzionamento dell'intero framework, è possibile dare un'occhiata alla pagina Publications...

Avrai bisogno di

  • lttoolbox (>= 3.0.0)
  • libxml utils (xmllint etc.)
  • apertium (>= 3.0.0)
  • un editor di testo (o un altro editor XML)

Questa guida non descriverà come installare i suddetti pacchetti, puoi trovare maggiori informazioni leggendo la documentazione presente sul sito di Apertium.

In cosa consiste una coppia di lingue?

Apertium è un traduttore di tipo shallow-transfer. Il sistema shallow-transfer di differenzia da quello deep-transfer nelle modalità di lavoro: il sistema shallow-transfer non effettua una completa analisi sintattica. Le regole sono essenzialmente gruppi di unità lessicali, mentre i tre dizionari sono:

  1. Il dizionario morfologico per il linguaggio xx: questo contiene le regole secondo le quali i vocaboli della lingua xx sono coniugati. Nel nostro esempio sarà: apertium-sh-en.sh.dix
  2. Il dizionario morfologico per il linguaggio yy: questo contiene le regole secondo le quali i vocaboli della lingua yy sono coniugati. Nel nostro esempio sarà: apertium-sh-en.en.dix
  3. Il dizionario bilingue: contiene i vocaboli e i simboli corrispondenti nei due linguaggi. Nel nostro esempio sarà: apertium-sh-en.sh-en.dix

Nella coppia di lingue i due linguaggi sono intercambiabili: è possibile sia tradurre xx in yy sia il contrario.

I file che contengono le regole sono due. Questi descrivono le modalità secondo le quali le parole sono riordinate all'interno della frase una volta tradotta (es. gatto nero -> cat black -> black cat). Le regole si occupano anche di accordare i vocaboli in genere, numero, ecc. Come descritto più avanti, le regole possono inserire o rimuovere elementi lessicali. I due file sono:

  1. Le regole di trasferimento dalla lingua xx alla yy: questo file contiene le regole secondo le quali le parole della lingua xx verranno riordinate nella lingua yy. Nel nostro esempio sarà: apertium-sh-en.sh-en.t1x
  2. Le regole di trasferimento dalla lingua yy alla xx: questo file contiene le regole secondo le quali le parole della lingua yy verranno riordinate nella lingua xx. Nel nostro esempio sarà: apertium-sh-en.en-sh.t1x

Alcune delle coppie di lingue attualmente disponibili hanno altri file, ma in questa sezione non verranno trattati. Quelli appena descritti sono gli unici file richiesti per ottenere un traduttore funzionante.

Coppia di lingua

Com'è prevedibile dai nomi dei file presi in esempio, questa guida farà uso delle lingue serbo-croato e inglese per mostrare come creare un sistema basilare di traduzione. Non è una coppia facile da trattare dal momento che il sistema di traduzione funziona meglio se applicato a lingue simili. Questo non dovrebbe però rappresentare un problema per i semplici esempi mostrati qui.

Brevi note sui termini usati

Prima di procedere, è necessario capire precisamente cosa si intende con alcuni termini.

Il primo è il termine lemma. Il lemma è la semplice parola privata di qualsiasi informazione grammaticale. Per esempio, il lemma della parola gatti è gatto. Pertanto i lemmi dei sostantivi italiani saranno singolari. Per quanto riguarda i verbi, il lemma sarà dato dall'infinito presente (es. il lemma di ero sarà essere).

Il secondo termine è simbolo. Nel contesto del progetto Apertium, i simboli si riferiscono ad "etichette grammaticali". Il sostantivo gatti è un sostantivo plurale, pertanto avrà un' etichetta grammaticale (un simbolo, quindi) che lo contrassegnerà come nome e un'altra che lo contrassegnerà come plurale. Nel sistema di input/output di Apertium, questi simboli sono descritti all'interno di parentesi angolari come mostrato:

  • <n>; per i nomi.
  • <pl>; per i plurali.

Altri esempi di simboli sono <sg> per il singolare, <p1> per la prima persona, <pri> per il presente indicativo, ecc. Si noti come spesso i simboli sono abbreviazioni o acronimi dei termini a cui si riferiscono.

Il terzo termine è paradigma. Nel contesto del progetto Apertium, il termine paradigma si riferisce a una sorta di modello che descrive come i vocaboli sono coniugati. Nel dizionario morfologico, i lemmi sono collegati con i paradigmi in quanto ci permettono di determinare come un vocabolo si presenti una volta coniugato senza doverlo riscrivere con tutte le desinenze possibili.

Per esempio se vogliamo inserire nel dizionario i due aggettivi felice e pigro, invece di inserire ogni volta le desinenze di ciascuno:

  • felice, felic (e, issimo)
  • semplice, semplic (e, issimo)

Possiamo semplicemente inserirne uno e dire "semplice, si declina come felice", oppure "triste, si declina come felice", "gentile, si declina come felice", ecc. Nell'esempio, felice rappresenta il paradigma, il modello seguito per la coniugazione degli altri aggettivi simili. Una descrizione più approfondita di come si determina questa relazione verrà data a breve. I paradigmi sono definiti tramite il tag <pardef> e usati all'interno del tag <par>.

Iniziare

I dizionari monolingue

See also: List of dictionaries and Incubator

Cominciamo col creare il nostro primo dizionario. Il dizionario sarà costituito da un file XML. Apri il tuo editor di testo e scrivi quello che segue:

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

</dictionary>

Il file che otteniamo indica semplicemente che stiamo creando un dizionario. Per renderlo funzionante, però, dobbiamo inserire altre informazioni, la prima è l'alfabeto. Questo stabilisce quali lettere possono essere usate all'interno della lingua che stiamo definendo. Per il serbo-croato, l'alfabeto che stiamo andando a definire risulterà come:

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

È necessario porre l'alfabeto all'interno del tag <dictionary>.

Adesso definiamo alcuni simboli. Cominciamo con cose semplici: nomi (n) al singolare (sg) e al plurale (pl).

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

I nomi dei simboli non devono per forza essere brevi ma, dal momento che dovrai ricordarli e scriverli spesso, conviene abbreviarli.

Sfortunatamente il caso trattato non è così semplice, i nomi in serbo-croato si coniugano in caso, genere e numero. Tuttavia, allo scopo dell'esempio, consideremo che il nome sia maschile e al caso nominativo (un esempio completo si può trovare alla fine di questa guida).

La prossima cosa da definire è la sezione per i paradigmi:

<pardefs>

</pardefs>

e la sezione del dizionario vero e proprio:

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

</section>

Ci sono due tipi di sezioni, il primo è dato dalla sezione standard che contiene i vocaboli, ecc. Le sezioni di secondo tipo sono facoltative e definiscono la punteggiatura e così via. Nel caso trattato mancherà la sezione facoltativa.

A questo punto il nostro file dovrebbe assomigliare a qualcosa come:

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

Ora che abbiamo messo in piedi lo scheletro, possiamo cominciare ad aggiungere un nome. Il nome in questione sarà 'gramofon' (che sarebbe il 'grammofono').

Dal momento che non ne abbiamo, la prima cosa da fare è definire un paradigma.

Ricorda che stiamo stabilendo per convenzione di usare il genere maschile e il caso nominativo. La forma singolare del nome è 'gramofon' e il plurale è 'gramofoni'. Allora:

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

Nota: '<l/>' (equivalente a <l></l>) denota che non bisogna aggiungere nessun carattere a 'gramofon' per ottenere il singolare.

Probabilmente ti starai chiedendo per cosa stanno <e>,

, <l> e <r>. Bene,

  • e, sta per entry (indica l'inserimento di un nuovo elemento).
  • p, sta per pair (indica la coppia).
  • l, sta per left (indica la parola vera e propria).
  • r, sta per right (indica gli elementi grammaticali che caratterizzano la parola).

perché destra e sinistra? Bene, i dizionari morfologici alla fine andranno compilati. Compilarli da sinistra a destra significa produrre un analizzatore, mentre compilarli da destra a sinistra significa produrre un generatore. Il prodotto della compilazione (analizzatore o generatore) sarà in grado, a partire da un input, di produrre un output coerente con la modalità in cui è stato creato. L'esempio farà capire meglio:

* da sinistra a destra: gramofoni ---> gramofon<n><pl> (analizzatore)
* da destra a sinistra: gramofon<n><pl> ---> gramofoni (generatore)

Ora che abbiamo definito il paradigma, dobbiamo collegarlo con il rispettivo lemma, gramofon. Quest'operazione andrà fatta nella sezione che abbiamo definito.

L'elemento da inserire all'interno di </dictionary>

Ora dobbiamo aggiungere l'elemento per tradurre le parole da una lingua all'altra. Qualcosa come:

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

Dato che dovranno essere aggiunti molti elementi come questo, di solito vanno scritti su un'unica riga per facilitare la lettura del file. Qui non si trovano sulla stessa riga per facilitarne la comprensione. Anche qui troviamo 'l' (left) e 'r' (right). Se compiliamo questo dizionario da sinistra a destra otterremo un dizionario serbo-croato → inglese, se lo compiliamo da destra a sinistra otterremo un dizionario inglese → serbo-croato.

A questo punto procediamo eseguendo i seguenti comandi:

$ 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

Per generare l'analizzatore morfologico (automorf), il generatore morfologico (autogen) ed il dizionario stesso (autobil, dove bil sta per "bilingue").

Le regole di trasferimento

Bene, ora abbiamo due dizionari morfologici e un dizionario bilingue. Tutto ciò di cui necessitiamo ora sono delle regole di trasferimento per i nomi. I file che contengono le regole di trasferimento hanno il loro DTD (tansfer.dtd) che può essere trovato nel pacchetto di Apertium. Se hai bisogno di implementare una regola, si potrebbe rivelare una buona idea quella di guardare prima tra le regole di altre coppie di lingue. Alcune regole possono essere riutilizzate anche tra lingue diverse.

Cominciamo come abbiamo già fatto con lo scheletro base:

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

</transfer>

Al momento, dato che stiamo ignorando il caso del vocabolo, dobbiamo solo creare la regola che prende come input i simboli grammaticali e li restituisce nuovamente nell'output.

Dobbiamo prima definire le categorie e gli attributi. Le categorie e gli attributi ci permettono di raggruppare simboli grammaticali. Le categorie ci consentono di raggruppare simboli in base all'aderenza a un pattern (es. 'n.*' comprenderà tutti i nomi). Gli attributi ci consentono di raggruppare alcuni simboli variabili riferiti allo stesso oggetto(es. 'sg' e 'pl' possono essere raggruppati sotto l'attributo 'number').

Aggiungianmo le sezioni necessarie:

<section-def-cats>

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

</section-def-attrs>

Dato che stiamo flettendo i nomi solo in numero (o singolare o plurale), avremo bisogno di aggiungere una categoria per i nomi con l'attributo del numero. Qualcosa come quello che segue sarà sufficiente.

Aggiungi in section-def-cats:

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

Questo rintraccerà tutti i nomi (i lemmi seguiti da <n>) e si riferirà a loro come "nom" (vedremo l'utilità di questa operazione in seguito).

Aggiungi in section-def-attrs:

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

e poi

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

Il primo definisce l'attributo nbr (numero), che può assumere il valore di singolare (sg) o plurale (pl).

Il secondo definisce l'attributo a_nom (attributo del nome).

La prossima cosa di cui abbiamo bisogno è una sezione per le variabili globali:

<section-def-vars>

</section-def-vars>

Queste variabili sono utilizzate per memorizzare o scambiare gli attributi tra le regole. Per il momento abbiamo bisogno di definirne solo una,

<def-var n="number"/>

Infine, dobbiamo aggiungere una regola per prendere il nome in input e per produrre l'output in forma corretta. Avremo bisogno di una sezione per le regole...

<section-rules>

</section-rules>

Ecco qui a seguire un esempio di regola:

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

Il primo tag, è ovvio, definisce la regola. Il secondo tag è dato dal pattern e significa: "applica questa regola se questo pattern è riscontrato". In questo esempio il pattern è dato da un singolo nome (definito dalla categoria nom). Nota che i pattern sono applicati a partire dal più lungo. Se, per esempio, si hanno tre regole di cui la prima verifica la presenza del pattern "<prn><vblex><n>", la seconda del pattern "<prn><vblex>" e la terza del pattern "<n>", il pattern a venir verificato prima sarà il più lungo ovvero il primo.

A ciascun pattern è associata un'azione che produce un dato output (out). L'output è un'unità lessicale (lu).

Il tag clip permette all'utente di selezionare e manipolare gli attribuiti e le parti del lessico della lingua di partenza (side="sl"), o della lingua di arrivo (side="tl").

Compiliamolo e testiamolo. Le regole di trasferimento sono compilate con:

$ apertium-preprocess-transfer apertium-sh-en.sh-en.t1x sh-en.t1x.bin

Che genererà il file sh-en.t1x.bin.

Ora siamo pronti a testare il nostro sistema di traduzione automatica. Manca ancora una parte cruciale, l'attributo part-of-speech (PoS), ma verrà illustrata a breve. Nel frattempo possiamo testare il sistema così com'è:

Per prima cosa analizziamo una parola, gramofoni:

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

Ora, normalmente qui il tagger POS avrebbe scelto la giusta versione in base alla parte del discorso, ma non avendo ancora il tagger POS, possiamo usare un piccolo script gawk (grazie a Sergio) che semplicemente mostrerà il primo termine ottenuto.

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

Ora processiamolo con la regola di trasferimento:

$ 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.sh-en.t1x sh-en.t1x.bin sh-en.autobil.bin

Questo produrrà come output:

^gramophone<n><pl>$^@
  • 'gramophone' è il lemma (lem) della lingua finale (side="tl") alla posizione 1 (pos="1").
  • '<n>' è l'attributo del nome (a_nom) della lingua finale alla posizione 1.
  • '<pl>' è l'attributo numero (nbr) della lingua finale alla posizione 1.

Prova a commentare una dichiarazione del tag clip, ricompila e osserva che succede.

Bene, ora che abbiamo l'output del "trasferitore", l'unica cosa che rimane da generare sono le forme flesse del linguaggio finale. Allo scopo useremo lt-proc ma come generatore (-g), non come analizzatore.

$ 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.sh-en.t1x sh-en.t1x.bin sh-en.autobil.bin | \
  lt-proc -g sh-en.autogen.bin

gramophones\@

E ci siamo! Ora hai un sistema di traduzione automatica che traduce un nome dal serbo-croato all'inglese. Ovviamente questo non è molto utile, ma ci addentreremo presto in cose più complesse. Non preoccuparti per il simbolo '@', lo spiegheremo presto.

Pensa un altro po' di parole che si flettono allo stesso modo di gramofon. Come aggiungerli? Non abbiamo bisogno di aggiungere altri paradigmi, basterà aggiungere l'elemento nella sezione principale del dizionario monolingue e bilingue.

Passiamo ai verbi

Bene, ora abbiamo un sistema che traduce i nomi. Ma per creare qualcosa di veramente utile dobbiamo poter tradurre i verbi e perfino intere frasi! Per mostrare come fare, utilizzeremo il verbo inglese to see. La rispettiva traduzione in serbo-croato è videti. Il serbo-croato è una lingua che non necessita di soggetto, questo significa che non hanno bisogno del pronome personale che compie l'azione descritta dal verbo. L'inglese è diverso. Per esempio: I see sarebbe tradotto in serbo-croato come vidim.

  • vidim
  • see<p1><sg>
  • I see

Nota: <p1> indica che si tratta di una prima persona.

Questo sarà importante quando arriveremo a trattare delle regole di trasferimento per i verbi. Altri esempi di lingue che non necessitano di soggetto sono: italiano, spagnolo, rumeno e polacco. Questo significa anche che se nel dizionario morfologico serbo-croato dobbiamo inserire solo il verbo, nel dizionario morfologico inglese dovremo inserire sia il verbo che il pronome personale. Esamineremo anche questi casi.

Le altre persone del verbo videti sono: vidiš, vidi, vidimo, vidite, e vide; queste corrispondono rispettivamente a vedi, vede, vediamo, vedete, vedono.

A questo punto proviamo a tradurre la frase "Vidim gramofoni" in "I see gramophones". Per ragioni di spazio, aggiungeremo soltanto le informazioni basilari per fare la traduzione, mentre lasceremo il lavoro di aggiungere i paradigmi del verbo come esercizio per il lettore.

L'astuto lettore avrà realizzato che ancora non possiamo tradurre correttamente vidim gramofoni poiché non è grammaticalmente corretto in serbo-croato. La frase corretta sarebbe vidim gramofone in quanto il nome va coniugato in caso accusativo. Dovremo aggiungere anche questa forma. Tuttavia, per il momento, non è necessario aggiungere informazioni sul caso.

La prima cosa che dobbiamo fare è aggiungere qualche simbolo. Dobbiamo prima aggiungere il simbolo per 'verb', che chiameremo 'vblex' (che significa verbo lessicale, il contrario dei verbi modali e di altri tipi). I verbi hanno la persona ('person') e il tempo ('tense') oltre che il numero, pertanto aggiungiamone un paio. Dobbiamo tradurre "I see", aggiungeremo, quindi, "p1" (prima persona) per la persona e "pri" (presente indicativo) per il tempo.

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

Fatto ciò, allo stesso modo dei nomi, aggiungeremo un paradirma per la coniugazione dei verbi. La prima riga sarà:

<pardef n="vid/eti__vblex">

La '/' è utilizzata per indicare il punto in cui verranno aggiunte le desinenze (le parti racchiuse tra <l> e </l>).

A questo punto aggiungiamo la flessione per la prima persona singolare:


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

La parte 'im' indica la terminazione (per formare 'vid-im') del verbo. È necessario, poi aggiungere 'eti' nella sezione dato che nella definizione questa sarà tagliata via. Il resto è piuttosto chiaro: 'vblex' indica che il verbo in questione è lessicale, 'pri' indica che si tratta di un presente indicativo, 'p1' indica che si tratta di una prima persona mentre 'sg' afferma che il numero è singolare. Possiamo anche aggiungere il plurale che sarà molto simile eccetto per la terminazione (che sarà 'imo') e per il numero (che sarà 'pl').

Completato anche questo passiaggio, dobbiamo definire il lemma nella sezione principale:

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

Nota: il contenuto di <i> </i> è la radice, non il lemma.

Questo è quanto per quel che riguarda il dizionario serbo-croato di cui abbiamo parlato fino ad ora. Compiliamolo e testiamolo:

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

Bene, ora non ci rimane che fare la stessa cosa per il dizionario di inglese (ricordati di aggiungere le stesse definizioni dei simboli che hai aggiunto nel dizionario serbo-croato).

Il paradigma è:

<pardef n="s/ee__vblex">

poiché il passato fa 'saw'. Aggiungiamo, quindi, un'elemento per 'see' e assegnamogli solo il simbolo 'pri'.


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

e come sempre, un nuovo elemento anche nella sezione principale:

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

Salviamo, ricompiliamolo e testiamolo:

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

Ora aggiungiamo l'elemento anche nel dizionario bilingue:

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

(non dimenticare di aggiungere le sdefs all'interno del file)

E ricompila:

$ 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

Ora testalo:

$ 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.sh-en.t1x sh-en.t1x.bin sh-en.autobil.bin

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

Vediamo che l'analisi è andata avanti senza problemi ma otteniamo un '#' come mostrato:

$ 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.sh-en.t1x sh-en.t1x.bin sh-en.autobil.bin | \
  lt-proc -g sh-en.autogen.bin
#see\@

Il '#' significa che il generatore non riesce a generare la forma lessicale corretta poiché non la contiene. perché accade questo?

In pratica l'analisi non trova corrispondenza, il 'see' nel dizionario è see<vblex><pri>, ma il see inviato dal "trasferitore" è see<vblex><pri><p1><sg>. La parte serbo-croata del dizionario possiede più informazioni di quelle richieste dalla parte inglese. Puoi testare questo comportamento aggiungendo i simboli mancanti al dizionario inglese, ricompilandolo e testandolo nuovamente.

Tuttavia, il modo migliore per risolvere questo comportamento è scrivere una regola. Quindi apri il file delle regole (apertium-sh-en.sh-en.t1x sh-en.t1x.bin sh-en.autobil.bin in caso ne avessi dimenticato il nome).

Aggiungiamo una nuova categoria per 'verb'.

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

Dobbiamo anche aggiungere gli attributi per il tempo e per la persona. Per motivi di spazio aggiungeremo solo la prima persona ma è possibile aggiungere anche p2 e p3.

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

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

Dovremo anche aggiungere un attributo per i verbi.

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

Ora scriviamo tra le regole:

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

Ricorda che se commenti i tag 'clip' nell'esempio di regola appena visto, essi scompariranno nell'output. Possiamo così prendere in entrata un verbo con tutta l'analisi, ma produrre un output contenente un'analisi parziale (lemma + tag verbo + tag tempo)

Adesso, se ricompiliamo il tutto, otteniamo:

$ 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.sh-en.t1x sh-en.t1x.bin sh-en.autobil.bin
^see<vblex><pri>$^@

e:

$ 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.sh-en.t1x sh-en.t1x.bin sh-en.autobil.bin | \
  lt-proc -g sh-en.autogen.bin
see\@

Provalo con 'vidimo' (we see) per vedere se ottieni l'output corretto.

Prova ora con "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.sh-en.t1x sh-en.t1x.bin sh-en.autobil.bin | \
  lt-proc -g sh-en.autogen.bin
see gramophones\@

E il pronome personale?

Bene, siamo a buon punto ma ci manca ancora il pronome personale che è necessario nella lingua inglese. Per aggiungerlo, dobbiamo prima modificare il dizionario morfologico inglese.

Come già visto, la prima cosa da fare è aggiungere i simboli necessari:

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

Dei due simboli, prn è il pronome, e subj è il soggetto (come il soggetto di una preposizione).

poiché non c'è radice o lemma per il pronome personale soggetto, ci basta aggiungere il pardef come segue:

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

Dove 'prsubj' sta per 'personal subject' (personale soggetto). I rimanenti (You, We, ecc.) saranno un esercizio per il lettore.

Possiamo aggiungere un elemento nella sezione principale come segue:

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

A questo punto salva, ricompila e testa. Dovremmo ottenere qualcosa come:

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

(Nota: è in lettere maiuscole perché I è in maiuscolo).

Ora dobbiamo correggere la regola 'verb' per dare come output anche il pronome personale.

Prima, aggiungiamo una categoria:

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

Ora aggiungiamo i tipi di pronome come attributi, possiamo anche aggiungere il tipo 'obj' (oggetto) anche se non ne faremo uso per il momento:

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

Ed ecco la regola:

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

Assomiglia quasi alla stessa regola di prima ma sono state fatte un paio di semplici modifiche.

Abbiamo bisogno di ottenere come output:

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

così che il generatore possa scegliere il pronome corretto e la giusta forma del verbo.


Ecco un breve riassunto:

  • <lit>, stampa una stringa, in questo caso "prpers".
  • <lit-tag>, stampa un tag; poiché non possiamo ottenere i tag a partire dal verbo, li aggiungiamo noi stessi, "prn" per il pronome e "subj" per il soggetto.
  • , stampa uno spazio vuoto.

Nota che abbiamo ricavato le informazioni del numero e del tempo direttamente dal verbo.

Se ora ricompiliamo e testiamo nuovamente otteniamo:

$ 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.sh-en.t1x sh-en.t1x.bin sh-en.autobil.bin | \
  lt-proc -g sh-en.autogen.bin
I see gramophones

Che, sebbene non sia qualcosa di sensazionale, è una traduzione piuttosto accurata.

Parlami un po' di 'record player' (parole multiple)

Sebbene gramophone sia una parola inglese, non è certamente la miglior traduzione. Gramophone è usata solitamente per descrivere il vecchio tipo di apparecchio (quello con l'ago al posto del pennino e senza amplificazione elettrica). Una traduzione migliore del termine sarebbe 'record player'. Anche se è composta da più di un vocabolo, è possibile trattarla come se fosse un'unica parola usando la costruzione delle parole multiple.

Non abbiamo bisogno di incidere né sul dizionario serbo-croato né su quello bilingue, ma solo su quello inglese. Aprilo, pertanto.

Il plurale di 'record player' è 'record players', puoi usare infatti lo stesso paradigma di gramophone (gramophone__n) — nel senso che ci basta aggiungere solo la 's'. Tutto quello che dobbiamo fare è aggiungere un nuovo elemento alla sezione principale.

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

L'unica differenza è l'uso del tag , che non ci è del tutto nuovo avendolo visto nel file delle regole.

Bene, ricompilato e testalo nel solito modo:

$ 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.sh-en.t1x sh-en.t1x.bin sh-en.autobil.bin  | \
  lt-proc -g sh-en.autogen.bin
I see record players

Perfetto. Uno dei maggiori benefici dell'uso delle parole multiple è che puoi tradurre modi di dire senza dover fare la traduzione parola per parola. Per esempio l'espressione inglese "at the moment" sarebbe tradotta in serbo-croato come "trenutno" (trenutak = moment, trenutno sarebbe l'avverbio). Non sarebbe stato possibile tradurre un'espressione del genere dall'inglese al serbo-croato col metodo del'analisi parola per parola.

Avere a che fare con variazioni minori

Il serbo-croato ha diversi modi di scrivere ciascuna parola a causa delle variazioni dialettali. Ha un interessante sistema di scrittura dato che si scrive nello stesso modo in cui si parla. Per esempio le persone che parlano Ijekavian direbbero "rječnik" intendendo quello che le persone che parlano Ekavian direbbero "rečnik". Questo riflette le differenze di pronuncia per la vocale proto-slava yat.

Analisi

Queste situazioni si possono trattare in modo piuttosto semplice con l'uso dei paradigmi. I paradigmi non sono usati solo per aggiungere simboli grammaticali, ma anche per sostituire qualsiasi carattere/simbolo con un altro. Per esempio qui viene mostrato un paradigma che accetta sia "e" e "je" nell'analisi. Il paradigma dovrebbe andare nel dizionario monolingue serbo-croato.

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

Aggiungi poi nella sezione principale:

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

Questo ci permette soltanto di analizzare entrambe le forme tuttavia... è necessario più lavoro nel caso volessimo generare entrambe le forme.

Generazione

Vedi anche