• Non ci sono risultati.

4.1

Agente custode

L’agente custode `e implementato all’interno della classe KeeperAgent. Du-

rante la fase di setup(), svolge le seguenti operazioni:

• avvia il nodo TuCSoN, nel caso questo non sia gi`a correttamente atti-

vo, e vi inserisce in maniera asincrona cinque tuple team(’WHITE’) e cinque tuple team(’BLACK’), oltre alla tupla ball(1) che rappresenta il pallone di gioco;

• controlla che nel cluster Kafka sia presente il topic playgroundTopic relativo agli eventi di gioco ed in caso contrario ne richiede la creazione; • aggiunge il comportamento ObservePlaygroundBehaviour.

p r o t e c t e d v o i d s e t u p () { ... if (!t h i s. h e l p e r . i s A c t i v e (" l o c a l h o s t ", 20504 , 1 0 0 0 0 ) ) { t h i s. h e l p e r . s t a r t T u c s o n N o d e ( 2 0 5 0 4 ) ; } ... for (int i = 0; i < t h i s. p l a y e r s _ p e r _ t e a m ; i ++) { L o g i c T u p l e i n t e n t i o n = L o g i c T u p l e . p a r s e (" t e a m ( ’ W H I T E ’) ") ;

f i n a l Out out = new Out (t h i s. tcid , i n t e n t i o n ) ;

t h i s. b r i d g e . a s y n c h r o n o u s I n v o c a t i o n ( out ) ; }

for (int i = 0; i < t h i s. p l a y e r s _ p e r _ t e a m ; i ++) {

L o g i c T u p l e i n t e n t i o n = L o g i c T u p l e . p a r s e (" t e a m ( ’ B L A C K ’) ") ;

f i n a l Out out = new Out (t h i s. tcid , i n t e n t i o n ) ;

t h i s. b r i d g e . a s y n c h r o n o u s I n v o c a t i o n ( out ) ; }

L o g i c T u p l e i n t e n t i o n = L o g i c T u p l e . p a r s e (" b a l l (1) ") ;

f i n a l Out out = new Out (t h i s. tcid , i n t e n t i o n ) ;

t h i s. b r i d g e . a s y n c h r o n o u s I n v o c a t i o n ( out ) ; ... if (! A d m i n U t i l s . t o p i c E x i s t s ( zkUtils , t h i s. p l a y g r o u n d T o p i c ) ) { A d m i n U t i l s . c r e a t e T o p i c ( zkUtils , t h i s. p l a y g r o u n d T o p i c , p a r t i t i o n s , r e p l i c a t i o n , t o p i c C o n f i g u r a t i o n , n u l l) ; } t h i s. a d d B e h a v i o u r (new O b s e r v e G a m e B e h a v i o u r () ) ; }

ObserveGameBehaviour estende la classe CyclicBehaviour. Quando questo comportamento viene inizializzato, crea un’istanza del componente Kafka- ConsumerAssistant ed effettua la sottoscrizione al topic del playground. In seguito, ad ogni esecuzione del metodo action(), si eseguono le richieste a polling al broker Kafka per ottenere i messaggi presenti nel topic sottoscritto.

Si noti come, grazie al disaccoppiamento dall’effettiva richiesta al broker, sia possibile indicare un tempo di timeout molto elevato senza condizionare l’au- tonomia dell’agente, riducendo di conseguenza anche il numero di richieste di rete che vengono effettuate verso il cluster Kafka.

p r i v a t e c l a s s O b s e r v e P l a y g r o u n d B e h a v i o u r e x t e n d s C y c l i c B e h a v i o u r { ... p r i v a t e K a f k a C o n s u m e r A s s i s t a n t kca ; ... p u b l i c O b s e r v e P l a y g r o u n d B e h a v i o u r () { ...

kca = new K a f k a C o n s u m e r A s s i s t a n t (this, c o n s u m e r _ g r o u p ) ; kca . s u b s c r i b e ( K e e p e r A g e n t .t h i s. p l a y g r o u n d T o p i c ) ;

}

p u b l i c v o i d a c t i o n () {

C o n s u m e r R e c o r d s <String, String> r e c o r d s = kca . c o n s u m e ( L o n g . M A X _ V A L U E ) ; ...

} }

4.2

Agente giocatore

