Corso di laurea specialistica in

Sistemi per il trattamento dell’informazione (classe 23S: Informatica)

Corso di Laboratorio di Sistemi Intelligenti

Docente: P.Torasso

a.a. 2003/04

Progetto: Ruby al supermercato

Il progetto in questione ha lo scopo di far sviluppare un agente intelligente (Ruby) che deve combinare sia aspetti deliberativi che reattivi per svolgere il compito di muoversi all’ interno di un supermercato e di acquistare quanto gli viene indicato.

Il mondo in cui si deve muovere Ruby è un supermercato in cui si vendono diversi prodotti. Il supermercato è rappresentato (in modo assai semplificato) come un insieme di celle connesse ciascuna delle quali può contenere una parete (wall), uno scaffale (stand), l’entrata (entry) , l’uscita (exit), la legenda dei prodotti (vedi sotto) oppure essere vuota (empty). Si suppone che le celle siano numerate dal basso verso l’alto e da sinistra verso destra. Si suppone inoltre che l’entrata e l’uscita sia contigue, siano localizzate nella riga 1 e che le celle davanti all’ingresso e all’uscita (cioe’ nella riga 2) siano libere.

Si noti che gli scaffali sono colorati ed il colore ha un significato semantico in quanto il colore indica una possibile tipologia merceologica (ad esempio gli stand che contengono bevande sono colorati di giallo, mentre gli scaffali che contengono verdura e frutta sono colorati in verde).

Ciascun prodotto è contenuto in uno scaffale (stand). Uno scaffale può contenere solo item dello stesso tipo, mentre più stand possono contenere lo stesso tipo di prodotto. Per far sapere cosa contiene uno stand c’e’ una opportuna etichetta sullo stand che specifica i dati salienti del prodotto in esso contenuto (si veda deftemplate standcontent). L’etichetta può essere letta solo da una cella adiacente allo scaffale. Inoltre lo scaffale può essere aperto anche solo da un lato per cui una operazione di lettura può fallire se è fatta su un lato chiuso dello scaffale. Considerazioni analoghe valgono anche per il prelevamento di un item dallo scaffale. Questo può essere fatto solo se Ruby si trova nella cella contigua e se lo scaffale è aperto in quella posizione.

Ogni prodotto e’ caratterizzato dal nome del prodotto (nome generico o specifico), dal nome della ditta che lo produce o lo distribuisce, il tipo di confezione e il prezzo. Le informazioni sui prodotti sono definite nel deftemplate standcontent. Si noti che standcontent ha anche uno slot che specifica la numerosità degli item di quel prodotto contenuti in quell’ istante nello stand.

La lista della spesa che Ruby deve fare e’ nota a Ruby attraverso fatti di tipo goal, che specificano quanti item di un certo tipo devono essere acquistati. Si tenga presente che l’unico campo richiesto nel goal e’ quello relativo al nome del prodotto (esempio caffè o robiola), mentre non sono obbligatori i dati relativi alla ditta produttrice, al tipo di confezione e al prezzo massimo per item da acquistare. Ovviamente se queste informazioni (facoltative) sono presenti nel goal, queste sono tenute in conto da Ruby nel fare gli acquisti.

Il nostro agente robotico Ruby ha la capacità di fare solo cinque azioni:

· Go

Con questa azione Ruby avanza di una posizione (cella) nella direzione in cui è attualmente orientato. Ovviamente l’azione di muoversi ha successo se la cella in cui Ruby deve andare non è composta da un muro o da uno stand o dall’entrata. Se si cerca di fare una azione di go non permessa Ruby ha una percezione di bump (vedi sotto)

· Turnright

Con questa azione Ruby svolta su se stesso di 90 gradi a destra rispetto alla sua direzione corrente. Si tenga presente che le direzioni sono 4 (in particolare up, down, left, right). Ruby non cambia cella con questa operazione. Questa azione non fallisce mai.

· turnleft

Con questa azione Ruby svolta su se stesso di 90 gradi a sinistra rispetto alla sua direzione corrente. Ruby non cambia cella con questa operazione. Questa azione non fallisce mai.

· Read

Con questa azione Ruby può leggere l’ etichetta associata ad uno stand e quindi sapere cosa contiene lo stand stesso. Come accennato sopra l’azione ha successo solo se Ruby è in una cella adiacente a quella dello stand e se lo stand e’ aperto dal lato in cui si trova Ruby. Nel caso la lettura non sia stata possibile, lo slot item del fatto della percezione perc-read contiene fail (vedi sotto la discussione sulle percezioni)

· grasp

Con questa azione Ruby può prendere un item dallo stand (ne può prendere uno solo per volta, ma ovviamente iterando l’ azione di grasp si possono prendere item nella quantità voluta). L’azione ha successo solo se Ruby è in una cella adiacente a quella dello stand e se lo stand e’ aperto dal lato in cui si trova Ruby, inoltre lo stand non deve essere vuoto. Nel caso l’ azione di grasp fallisca per uno dei motivi sopra elencati, lo slot item del fatto della percezione perc-grasp contiene fail (vedi sotto la discussione sulle percezioni)

