Jade vers OMAS et OMAS vers Jade
Transcription
Jade vers OMAS et OMAS vers Jade
IA04 Projet 1 : OMAS vs JADE Automne 2007 Dernière mise à jour le 25 octobre 2007 Cyril Arnaud Maxime Robache 1 PASSAGE DE OMAS À JADE 1 Passage de OMAS à JADE L’objectif de cette partie est l’implémentation de l’application factorielle sur la plate-forme JADE avec un agent factorielle qui ne sait pas multiplier et un certain nombre d’agents multiplicateurs qui sous-traiterons avec des particularités définies que nous ferons évoluer au fil du travail. 1.1 Codage de l’application 1.1.1 Agent multiplicateur L’agent multiplicateur est un agent simple qui fait appel à un behaviour dérivant de la classe SimpleBehaviour. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 /∗ F i c h i e r mul1 . j a v a ∗/ package f a c t o 2 1 ; import import import import s i m p l e a g e n t . ResponderBahaviour ; j a d e . c o r e . AID ; j a d e . c o r e . Agent ; j a d e . l a n g . a c l . ACLMessage ; /∗ Mul1 e s t l ’ a g e n t m u l t i p l i c a t e u r numéro 1 ∗/ p u b l i c c l a s s Mul1 e x t e n d s Agent { protected void setup ( ) { AID dt = getAMS ( ) ; System . out . p r i n t l n ( ” H e l l o . My name i s ”+t h i s . getLocalName ( ) ) ; addBehaviour ( new Behaviour mul ( t h i s ) ) ; } } /∗ Fin de f i c h i e r ∗/ 1.1.2 Comportement de l’agent multiplicateur La classe Behaviour mul est la classe qui reçoit les messages de l’agent factorielle (qui sera developpé par la suite), traite la multiplication et envoie un message avec le résultat. Elle est donnée ci-dessous : 1 2 3 4 5 6 7 8 9 10 11 12 13 /∗ F i c h i e r Behaviour mul . j a v a ∗/ package f a c t o 2 1 ; import import import import import import import j a d e . c o r e . AID ; j a d e . c o r e . Agent ; j a d e . l a n g . a c l . ACLMessage ; j a d e . l a n g . a c l . MessageTemplate ; j a d e . c o r e . b e h a v i o u r s . Sim p le B e ha vi o ur ; java . lang . String ; j a v a . l a n g . Double ; p u b l i c c l a s s Behaviour mul e x t e n d s Sim p le B e ha vi o ur { 1 1 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 PASSAGE DE OMAS À JADE p r i v a t e s t a t i c f i n a l MessageTemplate mt = MessageTemplate . MatchPerformative ( ACLMessage .REQUEST) ; p u b l i c Behaviour mul ( Agent a g e n t ) { super ( agent ) ; } p r i v a t e v o i d sendMessage ( i n t a ) { ACLMessage a c l M e s s a g e = new ACLMessage ( ACLMessage . REQUEST) ; a c l M e s s a g e . a d d R e c e i v e r ( new AID( ”F1@jonas : 1 0 9 9 /JADE”) ) ; a c l M e s s a g e . s e t C o n t e n t ( a+” ”) ; System . out . p r i n t l n ( a c l M e s s a g e ) ; t h i s . myAgent . send ( a c l M e s s a g e ) ; } public void action ( ) { while ( true ) { ACLMessage a c l M e s s a g e = myAgent . r e c e i v e (mt) ; i f ( a c l M e s s a g e != n u l l ) { System . out . p r i n t l n ( myAgent . getLocalName ( )+” : I r e c e i v e d message . \ n ”+ aclMessage ) ; System . out . p r i n t l n ( ”Content : ”+ aclMessage . getContent ( ) ) ; 36 37 38 S t r i n g [ ] tab ; tab = a c l M e s s a g e . g e t C o n t e n t ( ) . t o S t r i n g ( ) . s p l i t ( ” ”) ; System . out . p r i n t l n ( ” t a b l e a u ”+tab [ 0 ] + ” ”+tab [ 1 ] ) ; 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 i n t a=I n t e g e r . p a r s e I n t ( tab [ 0 ] ) ; i n t b=I n t e g e r . p a r s e I n t ( tab [ 1 ] ) ; System . out . p r i n t l n ( a+”x ”+b+”=”+a ∗b ) ; l o n g time =( l o n g ) ( ( Math . random ( ) ∗ (2500 −500) ) + 5 0 0 ) ; System . out . p r i n t l n ( ”Time : ”+time ) ; t r y { Thread . s l e e p ( time ) ; } catch ( InterruptedException e ) { e . printStackTrace () ; } sendMessage ( a ∗b ) ; } else { t h i s . block () ; } } } p u b l i c b o o l e a n done ( ) { return f a l s e ; 2 1 63 64 65 66 PASSAGE DE OMAS À JADE } } /∗ Fin de f i c h i e r ∗/ Ce comportement prévoit l’attente d’un temps aléatoire entre 0,5 et 2,5 secondes avant la réponse. 1.1.3 L’agent factorielle L’agent factorielle, ne sachant pas lui-même multiplier, est celui qui va envoyer aux agents multiplicateurs le travail qu’ils ont à faire. Il va également centraliser les réponses pour rendre à l’utilisateur le résultat du calcul qu’il attend. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 /∗ F i c h i e r Facto . j a v a ∗/ package f a c t o 2 1 ; import import import import j a d e . c o r e . AID ; j a d e . c o r e . Agent ; j a d e . l a n g . a c l . ACLMessage ; j a d e . l a n g . a c l . MessageTemplate ; //F1 e s t l ’ a g e n t q u i ré c u pè r e l e c a l c u l à f a i r e dans l e s arguments de lancement de l ’ a p p l i c a t i o n p u b l i c c l a s s Facto e x t e n d s Agent { protected void setup ( ) { System . out . p r i n t l n ( ” H e l l o . My name i s ”+t h i s . getLocalName ( ) ) ; 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 MessageTemplate mt = MessageTemplate . MatchPerformative ( ACLMessage . REQUEST) ; // RECUPERATION DU NOMBRE i n t nb=9; i n t nb2=nb −1; // ENVOI DES CALCULS A FAIRE AUX AGENTS M1 e t M2 ACLMessage a c l M e s s a g e ; w h i l e ( nb2 !=1) { sendMessage ( nb , nb2 ) ; a c l M e s s a g e=t h i s . b l o c k i n g R e c e i v e (mt) ; nb=I n t e g e r . p a r s e I n t ( a c l M e s s a g e . g e t C o n t e n t ( ) ) ; nb2−−; } // AFFICHAGE DU RESULTAT System . out . p r i n t l n ( ”RESULTAT : ”+nb ) ; } // Méthode pour e n v o y e r l e c a l c u l à f a i r e p r i v a t e v o i d sendMessage ( i n t a , i n t b ) { 3 1 PASSAGE DE OMAS À JADE 41 ACLMessage a c l M e s s a g e = new ACLMessage ( ACLMessage . REQUEST) ; 42 43 44 45 // Envoi à un d e s deux a g e n t s m u l t i p l i c a t e u r au h a s a r d d o u b l e i =Math . random ( ) ; i f ( i <0.5) a c l M e s s a g e . a d d R e c e i v e r ( new AID( ”M1@jonas : 1 0 9 9 /JADE”) ) ; else a c l M e s s a g e . a d d R e c e i v e r ( new AID( ”M2@jonas : 1 0 9 9 / JADE”) ) ; a c l M e s s a g e . s e t C o n t e n t ( a+” ”+b ) ; System . out . p r i n t l n ( a c l M e s s a g e ) ; t h i s . send ( a c l M e s s a g e ) ; 46 47 48 49 50 51 52 53 } } /∗ Fin de f i c h i e r ∗/ 1.2 Envoi des message en Broadcast Dans cette partie, nous allons modifier le code source écrit précédement afin d’envoyer les ordres de multiplication non plus à un agent au hasard, mais à tous les agents. L’agent factorielle ne prendra en compte que la première réponse qu’il recevra. Pour ce faire, l’envoi des messages dans l’agent factorielle devient : 1 2 a c l M e s s a g e . a d d R e c e i v e r ( new AID( ”M1@jonas : 1 0 9 9 /JADE”) ) ; a c l M e s s a g e . a d d R e c e i v e r ( new AID( ”M2@jonas : 1 0 9 9 /JADE”) ) ; Dans le cas où nous aurions plus de deux agents multiplicateurs, il faudrait écrire une boucle pour ajouter tous les agents à la liste des receveurs. Il est également nécessaire de modifier le contenu du message de retour : 1 a c l M e s s a g e . s e t C o n t e n t ( a+” ”+b+” ”+r e s ) ; Ainsi que la réception des messages par l’agent factorielle : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 w h i l e ( b o o l ==0) { a c l M e s s a g e=t h i s . b l o c k i n g R e c e i v e (mt) ; S t r i n g [ ] tab ; tab = a c l M e s s a g e . g e t C o n t e n t ( ) . t o S t r i n g ( ) . s p l i t ( ” ”) ; i n t a=I n t e g e r . p a r s e I n t ( tab [ 0 ] ) ; i n t b=I n t e g e r . p a r s e I n t ( tab [ 1 ] ) ; i f ( a==nb && b==nb2 ) { nb=I n t e g e r . p a r s e I n t ( tab [ 2 ] ) ; b o o l =1; } } 1.3 Grands nombres Si l’on veut calculer des factorielles avec des grands nombres (50 par exemple) la taille du type ”entier” sera dépassée. Pour éviter cela, il est possible d’utiliser le type double par exemple qui permettra de calculer de plus grands nombres. 4 1 PASSAGE DE OMAS À JADE 1.4 Timeout Dans le cas de non-réponse de l’un des agents multiplicateurs il est préférable de gérer un timeout. Pour cela, il suffit d’intégrer à l’agent factorielle le timeout dans la fonction qui définit la réception des messages : 1 2 3 l o n g time =1000; a c l M e s s a g e=t h i s . b l o c k i n g R e c e i v e (mt , time ) ; Il faut également modifier le comportement de l’agent en cas de timeout (qui est repérable par un message NULL) : 1 2 3 i f ( a c l M e s s a g e != n u l l ) { System . out . p r i n t l n ( t h i s . getLocalName ( )+” : I r e c e i v e d message . FROM”+a c l M e s s a g e . g e t S e n d e r ( ) ) ; S t r i n g [ ] tab ; tab = a c l M e s s a g e . g e t C o n t e n t ( ) . t o S t r i n g ( ) . s p l i t ( ” ”) ; i n t a=I n t e g e r . p a r s e I n t ( tab [ 0 ] ) ; i n t b=I n t e g e r . p a r s e I n t ( tab [ 1 ] ) ; 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 i f ( a==nb && b==nb2 ) { nb=I n t e g e r . p a r s e I n t ( tab [ 2 ] ) ; nb2−−; b o o l =1; } } else { b o o l =1; System . out . p r i n t l n ( ”TIMEOUT ! ! ”) ; } 1.5 Contract-Net Le protocole Contract-Net étant implémenté directement dans Jade au travers d’un certain nombre de prototypes (Contract-Net initiator et Contract-Net responder), il suffit, pour réecrire l’application de traiter les opérations à effectuer suivant les messages reçus. Grâce aux fonctions de type handle, cela se fait très facilement. 1.5.1 1 2 3 4 5 6 7 8 9 10 11 12 Contract-Net Initiator /∗ F i c h i e r f a c C o n t r a c t N e t I n i t i a t o r . j a v a ∗/ package ContractNet ; import import import import import import import import j a d e . c o r e . Agent ; j a d e . c o r e . AID ; j a d e . l a n g . a c l . ACLMessage ; jade . proto . ContractNetInitiator ; j a d e . domain . FIPANames ; j a d e . domain . FIPAAgentManagement . DFAgentDescription ; j a d e . domain . FIPAException ; j a d e . domain . DFService ; 5 1 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 PASSAGE DE OMAS À JADE import import import import import import import import import import j a d e . domain . FIPAAgentManagement . S e r v i c e D e s c r i p t i o n ; jade . core . behaviours . ∗ ; java . io . ∗ ; java . net . ∗ ; java . lang . ∗ ; java . u t i l . ∗ ; j a v a . u t i l . Random ; j a v a . u t i l . Date ; j a v a . u t i l . Vector ; j a v a . u t i l . Enumeration ; p u b l i c c l a s s f a c C o n t r a c t N e t I n i t i a t o r e x t e n d s Agent { AID [ ] mulAgents ; Integer FactValueInteger ; String FactValueString ; i n t FactValue , CurrentValue , C u r r e n t T o t a l ; p r i v a t e Object o b j = new Object ( ) ; protected void setup ( ) { try { synchronized ( obj ) { obj . wait (3000) ; } } c a t c h ( I n t e r r u p t e d E x c e p t i o n ex ) {} Object [ ] a r g s = getArguments ( ) ; FactValue = 9 ; CurrentValue = FactValue ; CurrentTotal = 1 ; // Recherche d e s a g e n t s m u l t i p l i c a t e u r s DFAgentDescription t e m p l a t e = new DFAgentDescription ( ) ; S e r v i c e D e s c r i p t i o n sd = new S e r v i c e D e s c r i p t i o n ( ) ; sd . setType ( ” m u l t i p l y ”) ; t e m p l a t e . a d d S e r v i c e s ( sd ) ; try { DFAgentDescription [ ] r e s u l t = DFService . s e a r c h ( t h i s , template ) ; System . out . p r i n t l n ( ”Les a g e n t s m u t l i p l i c a t e u r s ont é t é t r o u vé s : ”) ; mulAgents = new AID [ r e s u l t . l e n g t h ] ; f o r ( i n t i = 0 ; i < r e s u l t . l e n g t h ; ++i ) { mulAgents [ i ] = r e s u l t [ i ] . getName ( ) ; System . out . p r i n t l n ( mulAgents [ i ] ) ; } } c a t c h ( FIPAException f e ) { fe . printStackTrace () ; } // C ré a t i o n du message CFP ACLMessage msg = new ACLMessage ( ACLMessage .CFP) ; 6 1 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 PASSAGE DE OMAS À JADE f o r ( i n t i = 0 ; i < mulAgents . l e n g t h ; ++i ) { msg . a d d R e c e i v e r ( mulAgents [ i ] ) ; } msg . s e t P r o t o c o l ( FIPANames . I n t e r a c t i o n P r o t o c o l .FIPA CONTRACT NET ); // Demande une ré p o n s e en 5 s e c o n d e s msg . setReplyByDate ( new Date ( System . c u r r e n t T i m e M i l l i s ( ) + 5 0 0 0 ) ) ; S t r i n g message = new S t r i n g ( ) ; message = C u r r e n t T o t a l + ” , ” + CurrentValue −−; msg . s e t C o n t e n t ( message ) ; addBehaviour ( new C o n t r a c t N e t I n i t i a t o r ( t h i s , msg ) { p r o t e c t e d v o i d h a n d l e R e f u s e ( ACLMessage r e f u s e ) { System . out . p r i n t l n ( ”Agent ” + r e f u s e . g e t S e n d e r ( ) . getName ( ) +” a r e f u s é ”) ; } p r o t e c t e d v o i d h a n d l e F a i l u r e ( ACLMessage f a i l u r e ) { i f ( f a i l u r e . g e t S e n d e r ( ) . e q u a l s ( myAgent . getAMS ( ) ) ) { // Le r e c e v e u r n ’ e x i s t e pas System . out . p r i n t l n ( ”Responder d o e s not e x i s t ”) ; } else { System . out . p r i n t l n ( ”Agent ” + f a i l u r e . g e t S e n d e r ( ) . getName ( ) +” f a i l e d ”) ; } // Immediate f a i l u r e −−> we w i l l not r e c e i v e a r e s p o n s e from t h i s a g e n t } p r o t e c t e d v o i d h a n d l e A l l R e s p o n s e s ( Vector r e s p o n s e s , Vector acceptances ) { i f ( r e s p o n s e s . s i z e ( ) < mulAgents . l e n g t h ) { // Some r e s p o n d e r didn ’ t r e p l y w i t h i n t h e s p e c i f i e d timeout System . out . p r i n t l n ( ”Timeout e x p i r e d : m i s s i n g ” +(mulAgents . l e n g t h − r e s p o n s e s . s i z e ( ) )+” r e s p o n s e s ”) ; } // E v a l u a t e P r o p o s a l s , t a k e t h e f a s t e s t one int response ; i n t min time=−1; AID b e s t P r o p o s e r = n u l l ; ACLMessage a c c e p t = n u l l ; Enumeration e = r e s p o n s e s . e l e m e n t s ( ) ; w h i l e ( e . hasMoreElements ( ) ) { ACLMessage msg = ( ACLMessage ) e . nextElement ( ) ; i f ( msg . g e t P e r f o r m a t i v e ( ) == ACLMessage .PROPOSE ) { ACLMessage r e p l y = msg . c r e a t e R e p l y ( ) ; 7 1 PASSAGE DE OMAS À JADE 112 r e p l y . s e t P e r f o r m a t i v e ( ACLMessage . REJECT PROPOSAL) ; r e s p o n s e = ( new I n t e g e r ( msg . g e t C o n t e nt () ) ) . intValue () ; a c c e p t a n c e s . addElement ( r e p l y ) ; i f ( min time == −1) min time=r e s p o n s e ; i f ( r e s p o n s e <= min time ) { b e s t P r o p o s e r = msg . g e t S e n d e r ( ) ; a c c e p t=r e p l y ; } 113 114 115 116 117 118 119 120 121 122 123 } } // Accept t h e p r o p o s a l o f t h e b e s t ( i n t h i s c a s e t h e f a s t e s t ) proposer i f ( a c c e p t != n u l l ) { System . out . p r i n t l n ( ”A c c e p t i n g p r o p o s a l ” + b e s t P r o p o s e r +” from r e s p o n d e r ” + b e s t P r o p o s e r . getName ( ) ) ; a c c e p t . s e t P e r f o r m a t i v e ( ACLMessage . ACCEPT PROPOSAL) ; } 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 } // Content o f Inform message i s m u l t i p l i c a t i o n o f v a l u e s p r o t e c t e d v o i d h a n d l e I n f o r m ( ACLMessage i n f o r m ) { C u r r e n t T o t a l = ( new I n t e g e r ( i n f o r m . g e t C o n t e n t ( ) ) ) . intValue () ; i f ( CurrentValue >= 2 ) { ACLMessage msg = new ACLMessage ( ACLMessage .CFP) ; f o r ( i n t i = 0 ; i < mulAgents . l e n g t h ; ++i ) { msg . a d d R e c e i v e r ( mulAgents [ i ] ) ; } msg . s e t P r o t o c o l ( FIPANames . InteractionProtocol . FIPA CONTRACT NET) ; // We want t o r e c e i v e a r e p l y i n 10 secs msg . setReplyByDate ( new Date ( System . currentTimeMillis ( ) + 5000) ) ; S t r i n g message = new S t r i n g ( ) ; message = C u r r e n t T o t a l + ” , ” + CurrentValue −−; msg . s e t C o n t e n t ( message ) ; // Behaviour i s r e s e t e d , t o c o n t i n u e operation . r e s e t ( msg ) ; } else { System . out . p r i n t l n ( ”Agent ” + i n f o r m . g e t S e n d e r ( ) . getName ( ) +” s u c c e s s f u l l y performed t h e r e q u e s t e d a c t i o n ”) ; 8 1 PASSAGE DE OMAS À JADE 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 System . out . p r i n t l n ( ”T o t a l : ” + CurrentTotal ) ; } } }) ; /∗ Fin de f i c h i e r ∗/ \ end { l s t l i s t i n æ } \ s u b s u b s e c t i o n { Contract−Net Responder } \ begin { l s t l i s t i n g } /∗ F i c h i e r f a c C o n t r a c t N e t R e s p o n d e r . j a v a ∗/ package ContractNet ; import import import import import import import import import import import import import import import import import import import import j a d e . c o r e . Agent ; j a d e . c o r e . AID ; j a d e . l a n g . a c l . ACLMessage ; j a d e . l a n g . a c l . MessageTemplate ; j a d e . p r o t o . ContractNetResponder ; j a d e . domain . FIPANames ; j a d e . domain . FIPAAgentManagement . NotUnderstoodException ; j a d e . domain . FIPAAgentManagement . R e f u s e E x c e p t i o n ; j a d e . domain . FIPAAgentManagement . F a i l u r e E x c e p t i o n ; java . u t i l . StringTokenizer ; j a d e . domain . DFService ; j a d e . domain . FIPAException ; j a d e . domain . FIPAAgentManagement . DFAgentDescription ; j a d e . domain . FIPAAgentManagement . S e r v i c e D e s c r i p t i o n ; java . io . ∗ ; java . net . ∗ ; java . lang . ∗ ; j a v a . l a n g . Double ; java . u t i l . ∗ ; j a v a . u t i l . Random ; p u b l i c c l a s s f a c C o n t r a c t N e t R e s p o n d e r e x t e n d s Agent { p r i v a t e Object o b j = new Object ( ) ; protected void setup ( ) { System . out . p r i n t l n ( ”Agent ” + getLocalName ( ) + ” w a i t i n g f o r CFP . . . ”) ; MessageTemplate t e m p l a t e = MessageTemplate . and ( MessageTemplate . MatchProtocol ( FIPANames . I n t e r a c t i o n P r o t o c o l . FIPA CONTRACT NET) , MessageTemplate . MatchPerformative ( ACLMessage .CFP) ) ; DFAgentDescription dfd = new DFAgentDescription ( ) ; dfd . setName ( getAID ( ) ) ; S e r v i c e D e s c r i p t i o n sd = new S e r v i c e D e s c r i p t i o n ( ) ; sd . setType ( ” m u l t i p l y ”) ; sd . setName ( ” m u l t i p l y i n g −a g e n t ”) ; dfd . a d d S e r v i c e s ( sd ) ; 9 1 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 PASSAGE DE OMAS À JADE try { DFService . r e g i s t e r ( t h i s , dfd ) ; } c a t c h ( FIPAException f e ) { fe . printStackTrace () ; } // Responder Behaviour i s C y c l i c addBehaviour ( new ContractNetResponder ( t h i s , t e m p l a t e ) { i n t value1 , v a l u e 2 ; p r o t e c t e d ACLMessage handleCfp ( ACLMessage c f p ) throws NotUnderstoodException , R e f u s e E x c e p t i o n { Random g e n e r a t o r = new Random ( ) ; System . out . p r i n t l n ( ”Agent ” + getLocalName ( ) +” : CFP r e c e i v e d from ” +c f p . g e t S e n d e r ( ) . getName ( ) + ” . Action i s ” + c f p . g e t C o n t e n t () ) ; S t r i n g T o k e n i z e r v a l u e s = new S t r i n g T o k e n i z e r ( c f p . g e t t C o n t e n t ( ) , ” , ”) ; v a l u e 1 = I n t e g e r . p a r s e I n t ( v a l u e s . nextToken ( ) ) ; v a l u e 2 = I n t e g e r . p a r s e I n t ( v a l u e s . nextToken ( ) ) ; d o u b l e r = ( g e n e r a t o r . nextDouble ( ) ∗ 2 ) + 0 . 5 ; i n t w = ( i n t ) ( r ∗ 1000) ; try { synchronized ( obj ) { o b j . w a i t (w) ; } } c a t c h ( I n t e r r u p t e d E x c e p t i o n ex ) {} // E v a l u a t e A c t i o n r e t u r n system time i n ms , t o l e t f a c A g e n t s e l e c t t h e f a s t e s t mulAgent int proposal = evaluateAction () ; i f ( p r o p o s a l == 1 ) { // We p r o v i d e a p r o p o s a l System . out . p r i n t l n ( ”Agent ” + getLocalName ( ) + ” : P r o p o s i n g ” + proposal ) ; ACLMessage p r o p o s e = c f p . c r e a t e R e p l y ( ) ; p r o p o s e . s e t P e r f o r m a t i v e ( ACLMessage . PROPOSE) ; propose . setContent ( S t r i n g . valueOf ( proposal ) ) ; return propose ; } else { // We r e f u s e t o p r o v i d e a p r o p o s a l System . out . p r i n t l n ( ”Agent ” + getLocalName ( ) + ” : R e f u s e ”) ; throw new R e f u s e E x c e p t i o n ( ” e v a l u a t i o n − f a i l e d ”) ; } 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 } p r o t e c t e d ACLMessage p r e p a r e R e s u l t N o t i f i c a t i o n ( ACLMessage cfp , ACLMessage propose , ACLMessage a c c e p t ) throws FailureException { 10 1 PASSAGE DE OMAS À JADE 246 System . out . p r i n t l n ( ”Agent ” + getLocalName ( ) + ” : P r o p o s a l a c c e p t e d ”) ; int result ; 247 248 249 250 251 252 // p e r f o r m A c t i o n r e t u r n r e s u l t o f v a l u e 1 ∗ v a l u e 2 r e s u l t = p e r f o r m A c t i o n ( value1 , v a l u e 2 ) ; i f ( r e s u l t > 0) { System . out . p r i n t l n ( ”Agent ” + getLocalName ( ) +” : Action s u c c e s s f u l l y performed ”) ; ACLMessage i n f o r m = a c c e p t . c r e a t e R e p l y () ; i n f o r m . s e t P e r f o r m a t i v e ( ACLMessage . INFORM) ; inform . setContent ( S t r i n g . valueOf ( r e s u l t )); return inform ; } else { System . out . p r i n t l n ( ”Agent ” + getLocalName ( ) + ” : Action e x e c u t i o n f a i l e d ”) ; throw new F a i l u r e E x c e p t i o n ( ” unexpected−e r r o r ”) ; return inform ; } else { System . out . p r i n t l n ( ”Agent ” + getLocalName ( ) + ” : Action e x e c u t i o n f a i l e d ”) ; throw new F a i l u r e E x c e p t i o n ( ” unexpected−e r r o r ”) ; } 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 } p r o t e c t e d v o i d h a n d l e R e j e c t P r o p o s a l ( ACLMessage cfp , ACLMessage propose , ACLMessage r e j e c t ) { System . out . p r i n t l n ( ”Agent ” + getLocalName ( ) + ” : P r o p o s a l r e j e c t e d ”) ; } 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 }) ; } private int evaluateAction () { // Return system time i n ms return ( int ) (1) ; } p r i v a t e i n t p e r f o r m A c t i o n ( i n t value1 , i n t v a l u e 2 ) { return ( value1 ∗ value2 ) ; } } /∗ Fin de f i c h i e r ∗/ 11 2 PASSAGE DE JADE À OMAS 1.6 Comparaison JADE vs OMAS Après la traduction d’une application originellement développée en OMAS vers JADE, nous pouvons noter quelques dissemblances dans les méthodes d’implémentation. Les caractéristiques objets de Java permettent de déclarer des classes, notamment d’agent, ce qui n’est pas possible en Lisp. Cela permet d’instancier plusieurs fois chaque classe sans avoir à déclarer plusieurs agents dès le départ. En revanche, nous pouvons égelement dire que le système de comportement (skills) de OMAS est plus clair et plus simple à comprendre que celui de JADE. Alors que OMAS est prévu pour, nous sommes obligé avec JADE d’utiliser des éléments de programmations (boucles, conditions etc.) qui alourdissent le code source. Globalement, il semble que plus l’application est importante (en terme de taille) et plus OMAS devrait être préconisé car plus simple et plus clair. 2 Passage de JADE à OMAS Ce programme permet de reproduire le concept d’une transaction entre un acheteur BOOKBUYER et plusieurs vendeurs BOOK-SELLER. L’acheteur souhaite acheter un livre (ou des livres) à moindre prix. Pour chaque titre de livre à acheter, il diffuse aux vendeurs le titre de son livre et les vendeurs lui retourne une proposition de prix si ils l’ont à disposition. L’acheteur choisi le plus bas prix, valide la transaction. Si l’acheteur ne reçoit pas d’offre, il réémet sa demande. L’acheteur se termine quand sa liste de livre est vide. 2.1 Agent BOOK-BUYER L’agent BOOK-BUYER récupère la liste de livre dans les arguments. Son fonctionnement peut se résumer comme suit : Tant que la liste de livre n’est pas vide : Envoi une demande de prix pour le premier titre de la liste Attends une réponse pendant N sinon continue Fin tant que Arrivée de réponses : Envoi d’une validation au vendeur Supprime le titre du livre de la liste 1 2 3 4 5 6 7 8 9 10 11 ;;;======================== ; ;; I N I T ;;;======================== ( in−package : omas ) ( setq ∗ i n i t − l i s t ∗ ’ ( ( ∗ debugging ∗ t ) ( : local−coterie−name : thor ) 12 2 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 PASSAGE DE JADE À OMAS ( : a p p l i c a t i o n − f o l d e r BOOK) ( : a g e n t s BOOK−SELLER−1 BOOK−SELLER−2 BOOK−BUYER) ( : m es s ag e s Z−MESSAGES) ) ) ( format t ”˜&∗∗∗ OMAS v˜A − i n i t f i l e l o a d e d ∗∗∗ ” ∗ omas−version−number ∗) ( in−package : omas ) ( setq ∗ local−coterie−agents ∗ ’ ( :BOOK−SELLER−1 :BOOK−SELLER−2 :BOOK−BUYER) ) ; ; Fin de F i c h i e r ;;;======================== ; ;; AGENT BOOK−BUYER ;;;======================== ( eval−when ( c o m p i l e l o a d e v a l ) ( u n l e s s ( find−package :BOOK−BUYER) ( make−package :BOOK−BUYER) ) ) ( in−package :BOOK−BUYER) ( eval−when ( c o m p i l e l o a d e v a l ) ( use−package : omas ) ( e x p o r t ’ (BOOK−BUYER) ) ) ; r e e x p o r t i t f o r u s e i n o t h e r p a c k a g e s ( omas : : d e f a g e n t BOOK−BUYER : r e d e f i n e t ) ;;;======================== ; ;; ; ;; BOOK−BUYER s k i l l s ; ;; ;;;======================== ; ;;==== R e q u e s t P e r f o r m e r ======= ( d e f P a r a m e t e r ∗BOOK−BUYER−RequestPerformer−functions∗ ’ ( ( : functions static−RequestPerformer dynamic−RequestPerformer ) ) ) ( d e f s k i l l : R e q u e s t P e r f o r m e r BOOK−BUYER : static−fcn static−RequestPerformer : dynamic−fcn dynamic−RequestPerformer : s e l e c t − b e s t − a n s w e r − f c n best−answer−RequestPerformer ; ; u s e a s e l e c t b e s t answer f c t f o r t h e b e s t p r i c e ) ( defun s t a t i c − R e q u e s t P e r f o r m e r ( a g e n t environment t i t l e ) ”Send a r e q u e s t f o r o f f e r s t o a l l book s e l l e r s a g e n t s ” 13 2 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 PASSAGE DE JADE À OMAS ( d e c l a r e ( i g n o r e environment ) ) ; ; send t h e message t o a l l t h e a g e n t ( send−subtask a g e n t : to : a l l : action : OfferRequestsServer : args ( l i s t t i t l e ) : strategy : collect−answers ) ( s t a t i c − e x i t agent n i l ) ) ( defun dynamic−RequestPerformer ( a g e n t environment r e s u l t ) ”The r e s u l t o f t h e b e s t answer f u n c t i o n i s r e t u r n e d t o t h e end−user ” ( d e c l a r e ( i g n o r e environment ) ) ( dynamic−exit a g e n t r e s u l t ) ) ( defun best−answer−RequestPerformer ( a g e n t environment m e s s a g e − l i s t ) ”Choose t h e b e s t p r i c e ” ( d e c l a r e ( i g n o r e environment ) ) ( l e t ( i n f o s e l l e r t i t l e ( books−to−buy−sub ( c d r ( r e c a l l book−buyer : books−to−buy ) ) ) ) ; ; e x t r a c t a l i s t with a n s w e r i n g a g e n t and c o n t e n t ( s e t q i n f o ( mapcar # ’( lambda ( xx ) ( l i s t ( omas : : from ! xx ) ( omas : : c o n t e n t s xx ) ) ) message−list ) ) ( s e t q i n f o ( s o r t i n f o #’< : key # ’( lambda ( xx ) ( cdadr xx ) ) ) ) ( setq s e l l e r ( caar i n f o ) ) ( setq t i t l e ( caadar i n f o ) ) ; ; Send a p u r c h a s e o r d e r t o t h e s e l l e r ( send−subtask a g e n t : to s e l l e r : action : PurchaseOrdersServer : args ( l i s t t i t l e ) ) ; ; Remove t h e c u r r e n t book from t h e book−to−buy l i s t ( remember book−buyer books−to−buy−sub : books−to−buy ) ) ) ;;;=========================== ; ;; ;; i n i t i a l conditions ; ;; ;;;============================ ( d e f f a c t BOOK−BUYER ( ”Think and Grow Rich ” ”48 Laws o f Power ” ”Memoirs o f a Geisha ”) : books−to−buy ) ;;;======================== ; ;; ; ;; goals ; ;; ;;;======================== 14 2 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 PASSAGE DE JADE À OMAS ; ; ; ==== g o a l s e c t i o n ===== ( defun goal−buy−book ( a g e n t ) ; ; ; D e f i n e a g o a l t o buy a r e q u e s t a book e v e r y 1 minute ( l i s t ( make−instance ’ omas : : message : type : r e q u e s t : from ( omas : : key a g e n t ) : t o ( omas : : key a g e n t ) : a c t i o n : RequestPerformer : a r g s ( l i s t ( c a r ( r e c a l l a g e n t : books−to−buy ) ) ) : task−id :BUY−BOOK )) ) ; ; ; r e t u r n T t o e n a b l e t h e g o a l NIL t i i n h i b i t i t ( defun enable−buy−book ( a g e n t s c r i p t ) ( declare ( ignore script ) ) ( r e c a l l book−buyer : books−to−buy ) ) ( d e f g o a l BUY−BOOK BOOK−BUYER ; ; E q u i v a l e n t t o t h e t i c k l e r b e h a v i o u r o f Jade : type : cyclic : period 60 : go al−enable−fc n enable−buy−book : script goal−buy−book ) ; ; ; ======== environment ====== ( d e f P a r a m e t e r ∗BOOK−BUYER−environment∗ ’ ( ( : s k i l l s : RequestPerformer ) (: globals ) ( : macros ) (: functions ) )) ; ; Fin de F i c h i e r 2.2 L’agent BOOK-SELLER L’agent BOOK-SELLER attend la réception d’un message de type demande. Arrivée d’un message de type demande Cherche si le titre du livre est présent dans sa liste locale Si il est présent Envoyer le prix à l’initiateur du message Sinon Rien faire Arrivée d’un message de type validation Décrémenter le stock dont le titre du livre correspond 15 2 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 PASSAGE DE JADE À OMAS ;;;=============================== ; ;; AGENT b o o k − s e l l e r − 1 ;;;=============================== ( eval−when ( c o m p i l e l o a d e v a l ) ( u n l e s s ( find−package : b o o k − s e l l e r − 1 ) ( make−package : b o o k − s e l l e r − 1 ) ) ) ; ; ; d e f i n e name i n t h e l o a d i n g environment , s o t h a t i t can be used without p r e f i x , ; ; ; e x p o r t i t t o t h e a g e n t package ( in−package : b o o k − s e l l e r − 1 ) ( eval−when ( c o m p i l e l o a d e v a l ) ( use−package : omas ) ( export ’ ( book−seller−1 ) ) ) ; reexport i t f o r use in other packages ( omas : : d e f a g e n t b o o k − s e l l e r − 1 : r e d e f i n e t ) ;;;====================== ; ;; ; ;; Skills ; ;; ;;;====================== ; ;;=== O f f e r R e q u e s t s S e r v e r ==== ( d e f P a r a m e t e r ∗ BOOK−SELLER−1−OfferRequestsServer−functions ∗ ’ ( ( : functions static−OfferRequestsServer ) ) ) ( d e f s k i l l : O f f e r R e q u e s t s S e r v e r BOOK−SELLER−1 : static−fcn static−OfferRequestsServer ) ( defun s t a t i c − O f f e r R e q u e s t s S e r v e r ( a g e n t environment t i t l e ) ”Return t h e p r i c e i f t h e r e q u e s t e d book o t h e r w i s e d o e s not b o t h e r answering . ” ( d e c l a r e ( i g n o r e environment ) ) ( l e t (( stock ( assoc t i t l e ( r e c a l l b o o k − s e l l e r − 1 : books ) : t e s t #’ string−equal ) ) ) ( i f stock ( s t a t i c − e x i t agent stock ) ( s t a t i c − e x i t agent : abort ) ) ) ) ; ;;== P u r c h a s e O r d e r s S e r v e r === ( d e f P a r a m e t e r ∗BOOK−SELLER−1−PurchaseOrdersServer−functions∗ ’ ( ( : functions static−PurchaseOrdersServer ) ) ) ( d e f s k i l l : P u r c h a s e O r d e r s S e r v e r BOOK−SELLER−1 : static−fcn static−PurchaseOrdersServer ) 16 2 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 PASSAGE DE JADE À OMAS ( defun s t a t i c − P u r c h a s e O r d e r s S e r v e r ( a g e n t environment t i t l e ) ”The s e l l e r a g e n t removes t h e p ur c h a s e d book from i t s c a t a l o g u e when r e c e i v i n g an o f f e r a c c e p t a n c e ” ( d e c l a r e ( i g n o r e environment ) ) ; ; D e l e t e t h e book from t h e a g e n t memory . ( l e t ∗ ( ( l i s t − b o o k s ( r e c a l l b o o k − s e l l e r − 1 : books ) ) ( l i s t − b o o k s − s u b ( d e l e t e − i f # ’( lambda ( xx ) ( e q u a l p t i t l e ( c a r xx ) ) ) l i s t − b o o k s ) ) ) ; ; Save t h e new l i s t i n t h e a g e n t memory ( remember b o o k − s e l l e r − 1 l i s t − b o o k s − s u b : books ) ( s t a t i c − e x i t agent list−books−sub ) ) ) ; ;;==== u p d a t e C a t a l o g u e === ( d e f P a r a m e t e r ∗BOOK−SELLER−1−updateCatalogue−functions∗ ’ ( ( : functions static−updateCatalogue ) ) ) ( d e f s k i l l : u p d a t e C a t a l o g u e BOOK−SELLER−1 : static−fcn static−updateCatalogue ) ( defun s t a t i c − u p d a t e C a t a l o g u e ( a g e n t environment t i t l e p r i c e ) ”Add a new book and h i s p r i c e t o t h e agent ’ s l i s t o f books ” ( d e c l a r e ( i g n o r e environment ) ) ( l e t ( ( l i s t − b o o k s ( r e c a l l b o o k − s e l l e r − 1 : books ) ) ) ; ; Add a new book t o t h e l i s t l i s t − b o o k s ( push ( c o n s t i t l e p r i c e ) l i s t − b o o k s ) ; ; Save a new book i n t h e a g e n t memory with t h e remember f u n c t i o n ( remember b o o k − s e l l e r − 1 l i s t − b o o k s : books ) ( s t a t i c − e x i t agent list−books ) ) ) ; ;=== i n i t i a l c o n d i t i o n s========= ; ; Add an i n i t i a l l i s t o f books t o t h e a g e n t ( d e f f a c t BOOK−SELLER−1 ( ( ”Memoirs o f a Geisha ” . 2 4 ) ( ”Think and Grow Rich ” . 2 2 ) ( ”48 Laws o f Power ” . 67) ) : books ) ( eval−when ( c o m p i l e l o a d e v a l ) ( use−package : b o o k − s e l l e r − 1 ) ) ; ; ; =====environment======= ( d e f P a r a m e t e r ∗ book−seller−1−environment ∗ 17 2 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 PASSAGE DE JADE À OMAS ’ ( ( : s k i l l s : OfferRequestsServer : PurchaseOrdersServer : updateCatalogue ) ) ) ; ; Fin de F i c h i e r ;;;=============== ; ; ; AGENT b o o k − s e l l e r − 2 ;;;================ ( eval−when ( c o m p i l e l o a d e v a l ) ( u n l e s s ( find−package : b o o k − s e l l e r − 2 ) ( make−package : b o o k − s e l l e r − 2 ) ) ) ; ; ; d e f i n e name i n t h e l o a d i n g environment , s o t h a t i t can be used without p r e f i x , ; ; ; e x p o r t i t t o t h e a g e n t package ( in−package : b o o k − s e l l e r − 2 ) ( eval−when ( c o m p i l e l o a d e v a l ) ( use−package : omas ) ( export ’ ( book−seller−2 ) ) ) ; reexport i t f o r use in other packages ( omas : : d e f a g e n t b o o k − s e l l e r − 2 : r e d e f i n e t ) ;;;================ ; ;; ; ;; Skills ; ;; ;;;================= ; ; ; == O f f e r R e q u e s t s S e r v e r ===== ( d e f P a r a m e t e r ∗ BOOK−SELLER−2−OfferRequestsServer−functions ∗ ’ ( ( : functions static−OfferRequestsServer ) ) ) ( d e f s k i l l : O f f e r R e q u e s t s S e r v e r BOOK−SELLER−2 : static−fcn static−OfferRequestsServer ) ( defun s t a t i c − O f f e r R e q u e s t s S e r v e r ( a g e n t environment t i t l e ) ”Return t h e p r i c e i f t h e r e q u e s t e d book o t h e r w i s e d o e s not b o t h e r answering . ” ( d e c l a r e ( i g n o r e environment ) ) ( l e t (( stock ( assoc t i t l e ( r e c a l l b o o k − s e l l e r − 2 : books ) : t e s t #’ string−equal ) ) ) ( i f stock ( s t a t i c − e x i t a g e n t s t o c k ) ; ; There i s a book ( s t a t i c − e x i t a g e n t : a b o r t ) ) ) ) ; ; No book with t h i s t i t l e ; ; ; ==== P u r c h a s e O r d e r s S e r v e r ====== ( d e f P a r a m e t e r ∗BOOK−SELLER−2−PurchaseOrdersServer−functions∗ ’ ( ( : functions static−PurchaseOrdersServer ) ) ) 18 2 156 157 158 159 160 161 162 163 164 165 PASSAGE DE JADE À OMAS ( d e f s k i l l : P u r c h a s e O r d e r s S e r v e r BOOK−SELLER−2 : static−fcn static−PurchaseOrdersServer ) ( defun s t a t i c − P u r c h a s e O r d e r s S e r v e r ( a g e n t environment t i t l e ) ”The s e l l e r a g e n t removes t h e p ur c h a s e d book from i t s c a t a l o g u e when r e c e i v i n g an o f f e r a c c e p t a n c e ” ( d e c l a r e ( i g n o r e environment ) ) ; ; D e l e t e t h e book from t h e a g e n t memory . ( l e t ∗ ( ( l i s t − b o o k s ( r e c a l l b o o k − s e l l e r − 2 : books ) ) ( l i s t − b o o k s − s u b ( d e l e t e − i f # ’( lambda ( xx ) 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 ; ; Save t h e new l i s t i n t h e a g e n t memory ( remember b o o k − s e l l e r − 2 l i s t − b o o k s − s u b : books ) ( s t a t i c − e x i t agent list−books−sub ) ) ) ; ;;===== u p d a t e C a t a l o g u e ==== ( d e f P a r a m e t e r ∗BOOK−SELLER−2−updateCatalogue−functions∗ ’ ( ( : functions static−updateCatalogue ) ) ) ( d e f s k i l l : u p d a t e C a t a l o g u e BOOK−SELLER−2 : static−fcn static−updateCatalogue ) ( defun s t a t i c − u p d a t e C a t a l o g u e ( a g e n t environment t i t l e p r i c e ) ”Add a new book and h i s p r i c e t o t h e agent ’ s l i s t o f books ” ( d e c l a r e ( i g n o r e environment ) ) ( l e t ( ( l i s t − b o o k s ( r e c a l l b o o k − s e l l e r − 2 : books ) ) ) ; ; Add a new book t o t h e l i s t l i s t − b o o k s ( push ( c o n s t i t l e p r i c e ) l i s t − b o o k s ) 19 2 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 PASSAGE DE JADE À OMAS ; ; Save a new book i n t h e a g e n t memory with t h e remember f u n c t i o n ( remember b o o k − s e l l e r − 2 l i s t − b o o k s : books ) ( s t a t i c − e x i t agent list−books ) ) ) ; ;;==== i n i t i a l c o n d i t i o n s==== ; ; Add an i n i t i a l l i s t o f books t o t h e a g e n t ( d e f f a c t BOOK−SELLER−2 ( ( ”Memoirs o f a Geisha ” . 2 2 ) ( ”Think and Grow Rich ” . 2 0 ) ( ”48 Laws o f Power ” . 95) ) : books ) ( eval−when ( c o m p i l e l o a d e v a l ) ( use−package : b o o k − s e l l e r − 2 ) ) ; ;;==== environment ======= ( d e f P a r a m e t e r ∗ book−seller−2−environment ∗ ’ ( ( : s k i l l s : OfferRequestsServer : PurchaseOrdersServer : updateCatalogue ) ) ) ; ; Fin de F i c h i e r ;;;======================== ; ;; Test MESSAGES ;;;======================== ; ; ; l o a d e d i n t h e package o f t h e l o a d i n g environment ( u s u a l l y OMAS) ( in−package : omas ) ( d e f m e s s a g e :OFFER−GEISHA−1 : type : r e q u e s t : t o : b o o k − s e l l e r − 1 : action : OfferRequestsServer : a r g s ( ”Memoirs o f a Geisha ”) ) ( d e f m e s s a g e :PURCHASE−LAWS−All : type : r e q u e s t : t o : a l l : action : PurchaseOrdersServer : a r g s ( ”48 Laws o f Power ”) ) ( d e f m e s s a g e :PURCHASE−NAPOLEAN−2 : type : r e q u e s t : t o : b o o k − s e l l e r − 2 : action : PurchaseOrdersServer : a r g s ( ”Think and Grow Rich ”) ) ( d e f m e s s a g e :ADD−DAN−1 : type : r e q u e s t : t o : b o o k − s e l l e r − 1 : a c t i o n : updateCatalogue : a r g s ( ”Your 100 M i l l i o n s ” 2 3 ) ) 20 2 PASSAGE DE JADE À OMAS 2.3 2.3.1 Analyse Représenation des données des Agents BOOK-SELLER Les vendeurs ont besoin d’une représentation interne de leur stock de livres. Les livres sont représentés par une liste de paires pointées. Chaque paire pointée est composée du titre du livre (chaı̂ne de caractères) et de son prix. La liste des livres à acheter par l’agent BOOK-BUYER est représentée dans une liste simple. 2.3.2 Traitement d’une liste de livres à acheter L’agent acheteur possède une skill d’achat d’un livre. Cette skill est déclenchée par l’envoi d’un message de type :request associée à l’action : RequestPerformer et d’un argument contenant le titre du livre à acheter. L’achat d’un livre commence systématiquement par l’envoi d’un message de type roadcast contenant le titre du livre. Les vendeurs disposant ce livre dans leur liste retourne à l’acheteur la paire pointée du titre et du prix du livre. La skill RequestPerformer est associée à un comportement du type est- answer-RequestPerformer. Les réponses des vendeurs sont donc collectées pendant un certain temps. Puis l’acheteur envoie automatiquement un nouveau broadcast qui annule l’appel d’offre et il sélectionne l’offre la plus intéressante parmi celles qu’il a reçues. Lors de la réception, l’acheteur envoie un nouveau message au vendeur proposant le meilleur prix et supprime simultanément le livre en cours d’achat de sa liste de livres à acheter. 2.3.3 GOAL cyclique Le goal cyclique permet de rechercher si la liste de l’acheteur est vide ou non. Si la liste est vide, l’agent acheteur se termine, si la liste n’est pas vide, le goal déclanche une demande pour le premier livre de la liste. 2.3.4 Timeout Quand aucun agent ne répond à un appel d’offre de l’agent acheteur, celui ci grâce au timeout réémet sa demande après un certain temps. Dans le cas de la non présence du titre du livre chez les vendeurs, un timeout-handler permet de gérer la continuité du programme : le titre du livre est placé à la fin de la liste ce qui permet lors du déclanchement du goal de passer au titre suivant. Le livre ayant posée problème sera de nouveau traitée quand la de la liste sera atteinte. 2.3.5 Comparaison avec JADE Au niveau de Jade, les agents s’échangent des objets livres ce qui simplifie la gestion par rapport à l’utilisation de listes chaı̂nées sur OMAS. 21