Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Grammatiche avanzate

Migliorare le grammatiche introducendo regole complesse
Migliorare le grammatiche introducendo regole complesse
Link copiato negli appunti

Abbiamo affrontato la creazione di grammatiche che permettono all'utente di dare delle risposte semplici (poco articolate) o di impartire comandi. Ma le espressioni usate dall'utente nella vita reale e le sue risposte sono decisamente più complesse ed articolate. Dobbiamo poter estendere le nostre grammatiche per contenere anche queste espressioni.

Pensiamo ad un'applicazione che deve ricercare servizi, ad esempio: farmacie, ostelli, parcheggi, etc, in una determinata città. La domanda che rivolgiamo all'utente potrebbe essere: "Dimmi in quale città ti trovi?"

Apparentemente l'unica possibile risposta per questa domanda è il nome della città, perciò la nostra grammatica sarà un elenco delle diverse città, ma sappiamo anche che la fantasia degli utenti non ha limiti, e che molto probabilmente utilizzerà il nostro servizio in macchina o mentre si deve spostare da una città all'altra.

Includeremo nella nostra grammatica, perciò, diverse espressioni quali:

  • "mi trovo a Genova",
  • "sono a Genova",
  • "sto andando a Genova",
  • ed altre voci simili.

Ovviamente potremmo costruire una grammatica con una lista delle infinite variazioni delle frasi riportate sopra, oppure cercare di razionalizzare le cosa e, da un lato coprire la maggior parte delle frasi dell'utente e dall'altro separare la parte di informazione che ci interessa da quella che non ci interessa. Per fare questo dovremmo porci due obiettivi:

  • capire quale parte della informazione è rilevante per la nostra applicazione
  • dividere i possibili input dell'utente in unità grammaticali per costruire delle regole flessibili.

Vediamo come realizzare questa suddivisione: il primo punto è abbastanza semplice da soddisfare in quanto nel nostro caso è sufficiente considerare solo l'informazione "città" e scartare il resto. Il secondo punto richiede un minimo di analisi.

Abbiamo detto che le nostre frasi possono essere del tipo:

  • io mi trovo a Genova
  • io sono vicino a Genova
  • io sto andando a Genova

Possiamo perciò scomporle e rappresentarle nel seguente modo:

io, mi
sono, trovo, sto
andando, recando, avvicinando, arrivando
a, vicino_a, presso, verso, quasi
città

Combinando un singolo elemento delle diverse righe potremmo comporre diverse frasi.

Fattociò procediamo alla scrittura del codice SRGS. Scriviamo le singole regole che rappresentano le nostre parti di grammatica:

Listato 3.12: grammatica complessa, regole

...
 <rule id="Pronomi">
  <one-of>
   <item>io</item>
   <item>mi</item>
  </one-of>
 </rule>
 <rule id="PrimoVerbo">
  <one-of>
   <item>sono</item>
   <item>trovo</item>
   <item>sto</item>
  </one-of>
 </rule>
 <rule id="SecondoVerbo">
  <one-of>
   <item>andando</item>
   <item>recando</item>
   <item>avvicinando</item>
   <item>arrivando</item>
  </one-of>
 </rule>
 <rule id="AvvMoto">
  <one-of>
   <item>vicino a</item>
   <item>a</item>
   <item>verso</item>
   <item>quasi</item>
   <item>presso</item>
  </one-of>
 </rule>
...

A questo dobbiamo aggiungere la regola con la città, l'unica che sarà semanticamente rilevante nel nostro caso:

Listato 3.13: grammatica complessa, regola città

...
 <rule id="Risposta" scope="public">
  <one-of>
   <!-- nome del campo ... -->
   <item>genova<tag><![CDATA[<citta "genova">]]></tag>
   </item>
   <item>milano<tag><![CDATA[<citta "milano">]]></tag>
   </item>
   <item>roma<tag><![CDATA[<citta "roma">]]></tag>
   </item>
   <!-- etc... -->
  </one-of>
 </rule>