· inspectlegenda

Con questa azione Ruby può leggere la legenda che contiene la corrispondenza tra colore dello stand e categoria merceologica. L’azione ha successo solo se Ruby è in una cella adiacente a quella dello legenda e se la legenda e’ aperta dal lato in cui si trova Ruby.. Nel caso l’ azione di inspectlegenda fallisca per uno dei motivi sopra elencati, lo slot standcolor del fatto della percezione perc-legenda contiene fail (vedi sotto la discussione sulle percezioni)

Come nello schema classico di un agente, ad ogni istante l’agente riceve percezioni dal mondo esterno, nel nostro caso dall’ambiente che modella il supermercato. Si suppone che l’agente abbia un sistema di visione (che non è soggetto a guasti) per cui il robot vede fino a tre celle in avanti rispetto alla sua posizione corrente. In modo più preciso, se Ruby si trova nella cella di coordinate (r,c) e la sua direzione è up riesce a vedere cosa contengono le celle (r+1,c), (r+2,c) e (r+3,c). Analoghe considerazioni valgono per le altre direzioni. E’ ovvio che la possibilità di vedere fino a tre celle in avanti è limitata dal fatto che la vista può essere impedita da una occlusione, sia essa rappresentata da un muro, da uno stand o dalla legenda. In questi casi l’agente non può sapere cosa ci sia dietro l’ostacolo (visivo). Si noti che Ruby percepisce lo stimolo visivo qualunque sia l’azione che viene svolta.

Come detto sopra, ad ogni istante l’ambiente fornisce a Ruby le percezioni visive che sono codificate nei fatti di tipo percepts, mentre fornisce le percezioni relative ad una operazione di read, grasp e inspectlegenda solo se nell’istante precedente Ruby ha deciso di compiere l’azione corrispondente (si vedano i fatti di tipo perc-read, perc-grasp, perc-legenda).

All’istante iniziale Ruby non conosce nulla del supermercato, sa solo che si trova all’entrata (di cui conosce le coordinate), che la sua direzione è up, che deve fare una azione di go per entrare nel supermercato e che l’uscita si trova nella cella adiacente a destra. La lista della spesa è nota a Ruby attraverso i fatti di tipo goal.

Ruby può dire di avere assolto al compito quando si trova nella cella dell’uscita avendo comperato quanto richiesto (e con gli eventuali vincoli sulla marca, ecc.) oppure quanto ha constatato che nel supermercato non sono disponibili questi prodotti.

Un ulteriore metro per la valutazione della funzionalità del robot è quella relativa al numero di azioni elementari che Ruby

deve compiere per assolvere il compito assegnato.

Al fine di semplificare lo sviluppo concettuale e implementativo di Ruby viene fornito un ambiente di simulazione in CLIPS. Questo ambiente di simulazione prevede tre moduli. Il modulo MAIN è usato esclusivamente per la comunicazione tra gli altri due che modellano rispettivamente l’ambiente del supermercato (ENV) e Ruby (AGENT). Il modulo ENV è fornito già completamente sviluppato (anche se l’implementazione potrebbe essere migliorata) perché ha scopo di fornire le percezioni sulla base del cambiamento di stato in seguito ad una azione decisa da Ruby.

Si noti che e’ all’interno di ENV che viene definito l’ambiente del supermercato, per cui se si volesse definire un supermercato con dimensione diverse e con contenuti diversi è necessario intervenire su questo modulo (in particolare la regola di nome "creation"). Il modulo AGENT è fornito in una versione assolutamente embrionale perché lo scopo del progetto è proprio lo sviluppo di questo modulo. Nella versione fornita esso definisce solo l’interfaccia di comunicazione (fatti di tipo exec) e ad ogni istante deve essere l’utente che fornisce l’azione che Ruby deve compiere nel supermercato.

Ovviamente a progetto ultimato l’agente deve essere in grado di decidere autonomamente le azioni da compiere nel modo più razionale possibile.

E’ sicuramente utile che si analizzi con una certa cura cosa fa il modulo ENV in modo da comprendere come le assunzioni sopra specificate sono rese a livello di implementazione di tipi di dati. Il file che contiene MAIN, ENV (con un particolare supermercato già rappresentato) e AGENT (nella forma appena abbozzata) è Ruby al Supermercato.

Si noti che Ruby deve avere delle componenti reattive (in particole integrare le percezioni che man mano riceve), ma e’ assai probabile che includa anche componenti deliberative (un possibile esempio è relativo alla necessità di pianificare il cammino che lo porta dallo stand dove ha completata la spesa alla uscita). Tecniche assai diverse possono essere utilizzate per fare questa ricerca. Nel caso che lo studente volesse sperimentare una soluzione relativamente semplice si suggerisce di prendere in considerazione una strategia iterative deepening. Lo studente può farsi una idea di come questa possa essere realizzata in un linguaggio a regola guardando la soluzione adottata per risolvere problemi nel mondo dei blocchi facendo uso di questa strategia oppure delle soluzioni per il labirinto.