L’agente giocatore `e implementato nella classe PlayerAgent. All’inizio del-

la sua vita, l’agente ha un unico comportamento, di tipo ArrivedToPlay- groundBehaviour.

All’interno di questo comportamento viene eseguita, tramite il bridge di TuC- SoN4JADE, l’operazione inp, in maniera asincrona, per estrarre una tupla del tipo team(S) dal centro di tuple. Si noti che l’utilizzo della primitiva inp permette all’agente di coordinarsi rispettando la propria autonomia. Essa in- fatti consente di eseguire un’operazione di estrazione non bloccante: se non esistono tuple che corrispondono al template indicato, viene restituito imme- diatamente all’agente un messaggio di fallimento. L’utilizzo inoltre dell’invo- cazione asincrona permette di disaccoppiare ulteriormente il comportamento dell’agente dall’esecuzione dell’operazione.

p r i v a t e c l a s s A r r i v e d T o P l a y g r o u n d B e h a v i o u r e x t e n d s W a k e r B e h a v i o u r {

p u b l i c A r r i v e d T o P l a y g r o u n d B e h a v i o u r ( A g e n t a , l o n g t i m e o u t ) {

s u p e r( a , t i m e o u t ) ; }

3.4.2 Agente giocatore 41

@ O v e r r i d e

p r o t e c t e d v o i d o n W a k e () { ...

L o g i c T u p l e t e a m = L o g i c T u p l e . p a r s e (" t e a m ( S ) ") ;

f i n a l Inp inp = new Inp ( P l a y e r A g e n t .t h i s. tcid , t e a m ) ;

P l a y e r A g e n t .t h i s. b r i d g e . a s y n c h r o n o u s I n v o c a t i o n ( inp , new D r a f t B e h a v i o u r ( P l a y e r A g e n t .this, 1 0 0 0 ) , P l a y e r A g e n t .t h i s) ;

... }

Il risultato della richiesta viene poi gestito all’interno del comportamento DraftBehaviour grazie alla callback setTucsonOpCompletionEvent(...)

definita da TuCSoN4JADE. Se la tupla `e stata estratta con successo, significa

che l’agente pu`o partecipare alla partita. Egli esegue quindi una out asincrona

per inserire la tupla player(name(nomeAgente), team(squadraAgente)) nel centro di tuple e passa al comportamento WaitToPlayBehaviour. Nel caso invece in cui la inp non abbia avuto successo, l’agente passa immedia- tamente al comportamento ObserveGameBehaviour tramite il quale osserva la partita da spettatore. p u b l i c c l a s s D r a f t B e h a v i o u r e x t e n d s T i c k e r B e h a v i o u r i m p l e m e n t s I A s y n c h C o m p l e t i o n B e h a v i o u r { ... p u b l i c v o i d o n T i c k () { . . . . if (t h i s. res . r e s u l t O p e r a t i o n S u c c e e d e d () ) { ... p l a y e r = L o g i c T u p l e . p a r s e (" p l a y e r ( n a m e ( ’ " + P l a y e r A g e n t .t h i s. g e t A I D () . g e t N a m e () + " ’) , t e a m ( " + P l a y e r A g e n t .t h i s. t e a m + " ) ) ") ;

f i n a l Out out = new Out ( P l a y e r A g e n t .t h i s. tcid , p l a y e r ) ; P l a y e r A g e n t .t h i s. b r i d g e . a s y n c h r o n o u s I n v o c a t i o n ( out ) ; ... P l a y e r A g e n t .t h i s. a d d B e h a v i o u r (new W a i t T o P l a y B e h a v i o u r ( P l a y e r A g e n t .this , 1 0 0 0 ) ) ; } e l s e { P l a y e r A g e n t .t h i s. a d d B e h a v i o u r (new O b s e r v e G a m e B e h a v i o u r ( P l a y e r A g e n t . this, 1 0 0 0 ) ) ; } t h i s. s t o p () ; } p u b l i c v o i d s e t T u c s o n O p C o m p l e t i o n E v e n t ( T u c s o n O p C o m p l e t i o n E v e n t ev ) { t h i s. res = ev ; } }

Il comportamento WaitToPlayBehaviour permette all’agente di attendere che si raggiunga il numero corretto di giocatori per poter iniziare la parti-

ta e, nel frattempo, di conoscere l’identit`a di tutti i giocatori. Questo viene