...

Non ci resta che creare una struttura di grammatica in grado di richiamare ed unire le regole appena create per adattarsi alle frasi del nostro utente.

Listato 3.14: grammatica complessa, regola pubblica

...
 <rule id="General" scope="public">
  <item>
   <ruleref special="GARBAGE"/>
   <item repeat="0-2">
    <ruleref uri="#Pronomi"/>
   </item>
   <item repeat="0-1">
    <ruleref uri="#PrimoVerbo"/>
   </item>
   <item repeat="0-1">
    <ruleref uri="#SecondoVerbo"/>
   </item>
   <item repeat="0-1">
    <ruleref uri="#AvvMoto"/>
   </item>
   <ruleref uri="#Risposta"/>
  </item>
 </rule>
...

Abbiamo definito una regola "General", di tipo pubblico, che è composta da un unico item (per semplicità), composto da diversi sotto elementi che saranno le nostre regole.

Da notare è l'uso del <ruleref> per indicare un riferimento ad una regola, tale riferimento può essere relativo alla stessa grammatica oppure inserito come URI, puntando cosi ad una grammatica esterna.

Un attributo importante di ITEM è repeat="..." che ci permette di indicare quante volta la singola regola deve essere richiamata, "0" significa che la regola è opzionale, "2" che la stessa regola può essere presente più volte, questo ci permette di coprire casi come:

  • sono a genova: repeat="0"
  • io sono a genova: repeat="1"
  • io mi trovo a genova: repeat="2"

Avendo, in questo caso, usato un solo item, dobbiamo tenere presente che le diverse regole sono lette in sequenza, una dopo l'altra, e non come valori alternativi, come invece accadrebbe nel caso di un <one-of>.

Per concludere, uniamo i listati 3.12, 3.13 e 3.14 in questo modo:

Listato 3.15: grammatica complessa

<?xml version="1.0"?>
<grammar xmlns="http://www.w3.org/2001/06/grammar" xml:lang="it-IT" version="1.0"
mode="voice" tag-format="Nuance">
 <rule id="General" scope="public">
  <item>
   <ruleref special="GARBAGE"/>
   <item repeat="0-2">
    <ruleref uri="#Pronomi"/>
   </item>
   <item repeat="0-1">
    <ruleref uri="#PrimoVerbo"/>
   </item>
   <item repeat="0-1">
    <ruleref uri="#SecondoVerbo"/>
   </item>
   <item repeat="0-1">
    <ruleref uri="#AvvMoto"/>
   </item>
   <ruleref uri="#Risposta"/>
  </item>
 </rule>

 <!-- sotto regole -->
 
 <rule id="Risposta" scope="public">
  <one-of>
   <!-- nome del campo ... -->
   <item>genova<tag><![CDATA[<citta "genova">]]></tag>
   </item>
   <item>milano<tag><![CDATA[<citta "milano">]]></tag>
   </item>
   <item>roma<tag><![CDATA[<citta "roma">]]></tag>
   </item>
   <!-- etc... -->
  </one-of>
 </rule>
 
  <rule id="Pronomi">
  <one-of>
   <item>io</item>
   <item>mi</item>
  </one-of>
 </rule>
 <rule id="PrimoVerbo">
  <one-of>
   <item>sono</item>
   <item>trovo</item>
   <item>sto</item>
  </one-of>
 </rule>
 <rule id="SecondoVerbo">
  <one-of>
   <item>andando</item>
   <item>recando</item>
   <item>avvicinando</item>
   <item>arrivando</item>
  </one-of>
 </rule>
 <rule id="AvvMoto">
  <one-of>
   <item>vicino a</item>
   <item>a</item>
   <item>verso</item>
   <item>quasi</item>
   <item>presso</item>
  </one-of>
 </rule>
 
</grammar>

Ti consigliamo anche