Jade (3 h) Dott. Daniela Briola
Jade Agent JADE Agents are defined as subclasses of the predefined class Agent Their initial code (if any) must be placed in a method called setup Agent actions are normally specified through Behaviour classes
Jade Agent The actions are described in the "action" method of these Behaviours There are 2 kinds of behaviour classes: primitive, like the Simple or Cyclic behaviours and composite ones which can combine both simple and composite behaviours to execute in sequence or in parallel.
Jade Agent Primitive Behaviours SimpleBehaviour: an basic class that you can extend in various ways and which often turns out to be the best solution when other promising Behaviours are found to have some hidden quirks CyclicBehaviour: This behaviour stays active as long as its agent is alive and will be called repeatedly after every event. Quite useful to handle message reception. TickerBehaviour: a cyclic behaviour which periodically executes some user-defined piece of code OneShotBehaviour: This executes ONCE and dies.... Not really that useful since the one shot may be triggered at the wrong time. WakerBehaviour: which executes some user code once at a specificied time ReceiverBehaviour: which triggers when a given type of message is received (or a timeout expires).
Jade Agent Primitive Behaviours Note: TickerBehaviour, WakerBehaviour and ReceiverBehaviour are conceptually subclasses of Cyclic and OneShot classes, but they are implemented as extentions of Simplebehaviour and Behaviour Composite Behaviours ParallelBehaviour: controls a set of children behaviours that execute in parallel. The important thing is the termination condition: we can specify that the group terminates when ALL children are done, N children are done or ANY child is done. SequentialBehaviour: this behaviour executes its children behaviours one after the other and terminates when the last child has ended.
Example 1: HelloWorld Agent import jade.core.Agent; import jade.core.behaviours.*; public class Simple0 extends Agent { protected void setup() { addBehaviour( new B1( this ) ); } } class B1 extends SimpleBehaviour { public B1(Agent a) { super(a); } public void action() { System.out.println( "Hello World! My name is "+ myAgent.getLocalName());} private boolean finished = false; public boolean done() { return finished; } } //End class B1
Example 1: HelloWorld Agent myAgent: is a local variable of all Behaviour objects which stores the agent reference passed as a parameter when the behaviour was created. The class B1 is specified outside the context of the Agent, but it can use myAgent to access its owner's attributes and methods. The mane of the agen is got with the myAgent.getLocalName()
Example 1: HelloWorld Agent Here are the commands required to compile and run our agent (type them from the directory where the code, Hello.java, is). % javac Hello.java % java jade.Boot fred:Hello Below there is the output of execution. But… that the agent loops and keeps on printing its message until we abort execution! % Hello World! My name is fred Hello World! My name is fred Hello World! My name is fred Hello World! My name is fred..... loops until stopped with CTRL-C.... ! The problem here is that we haven't explicitely indicated that the action was "done".
Example 1: HelloWorld Agent We add a local variable, "n", to the behaviour to terminate its operation after "action" has been called 3 times import jade.core.Agent; import jade.core.behaviours.*; public class Hello2 extends Agent { protected void setup() { addBehaviour( new SimpleBehaviour( this ) { int n=0; public void action() { System.out.println("HelloWorld!My name is "+myAgent.getLocalName()); n++; } public boolean done() { return n>=3; } } ); } // --- setup --- } // --- class Hello2
Example 2: Communication Here is a list of all attributes of a Jade ACL message. Jade provides get and set methods to access all the attributes. Performative - FIPA message type (INFORM, QUERY, PROPOSE,...) Addressing Receiver Sender (initialized automatically) Content - This is the main content of the message ConversationID - Used to link messages in same conversation
Example 2: Communication Language - Specifies which language is used in the content Ontology - Specifies which ontology is used in the content Protocol - Specifies the protocol ReplyWith - Another field to help distinguish answers InReplyTo - Sender uses to help distinguish answers ReplyBy - Used to set a time limit on an answer
Example 2: Communication When you create a message, you have to indicate its type (its ACL performative) and set the content. Example: ACLMessage msg = new ACLMessage(ACLMessage.INFORM ); msg.setContent(“My name is Spock" );
Example 2: Communication Common type of performative are: INFORM whereby one agent gives another some useful information QUERY to ask a question REQUEST to ask the other to do something PROPOSE to start bargaining AGREE or REFUSE
Example 2: Communication Then, assuming you want to send a message to the agent “Receiver”, sending a message is fairly easy AID dest =new AID( “Receiver", AID.ISLOCALNAME) ; msg.addReceiver( dest ); send(msg); Note: We use addReceiver because there is no setReceiver method.... One reason is that we can add several receivers to the message. AID.ISLOCALNAME is a constant
Example 2: Communication Messages are routed to wherever the destination agent resides and are placed in its message queue. There are 2 basic ways for the receiver to get its messages. blockingReceive(), the receiving agent suspends all its activities until a message arrives Receive(), which returns a message if there is one or null otherwise. This is the normal technique used when an agent is involved in parallel activities and has multiple active Behaviours.
Example 2: Communication Answering messages All messages have an attribute which contains the ID of the sender. We can answer a message as follows: ACLMessage msg = receive(); ACLMessage reply = new ACLMessage( ACLMessage.INFORM ); reply.setContent( "Pong" ); reply.addReceiver( msg.getSender() ); send(reply);
Example 2: Communication Answering messages To simplify answering, Jade provides a method createReply() which creates a new message with the sender and receiver attributes switched and all other attributes set correctly. Generally, only the content and performative have to be modified before sending it back.
Example 2: Communication Class Ping import jade.core.Agent; import jade.core.AID; import jade.core.behaviours.*; import jade.lang.acl.*; public class Ping extends Agent { protected void setup() { addBehaviour(new CyclicBehaviour(this) { public void action() { ACLMessage msg= receive(); if (msg!=null) System.out.println( "== Answer" + " <- " + msg.getContent() + " from " + msg.getSender().getName() ); block(); } }); ACLMessage msg = new ACLMessage(ACLMessage.INFORM); msg.setContent( "Ping" ); msg.addReceiver( new AID( “Pong", AID.ISLOCALNAME) ); send(msg); } // sends message to Pong
Example 2: Communication Class Pong import jade.core.Agent; import jade.core.behaviours.*; import jade.lang.acl.*; public class Pong extends Agent { protected void setup() { addBehaviour(new CyclicBehaviour(this) { public void action() { ACLMessage msg = receive(); if (msg!=null) { System.out.println( myAgent.getLocalName() + " received: " + msg.getContent() ); ACLMessage reply = msg.createReply(); reply.setPerformative( ACLMessage.INFORM ); reply.setContent(" Pong" ); send(reply); } block(); } }); }} To execute the example run % java jade.Boot main:Ping Pong:Pong
Example 3: Using DF Agent JADE implements a Directory Facilitator (DF) agent as specified by FIPA. The DF is often compared to the "Yellow Pages" phone book. Agents wishing to advertize their services register with the DF. Visiting agents can then ask (search) the DF looking for agents which provide the services they desire. The DF entries concentrate on listing the ontologies, protocols and languages which are supported by the agents.
Example 3: Using DF Agent DFAgentDescription Name: AID // Required for registration Protocols: set of Strings Ontologies: set of Strings Languages: set of Strings Services: set of { Name: String // Required for each service specified Type: String // Required Owner: String Protocols: set of Strings Ontologies: set of Strings Languages: set of Strings Properties: set of { Name: String, Value: String } }
Example 3: Using DF Agent import jade.core.Agent; import jade.core.behaviours.*; import jade.domain.DFService; import jade.domain.FIPAAgentManagement.*; import jade.domain.FIPAException; public class DF2 extends Agent { protected void setup() { ServiceDescription sd = new ServiceDescription(); sd.setType( "buyer" ); sd.setName( getLocalName() ); register( sd ); } void register( ServiceDescription sd) { DFAgentDescription dfd = new DFAgentDescription(); dfd.setName(getAID()); dfd.addServices(sd); try { DFService.register(this, dfd ); } catch (FIPAException fe) { fe.printStackTrace(); } } }
Example 3: Using DF Agent When an agent terminates, it is good practice to delete its entry in the DF Although agent entries are removed automatically from the AMS when an agent dies, the system does not remove them from the DF and it is up to the programmer to do it explicitely Each agent is allowed only ONE entry in the DF. Attempts to register an agent already in the DF gives an Exception.
Example 3: Using DF Agent To search the DF, you must create a DFD [with no AID] where the relevant fields are initialised to the properties you require The search returns an array of DFDs (with AIDs) whose attributes match your description and you can extract the ID of suitable agents from those entries Generally, you either want to find ONE agent with the services you need or ALL of them.
Example 3: Using DF Agent DFAgentDescription dfd = new DFAgentDescription(); ServiceDescription sd = new ServiceDescription(); sd.setType( “Ping" ); dfd.addServices(sd); DFAgentDescription[] result =DFService.search(this,dfd); System.out.println(result.length + " results" ); if (result.length>0) System.out.println(""+result[0].getName() );
Grazie a tutti! Testi delle slides tratti da gents/Jade/primer4.html Gli esempi sono in parte tratti dal tutorial sopra citato, ma modificati in parte, o creati ad hoc per questa esercitazione.