realizzato tramite tre rdAll: le prime due (una per squadra) servono per ot- tenere l’elenco delle tuple che corrispondono a player(name(S), team(S))

e conoscere l’identit`a dei giocatori che parteciperanno alla partita, mentre la

terza `e relativa alle tuple di tipo team(S) ancora presenti nel centro di tuple

che indicano quanti giocatori mancano ancora all’appello. Nel momento in

cui sono arrivati tutti i giocatori ed `e nota l’identit`a di compagni di squadra

e avversari, l’agente passa al comportamento TryToGetTheBall.

Si noti che, anche se in questo caso la semantica di invocazione dell’operazione

rdAll `e di tipo sincrono, grazie alla presenza di TuCSoN4JADE l’autono-

mia dell’agente viene preservata ed `e solamente il comportamento ad essere

sospeso in attesa che vengano ricevute le risposte.

p r i v a t e c l a s s W a i t T o P l a y B e h a v i o u r e x t e n d s T i c k e r B e h a v i o u r { p r o t e c t e d v o i d o n T i c k () { ... p l a y e r s _ w h i t e = L o g i c T u p l e . p a r s e (" p l a y e r ( n a m e ( S ) , t e a m ( ’ W H I T E ’) ) ") ; p l a y e r s _ b l a c k = L o g i c T u p l e . p a r s e (" p l a y e r ( n a m e ( S ) , t e a m ( ’ B L A C K ’) ) ") ; m i s s i n g _ p l a y e r s = L o g i c T u p l e . p a r s e (" t e a m ( S ) ") ; f i n a l R d A l l r d a l l _ w h i t e = new R d A l l ( P l a y e r A g e n t .t h i s. tcid , p l a y e r s _ w h i t e ) ; f i n a l R d A l l r d a l l _ b l a c k = new R d A l l ( P l a y e r A g e n t .t h i s. tcid , p l a y e r s _ b l a c k ) ; f i n a l R d A l l r d a l l _ m i s s i n g = new R d A l l ( P l a y e r A g e n t .t h i s. tcid , m i s s i n g _ p l a y e r s ) ; r e s _ w h i t e = P l a y e r A g e n t .t h i s. b r i d g e . s y n c h r o n o u s I n v o c a t i o n ( r d a l l _ w h i t e , null, t h i s) ; r e s _ b l a c k = P l a y e r A g e n t .t h i s. b r i d g e . s y n c h r o n o u s I n v o c a t i o n ( r d a l l _ b l a c k , null, t h i s) ; r e s _ m i s s i n g = P l a y e r A g e n t .t h i s. b r i d g e . s y n c h r o n o u s I n v o c a t i o n ( r d a l l _ m i s s i n g , null, t h i s) ; if ( r e s _ w h i t e != n u l l && r e s _ b l a c k != n u l l && r e s _ m i s s i n g != n u l l) { ... P l a y e r A g e n t .t h i s. a d d B e h a v i o u r (new T r y T o G e t T h e B a l l B e h a v i o u r () ) ; t h i s. s t o p () ; } ... } }

3.4.2 Agente giocatore 43

similare al comportamento ArrivedToPlaygroundBehaviour: quando viene eseguito, effettua una inp asincrona per cercare di ottenere la tupla ball(1) e affida il risultato al comportamento BallResultBehaviour.

All’interno di BallResultBehaviour l’agente attende il risultato della inp ed in seguito si passa al comportamento PlayGameBehaviour con l’indicazione del fatto che il giocatore abbia ottenuto il possesso del pallone o meno. p r i v a t e c l a s s T r y T o G e t T h e B a l l e x t e n d s O n e S h o t B e h a v i o u r {

...

p u b l i c v o i d a c t i o n () { ...

L o g i c T u p l e b a l l = L o g i c T u p l e . p a r s e (" b a l l (1) ") ;

f i n a l Inp inp = new Inp ( P l a y e r A g e n t .t h i s. tcid , b a l l ) ; P l a y e r A g e n t .t h i s. b r i d g e . a s y n c h r o n o u s I n v o c a t i o n ( inp , new B a l l R e s u l t B e h a v i o u r ( P l a y e r A g e n t .this, 1 0 0 0 ) , P l a y e r A g e n t .t h i s) ; ... } } p u b l i c c l a s s B a l l R e s u l t B e h a v i o u r e x t e n d s T i c k e r B e h a v i o u r i m p l e m e n t s I A s y n c h C o m p l e t i o n B e h a v i o u r { ... p u b l i c v o i d o n T i c k () { ... b o o l e a n b a l l = f a l s e; if (t h i s. res . r e s u l t O p e r a t i o n S u c c e e d e d () ) { b a l l = t r u e; } P l a y e r A g e n t .t h i s. a d d B e h a v i o u r (new P l a y G a m e B e h a v i o u r ( P l a y e r A g e n t .this, 5000 , b a l l ) ) ; t h i s. s t o p () ; } p u b l i c v o i d s e t T u c s o n O p C o m p l e t i o n E v e n t ( T u c s o n O p C o m p l e t i o n E v e n t ev ) { t h i s. res = ev ; } }

Il comportamento PlayGameBehaviour estende TickerBehaviour e viene eseguito dall’agente ogni 5 secondi. Esso realizza tutta la logica delle azioni del giocatore durante la partita. Durante l’inizializzazione del comportamen- to, viene creato il produttore Kafka necessario per poter pubblicare gli eventi di gioco generati dall’agente e viene aggiunto il comportamento ObserveGa-

meBehaviour, che `e del tutto similare al comportamento omonimo descritto

per l’agente custode.

Quando l’agente detiene il possesso del pallone, durante l’esecuzione del com- portamento PlayGameBehaviour, effettua la scelta dell’azione da compiere

tramite la selezione casuale di un agente tra tutti i componenti della propria squadra (compreso l’agente stesso che deve effettuare l’azione). Se la scelta ricade su un compagno, l’agente si limita a passargli il pallone inviandogli un messaggio tramite ACC di JADE, altrimenti, se viene estratto l’agente stesso, l’azione risulta essere un tiro a canestro, che in base ad un numero casuale,

pu`o essere un tiro realizzato o sbagliato. In seguito il possesso del pallone

passa poi all’altra squadra: l’agente seleziona un giocatore avversario e gli consegna il pallone inviandogli un messaggio. Non appena viene selezionato il tipo di azione che l’agente deve compiere, questi effettua una pubblicazione del relativo messaggio all’interno del topic Kafka del playground.

Si noti che nel caso in cui il giocatore non `e in possesso del pallone, egli si limi-

ta semplicemente a controllare la sua mailbox tramite il metodo receive() per verificare se qualche giocatore gli ha passato la palla.

p r i v a t e c l a s s P l a y G a m e B e h a v i o u r e x t e n d s T i c k e r B e h a v i o u r { ...

p u b l i c P l a y G a m e B e h a v i o u r ( A g e n t a , l o n g period , b o o l e a n b a l l ) { ...

t h i s. p r o d u c e r = new K a f k a P r o d u c e r<String, String>( p r o d u c e r _ p r o p s ) ; P l a y e r A g e n t .t h i s. a d d B e h a v i o u r (new O b s e r v e G a m e B e h a v i o u r ( P l a y e r A g e n t .this, 1 0 0 0 ) ) ; } p r i v a t e v o i d s h o o t () { ... int s h o t _ p = new R a n d o m () . n e x t I n t ( 1 0 0 ) ; if ( s h o t _ p + m o o d > 40) { s h o t = " s h o t _ m i s s e d "; } e l s e { s h o t = " s h o t _ m a d e "; } J s o n msg = new J s o n () ; msg . add (" t y p e ", s h o t ) ; msg . add (" p l a y e r ", P l a y e r A g e n t .t h i s. g e t A I D () . g e t N a m e () ) ; msg . add (" t e a m ", P l a y e r A g e n t .t h i s. t e a m ) ;

P r o d u c e r R e c o r d<String, String> r e c o r d = new P r o d u c e r R e c o r d<String,

String>( P l a y e r A g e n t .t h i s. p l a y g r o u n d T o p i c , msg . t o S t r i n g () ) ;

t h i s. p r o d u c e r . s e n d ( r e c o r d ) ;

S t r i n g o p p o n e n t = P l a y e r A g e n t .t h i s. o p p o n e n t s . get (new R a n d o m () . n e x t I n t ( P l a y e r A g e n t .t h i s. o p p o n e n t s . s i z e () ) ) ;

A C L M e s s a g e b a l l = new A C L M e s s a g e ( A C L M e s s a g e . P R O P O S E ) ; b a l l . a d d R e c e i v e r (new AID ( o p p o n e n t , AID . I S G U I D ) ) ; b a l l . s e t O n t o l o g y (" b a l l ") ;

b a l l . s e t C o n t e n t ( b a l l _ t o _ o p p o n e n t ) ; s e n d ( b a l l ) ;

}

3.4.2 Agente giocatore 45

J s o n msg = new J s o n () ; msg . add (" t y p e ", " p a s s ") ;

msg . add (" p l a y e r ", P l a y e r A g e n t .t h i s. g e t A I D () . g e t N a m e () ) ; msg . add (" to ", t a r g e t _ a g e n t ) ;

P r o d u c e r R e c o r d<String, String> r e c o r d = new P r o d u c e r R e c o r d<String,

String>( P l a y e r A g e n t .t h i s. p l a y g r o u n d T o p i c , msg . t o S t r i n g () ) ;

t h i s. p r o d u c e r . s e n d ( r e c o r d ) ;

A C L M e s s a g e b a l l = new A C L M e s s a g e ( A C L M e s s a g e . P R O P O S E ) ; b a l l . a d d R e c e i v e r (new AID ( t a r g e t _ a g e n t , AID . I S G U I D ) ) ; b a l l . s e t O n t o l o g y (" b a l l ") ; b a l l . s e t C o n t e n t ( p a s s _ q u a l i t y ) ; s e n d ( b a l l ) ; } p r o t e c t e d v o i d o n T i c k () { if (t h i s. b a l l ) { ... int i n d e x = new R a n d o m () . n e x t I n t ( P l a y e r A g e n t .t h i s. t e a m m a t e s . s i z e () ) ; S t r i n g t a r g e t _ a g e n t = P l a y e r A g e n t .t h i s. t e a m m a t e s . get ( i n d e x ) ; if ( t a r g e t _ a g e n t . e q u a l s ( P l a y e r A g e n t .t h i s. g e t A I D () . g e t N a m e () ) ) { t h i s. s h o o t () ; } e l s e { t h i s. p a s s ( t a r g e t _ a g e n t ) ; } t h i s. b a l l = f a l s e; } e l s e { f i n a l A C L M e s s a g e msg = t h i s. m y A g e n t . r e c e i v e ( M e s s a g e T e m p l a t e . M a t c h O n t o l o g y (" b a l l ") ) ; if ( msg != n u l l) { ... t h i s. b a l l = t r u e; } } } }

L’esecuzione concorrente dei comportamenti PlayGameBehaviour e Obser- veGameBehaviour rappresenta il fulcro dell’integrazione tra Kafka e JADE. Il fatto che ObserveGameBehaviour non sia bloccante, grazie al KafkaCon- sumerAssistant (o eventualemente alla chiamata diretta del metodo poll() con timeout nullo), permette all’agente di sfruttare message passing e publi- sh/subscribe senza che questi interferiscano tra di loro. Si noti inoltre che, utilizzando il metodo consume(timeout ) di KafkaConsumerAssistant con

un timeout molto elevato, `e possibile realizzare la gestione dinamica della

concorrenza tra i due comportamenti. Facendo in modo che ObserveGameBe- haviour rimanga in attesa nella coda dei comportamenti sospesi fino a che la sua esecuzione non diventi significativa, ovvero quando ci sono dei messaggi

Kafka pronti per essere ricevuti. `

E importante anche sottolineare che tali comportamenti permettono di mo- dellare una situazione in cui coesiste nell’agente una condotta sia proattiva

che reattiva, mantendo intatta la sua autonomia. L’agente `e infatti capace

di eseguire azioni proattive quando ha il pallone “tra le mani” e agire in maniera reattiva nella gestione dei messaggi (sia quelli JADE per il possesso del pallone che quelli Kafka per gli eventi di gioco), senza che sia uno dei due atteggiamenti a comandare il corso delle sue azioni. Si noti che tale situazione non sarebbe facilmente modellabile tramite ELDA, a causa del problema del- l’inversione del controllo che non garantisce alcuna separazione tra il volere dell’agente e il flusso degli eventi.

Il codice completo del caso di studio e dell’esempio mostrato in calce al capito-

lo 2 `e disponibile nel repository https://github.com/marcozaccheroni2/

3.4.2 Agente giocatore 47

Figura 3.1: Diagramma di interazione degli agenti all’interno del Playground in cui sono evidenziate le interazioni tramite TuCSon (in arancione), JADE (in azzurro) e Kafka (in verde)

Conclusioni e sviluppi futuri

Giunti al termine `e opportuno analizzare il lavoro svolto, cercando di indi-

viduare i risultati raggiunti e quelli mancati: in modo da offrire interessanti spunti per delle future argomentazioni che integrino ulteriormente il presente trattato confermandone o confutandone il contenuto.

Innanzitutto `e bene ricordare l’obiettivo della tesi, al fine di poter valutare

correttamente se esso sia stato raggiunto o meno: come `e stato gi`a detto,

il proposito principale era quello di mostrare come i due stili architetturali apparentemente molto diversi, che caratterizzano i Sistemi Multi-Agente e i

Sistemi ad Eventi, presentino in realt`a numerosi punti in comune che ren-

dono possibile la loro integrazione al fine di realizzare un’unica architettura

capace di sfruttare al meglio le potenzialit`a di entrambe le tipologie di sistemi.

Si confida nel raggiungimento di tali obiettivi, ad opera dei seguenti capitoli: • il capitolo 2 dovrebbe aver descritto in maniera esaustiva quali siano i concetti comuni ad entrambi gli stili architetturali e come questi pos- sano essere integrati rispettando i principi fondamentali di entrambe le tipologie di sistemi;

• il capitolo 3 dovrebbe aver mostrato un utile scenario in cui `e sfruttata l’integrazione di JADE, TuCSoN e Kafka, mettendo in evidenza come sia possibile integrare questi framework per utilizzare nel miglior modo possibile i loro diversi modelli di coordinazione all’interno di un unico sistema.

Analizzando il risultato ultimo della tesi, ovvero l’integrazione di JADE,

La progettazione e l’implementazione del componente che garantisce il disac- coppiamento di agente e coordination media, nell’integrazione tra JADE e Kafka, ha permesso di dimostrare come sia fondamentale che vengano gestite adeguatamente le dipendenze all’interno di un sistema molto complesso, ga- rantendo l’autonomia dei suoi componenti, in modo che l’interazione possa

essere utilizzata in maniera efficace per gestire la complessit`a del sistema.

A tale proposito, un possibile sviluppo futuro potrebbe essere l’estensione del componente KafkaConsumerAssistant in modo da poterlo inserire al- l’interno dell’infrastruttura JADE cos`ı da gettare le basi, includendo anche TuCSoN4JADE, per la realizzazione di un unico framework di sviluppo per i Sistemi Multi-Agente basati su eventi.

Bibliografia

[1] Danny Weyns, Andrea Omicini, and James J. Odell. Environment as a first class abstraction in multi-agent systems. Autonomous Agents and Multi-Agent Systems, 14(1):5–30, February 2007. Special Issue on Environments for Multi-agent Systems.

[2] Andrea Omicini, Alessandro Ricci, and Mirko Viroli. Artifacts in

the A&A meta-model for multi-agent systems. Autonomous Agents

and Multi-Agent Systems, 17(3):432–456, December 2008. Special Is- sue on Foundations, Advanced Topics and Industrial Perspectives of Multi-Agent Systems.

[3] Fabio Bellifemine, A Poggi, and Giovanni Rimassa. JADE - A FIPA- compliant agent framework, pages 97–108. The Practical Application Company Ltd., 1999.

[4] Andrea Omicini and Franco Zambonelli. Coordination for Internet ap- plication development. Autonomous Agents and Multi-Agent Systems, 2(3):251–269, September 1999. Special Issue: Coordination Mechanisms for Web Agents.

[5] Andrea Omicini and Enrico Denti. From tuple spaces to tuple centres. Science of Computer Programming, 41(3):277–294, November 2001. [6] Andrea Omicini. Formal ReSpecT in the A&A perspective. Electronic

Notes in Theoretical Computer Science, 175(2):97–117, June 2007. 5th International Workshop on Foundations of Coordination Languages and Software Architectures (FOCLASA’06), CONCUR’06, Bonn, Germany, 31 August 2006. Post-proceedings.

[7] LUDGER FIEGE, GERO M ¨UHL, and FELIX C. G ¨ARTNER. Modular event-based systems. The Knowledge Engineering Review, 17:359–388, 12 2002.

[8] Giancarlo Fortino, Alfredo Garro, Samuele Mascillaro, and Wilma Rus- so. Modeling multi-agent systems through event-driven lightweight dsc- based agents. In Proceedings of 6th International Workshop on “From Agent Theory to Agent Implementation”, 2008.

[9] Fortino G, Frattolillo F, Russo W, and ZIMEO E. Mobile active objec- ts for highly dynamic distributed computing. In Proceedings of IEEE International Parallel and Distributed Processing Symposium, pages –, April 15-19 - 2002.

[10] David Harel. Statecharts: a visual formalism for complex systems.

Science of Computer Programming, 8(3):231 – 274, 1987.

[11] Foundation for Intelligent Physical Agents (FIPA). Agent management support for mobility specification, 2002.

Ringraziamenti

Era il lontano 2006, quando per la prima volta misi piede all’universit`a, in

una cupa e uggiosa giornata di fine settembre (in realt`a non ricordo assolu-

tamente come fosse il tempo, non sono nemmeno sicuro che fosse settembre,

per`o nei miei ricordi era freddo, umido e anche tutto in bianco e nero). Ora

dopo la bellezza di 10 anni (mi vergogno un po’ a dirlo, ma tant’`e) `e giunto

il momento che il mio percorso ad Ingegneria arrivi finalmente al termine.

Con tutta probabilit`a non sarei mai riuscito ad arrivare qui, oggi, se non

avessi avuto la fortuna di avere un sacco di persone accanto, che mi hanno spronato, supportato e sopportato per tutto questo tempo. Ringraziare tutti

credo sia praticamente impossibile, ma cercher`o di fare del mio meglio.

Grazie alla Cate, per essere capace di darmi sempre forza e serenit`a, in qua-

lunque occasione, anche semplicemente standomi accanto.

Grazie a mio babbo e a mia mamma, per non avermi mai fatto mancare nien-

te ed aver fatto sempre il massimo per aiutarmi a superare tutte le difficolt`a

in modo che potessi arrivare fino a qui.

Grazie ai mio nonno, per “aver fatto i bambini insieme” e per avermi inse-

gnato come affrontare la vita con serenit`a, accettando quello che capita con

un sorriso, cercando sempre di trovare il lato positivo. Vorrei tanto che fosse qui per poter condividere anche con lui questo momento.

Grazie a mia nonna per essere sempre cos`ı forte e per essersi ogni volta fatta in quattro per supportarmi in tutti i modi possibili e non farmi mai sentire solo.

a completarla.

Grazie a Piero, Busca e Richard per tutti i momenti passati assieme in questi anni di magistrale tra robot, parcheggi, pianeti e fantasmi.

Grazie a Piero anche per Whale TRUE, TV Files e tutti i progetti fighissimi, mai realizzati, per cui adesso (forse) possiamo trovare il tempo.

Grazie ad Ale, Cianca, Gaia, Giova, Harry, Mike e Pira. Prima di conoscerli

ero quello che si pu`o definire un branco con un lupo solo, ora invece siamo in

tanti nel branco.

Grazie a tutto il Wuber: Sacco, Zatto, Mela, Dulo, Riccio, Manina, Masi, Edo, Greggione, Caffi, Bando, Johnny, Ross e Capitan Cangini, per tutte le

serate passate in palestra, perch´e certe volte giocare assieme a voi era l’unico

modo per riuscire a distrarmi.

Grazie al Prof. Omicini, per la Sua inesauribile disponibilit`a e per la Sua

simpatia.

Grazie alla mia Birbina, per tutte le bellissime chiacchierate che facciamo

e per avermi insegnato che l’affetto incondizionato `e una cosa meravigliosa,

anche se `e un animalino a dartelo.

Grazie infine a Wikipedia e StackOverflow per l’inestimabile aiuto che mi

hanno offerto in questi anni di universit`a, se sono riuscito a laurearmi `e

Documenti correlati