81
AFAS/ACRE Examples

AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak. It covers programming both with

Embed Size (px)

DESCRIPTION

SECTION 1: SETUP

Citation preview

Page 1: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

AFAS/ACRE Examples

Page 2: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

Introduction• This guide contains practical examples of how to program

protocols in AF-AgentSpeak.– It covers programming both with and without ACRE.

• Each section of the document outlines an example protocol and discusses its implementation.

• Section 5 introduces the Directory Facilitator Service, which you will need to use to locate key agents.

Page 3: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

SECTION 1: SETUP

Page 4: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

Setting Up• General Instructions:

http://www.agentfactory.com/index.php/ACRE_User_Guide

• Step 1: Download and install the Graphviz application from http://www.graphviz.org

• Step 2: Download the following JAR files and store them in your Eclipse project root:• MAS-ACRE.jar (http://www.agentfactory.com/~daithi/latest/)• AF-ACRE.jar (http://www.agentfactory.com/~daithi/latest/)• Log4J.jar (http://logging.apache.org/log4j/)

Page 5: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

NOTES• There are updates to both ACRE & AFSE – please download

them.– Relevant jar files / update center are available via the Fudan FTP

Server.

• These programs reflect an improved version of ACRE that includes functionality not present in the previous version.

• You can use these slides as notes in the practical exam.– In most cases, you will only be implementing the initiator role in the

protocols (the participant implementation will be given)

Page 6: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

SECTION 2: FIPA-REQUEST

Page 7: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

Protocol Overview

• Usage: Requesting an activity / service be performed

Page 8: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

Example• For this example, we study how to implement a protocol and

develop two simple task tasks:– Drinking beer task: prints “Mmmm tasty beer”– Time task: returns the time in the form time(?h, ?m, ?s)

• The example consists of two agents:– requester.aspeak: this agent is the participant and performs the tasks– requestee.aspeak: this agent is the initiator and requests that the tasks be

performed.

• First I will discuss requester implementation and then the requestee implementation.– Both programs will be preceded by explanations.

Page 9: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

Non ACRE: Requester• A protocol can be viewed as having a “main” flow together

with a number of “exceptional” flows (a flow is a sequence of messages).– For the request protocol, the main flow is where the participant

agrees to perform the task, performs the task successfully, and tells the initiator that the task has been performed.

– The first exceptional flow relates to the case where the participant refuses the request.

– The second exceptional flow relates to the case where the requested task fails.

• Let’s look at each flow individually…

Page 10: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

Non-ACRE: Requester (MAIN)• For the request protocol, the main flow can be encoded through

a single rule:

+message(request, ?initiator, ?task) : canDo(?task) <-+performingTask(?initiator, ?task),.send(agree, ?initiator, ?task),try {!performTask(?initiator, ?task)} recover {.send(failure, ?initiator, ?task)}-performingTask(?initiator, ?task);

• When the agent receives the “request” message for ?task, if it believes that is canDo(?task), then the main flow is followed (actions in italics).

Page 11: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

Non-ACRE: Requester (MAIN)• For the request protocol, the main flow can be encoded

through a single rule:

+message(request, ?initiator, ?task) : canDo(?task) <-+performingTask(?initiator, ?task),.send(agree, ?initiator, ?task),try {!performTask(?initiator, ?task)} recover {.send(failure, ?initiator, ?task)}-performingTask(?initiator, ?task);

• First, it adopts a belief that it is performing the task, and then it sends a message to the initiator agreeing to perform the task.

Page 12: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

Non-ACRE: Requester (MAIN)• For the request protocol, the main flow can be encoded

through a single rule:

+message(request, ?initiator, ?task) : canDo(?task) <-+performingTask(?initiator, ?task),.send(agree, ?initiator, ?task),try {

!performTask(?initiator, ?task)} recover {

.send(failure, ?initiator, ?task)}-performingTask(?initiator, ?task);

• Now it performs the task by raising the !performTask(…) goal.

Page 13: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

Non-ACRE: Requester (MAIN)• Default behaviour for performTask(…):

+!performTask(?agentID, ?task) : true <-.fail;

– If this rule is triggered then there is no implementation of the task, so the agent views the task as having failed.

• Drink beer task:

+!performTask(?agentID, drink(beer)) : name(?name) <-.println("[" + ?name + "] Mmmm tasty beer"),.send(inform, ?agentID, done(drink(beer)));

– The agent prints out “[<name>] Mmmm tasty beer” and informs the initiator that the task is done.

– This rule must be written before the default rule (see full code)

Page 14: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

Non-ACRE: Requester (MAIN)• For the request protocol, the main flow can be encoded

through a single rule:

+message(request, ?initiator, ?task) : canDo(?task) <-+performingTask(?initiator, ?task),.send(agree, ?initiator, ?task),try {

!performTask(?initiator, ?task)} recover {

.send(failure, ?initiator, ?task)}-performingTask(?initiator, ?task);

• Finally, the agent drops the performingTask(…) belief.

Page 15: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

Non-ACRE: Requester (FAILURE)• For the request protocol, the main flow can be encoded through a

single rule:

+message(request, ?initiator, ?task) : canDo(?task) <-+performingTask(?initiator, ?task),.send(agree, ?initiator, ?task),try {!performTask(?initiator, ?task)} recover {.send(failure, ?initiator, ?task)}-performingTask(?initiator, ?task);

• NOTE: the failure exceptional flow is implemented here by the try {…} recover {…} operator.– if the agent fails to perform the task, then the recovery plan involves the agent

sending a failure message to the initiator.

Page 16: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

Non-ACRE: Requester (REFUSE)• For the request protocol, the refuse exceptional flow can be

encoded through a single rule:

+message(request, ?initiator, ?task) : ~canDo(?task) <-.send(refuse, ? initiator, ?task);

• Here, the participant refuses to perform a requested task if it does not have the belief canDo(?task).

Page 17: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

Non-ACRE: Requester (CANCEL)• In our discussion of the basic protocol, we did not consider how to

cancel a request.– Doing this requires that we make use of a previously un-described feature of

AF-AgentSpeak that is not part of the basic AgentSpeak language.– Specifically, we associate a maintenance condition (see code in bold below)

with the rule that implements each task. If this condition becomes false, the agent causes the associated intention to fail.

+!performTask(?initiator, drink(beer)) : name(?name) <-[performingTask(?initiator,drink(beer))].println("[" + ?name + "] Mmmm tasty beer"),.send(inform, ?initiator, done(drink(beer)));

• For the performTask(…) rules, the maintenance condition is that you believe that you are performing the task.

Page 18: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

Non-ACRE: Requester (CANCEL)• Now, we can add a rule for handling cancellation requests:

+message(cancel, ?initiator, protocol(request, ?task)) : performingTask(?initiator, ?task) <--performingTask(?initiator, ?task);

– This rule basically has the effect of removing the performingTask(…) belief whenever the participant receives a request to cancel a task that it is currently performing.

– The side effect of removing this belief is that the maintenance condition on the !performTask(…) rule becomes false, causing the agent to fail the intention.

– The last thing we need to do is to modify our MAIN flow to cater for the task that the !performTask(…) rule has been intentionally failed…

Page 19: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

Non-ACRE: Requester (CANCEL)• The updated rule is:

+message(request, ?initiator, ?task) : canDo(?task) <-+performingTask(?initiator, ?task),.send(agree, ?initiator, ?task),try {

!performTask(?initiator, ?task)} recover {

if (performingTask(?initiator, ?task)) {.send(failure, ?initiator, ?task)

}}-performingTask(?initiator, ?task);

• The full code is presented on the next slide.

Page 20: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

Non ACRE: Requester (Code)#agent requester

+message(request, ?initiator, ?task) : canDo(?task) <-+performingTask(?initiator, ?task),.send(agree, ?initiator, ?task),try {

!performTask(?initiator, ?task)} recover {

if (performingTask(?initiator, ?task)) .send(failure, ?initiator, ?task)}-performingTask(?initiator, ?task);

+message(request, ?initiator, ?task) : ~canDo(?task) <-.send(refuse, ?initiator, ?task);

+message(cancel, ?initiator, protocol(request, ?task)) : performingTask(?initiator, ?task) <--performingTask(?initiator, ?task);

canDo(drink(beer));

+!performTask(?initiator, drink(beer)) : name(?name) <- [performingTask(?initiator, drink(beer))].println("[" + ?name + "] Mmmm tasty beer"),.send(inform, ?initiator, done(drink(beer)));

+!performTask(?initiator, ?task) : true <-.fail;

Page 21: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

Non-ACRE: Requestee• For the requestee, the protocol flows are not so complicated:

– Send a request for the participant to drink beer.– If this request is completed successfully, send a request for the participant

to drink wine.– Notice that the agent identifier uses the address: “local:localhost”.

• This can now be used for agents on the same platform

• The full code for the requestee is:#agent requestee

+initialized : true <-.send(request, agentID(requester, addresses("local:localhost")), drink(beer));

+message(inform, ?agentID, done(drink(beer))) : true <-

.send(request, agentID(requester, addresses("local:localhost")), drink(wine));

Page 22: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

Non-ACRE: Deploymentpublic class Main {

public static class DebugConfig extends AgentSpeakDebugConfiguration { public DebugConfig() { super(“afas", null); }

public void configure() { super.configure();

addAgent("requester", “acre/requester.aspeak"); addAgent("requestee", “acre/requestee.aspeak");

}}

public static void main(String[] args) { new DebugConfig().configure();}

}

Page 23: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

Non-ACRE Summary• The participant code has been designed to be extensible.

– To add another task, all you need to do is add a canDo(…) belief, and implement a !performTask(…) rule.

– Example: time

canDo(tell_time);

+!performTask(?initiator, tell_time) : name(?name) & time(?h, ?m, ?s) <- [performingTask(?initiator,

tell_time)].send(inform, ?initiator, result(tell_time, time(?h, ?m, ?s)));

– NOTE: The inform message this case is result(?task, ?value) which corresponds to the inform-result message in the protocol.

Page 24: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

ACRE: Adaptation• To implement this protocol in ACRE, the main differences lie in

the protocol rules:+message(request, ?initiator, ?task) : canDo(?task) <-

+performingTask(?initiator, ?task),.send(agree, ?initiator, ?task),try {!performTask(?initiator, ?task)} recover {if (performingTask(?initiator, ?task)) .send(failure, ?initiator, ?task)}-performingTask(?initiator, ?task);

+message(request, ?initiator, ?task) : ~canDo(?task) <-.send(refuse, ?initiator, ?task);

+message(cancel, ?initiator, protocol(request, ?task)) : performingTask(?initiator, ?task) <--performingTask(?initiator, ?task);

Page 25: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

ACRE: Adaptation• To start with, acre requires installation and initialization, so

we need the following lines of code:

module acre -> is.lill.acre.agent.module.ACREModule;

+initialized : true <- acre.init;

• Next, we need to modify any rule that uses a message event as a trigger or which uses the .send(…) action…

Page 26: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

ACRE: Adaptation• The first rule to consider is the main flow rule:

+message(request, ?initiator, ?task) : canDo(?task) <-+performingTask(?initiator, ?task),.send(agree, ?initiator, ?task),try {!performTask(?initiator, ?task)} recover {if (performingTask(?initiator, ?task)) .send(failure, ?initiator, ?task)}-performingTask(?initiator, ?task);

• To adapt this rule to ACRE:– we replace the triggering event with a conversationAdvanced(…) event– We replace every .send(…) action with an acre.advance(…) action

Page 27: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

ACRE: Adaptation• So, the ACRE equivalent rule becomes:

+conversationAdvanced(?cid,requested,?index) :conversationHistory(?cid, ?index, received, request, ?task) &conversationProtocolName(?cid,request) & canDo(?task) <-acre.advance(?cid, agree, ?task),try {!performTask(?cid, ?task)} recover {acre.advance(?cid, failure, ?task)};

• Key Points:– The performingTask(…) belief is no longer required– We use the conversationHistory(…) belief to access the last message sent

(this is because event processing can be delayed depending on the size of the agents event queue)

– This also accounts for the failure exceptional flow

Page 28: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

ACRE: Adaptation• In the non-ACRE implementation, the refuse exceptional flow

is realised through the following rule:

+message(request, ?initiator, ?task) : ~canDo(?task) <-.send(refuse, ?initiator, ?task);

• The ACRE equivalent is:+conversationAdvanced(?cid,requested,?index) :

conversationHistory(?cid, ?index, received, request, ?task) &conversationProtocolName(?cid,request) & ~canDo(?task) <-

acre.advance(?cid, refuse, ?task);

Page 29: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

ACRE: Adaptation• The cancel exceptional flow is supported through a standardised

rule that is protocol independent:

+conversationCancelRequest(?cid) : true <-acre.confirmCancel(?cid),acre.forget(?cid);

• The last place where the code must be adapted is in the !performTask(…) rules.– These rules implement the requested tasks and include the final inform-

done and inform-result messages.– The main difference is the use of acre.advance(…) instead of .send(…)– This has been supported through the modification of the parameters passed

to !performTask(…) which includes the conversation identifier instead of the agent identifier.

Page 30: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

ACRE: Adaptation• The modified task rules are:

+!performTask(?cid, drink(beer)) : name(?name) <-[conversationHistory(?cid, 1, received, request, drink(beer))].println("[" + ?name + "] Mmmm tasty beer"),acre.advance(?cid, inform, done(drink(beer)));

+!performTask(?cid, tell_time) : name(?name) & time(?h, ?m, ?s) <-[conversationHistory(?cid, 1, received, request, tell_time)]acre.advance(?cid, inform, result(tell_time, time(?h, ?m, ?s)));

+!performTask(?cid, ?task) : true <-.fail;

• Key Point:– The maintenance condition changes to conversationHistory(…,1,…) where 1 is

the index of the first message in the conversation.– The tell_time task is omitted from the program in the next slide.

Page 31: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

ACRE: Adaptation#agent requester

module acre -> is.lill.acre.agent.module.ACREModule;+initialized : true <- acre.init;

+conversationAdvanced(?cid,requested,?index) : conversationProtocolName(?cid,request) & canDo(?task) &conversationHistory(?cid, ?index, received, request, ?task) <-acre.advance(?cid, agree, ?task),try {!performTask(?initiator, ?task)} recover {acre.advance(?cid, failure,? task)};

+conversationAdvanced(?cid,requested,?index) : conversationProtocolName(?cid,request) & ~canDo(?task) &conversationHistory(?cid, ?index, received, request, ?task) <-acre.advance(?cid, refuse, ?task);

+conversationCancelRequest(?cid) : true <- acre.confirmCancel(?cid), acre.forget(?cid);

canDo(drink(beer));

+!performTask(?cid, drink(beer)) : name(?name) <- [conversationHistory(?cid, 1, received,request,tell_time)].println("[" + ?name + "] Mmmm tasty beer"),

acre.advance(?cid, inform, done(drink(beer)));

+!performTask(?cid, ?task) : true <- .fail;

Page 32: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

ACRE: Adaptation• The code for the requestee is:

#agent requestee

module acre -> is.lill.acre.agent.module.ACREModule;

+initialized : true <-acre.addRepository("file:///C:/Users/rem/acre"), acre.init,acre.addContact(agentID(requester,addresses("local:localhost"))),acre.start(org.fipa_request_1.3,requester,request,drink(beer));

+conversationAdvanced(?cid,refused,?index) :conversationProtocolName(?cid,request) <-acre.forget(?cid);

+conversationAdvanced(?cid,done,?index) : conversationProtocolName(?cid,request) <-acre.start(org.fipa_request_1.3,requester,request,tell_time);

+conversationMessage(?cid,inform,result(tell_time, time(?h, ?m, ?s))) : true <-.println("The time is: "+?h + ":"+?m+":"+?s);

Page 33: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

ACRE: Deploymentpublic class Main {

public static class ACREDebugConfig extends AgentSpeakDebugConfiguration { public ACREDebugConfig() { super("acre", null); }

public void configure() { addServiceInspectorFactory( new ProtocolManagerServiceInspectorFactory() );

super.configure(); addPlatformService(

ProtocolManagerPlatformService.class,ProtocolManagerPlatformService.NAME );

addAgent("requester", “acre/requester.aspeak"); addAgent("requestee", “acre/requestee.aspeak");

}}

public static void main(String[] args) { new ACREDebugConfig().configure();}

}

Page 34: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

SECTION 3: FIPA-SUBSCRIBE

Page 35: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

Protocol Overview

• Usage: Requesting updates on some topic

Page 36: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

Example• This example will implement a clock service, which sends

subscribers a message every second.– The message contents will be the number of seconds since the service

was started.

• As with the FIPA-REQUEST example, this example involves two agents:– Subscriber.aspeak: the participant (implements the service)– Subscribee.aspeak: the initiator (uses the service) and cancels the

subscription once the clock tick reaches 3.

• The discussion assumes you have read the previous example

Page 37: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

Non ACRE: Subscriber• The flows in the subscribe protocol are:

– Main flow: participant agrees to the subscription request and sends updates until the subscription is cancelled.

– The first exceptional flow relates to the case where the participant refuses the subscription request.

– The second exceptional flow relates to the case where the subscription service fails.

• NOTE: The service is implemented separately to the protocol, but uses knowledge of who the agent has accepted.– We discuss the service implementation first

Page 38: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

Non ACRE: Subscriber (Service)• The clock service involves a long-running intention which sends

messages to subscribed agents every second.+topic(clock) : true <-?i = 0,while(true) {durative(.sleep(1000)),?aids = list[?aid | subscription(?aid, clock) ].send(inform, ?aids, value(clock, ?i))?i = ?i + 1};

• Key Points:– A subscription(…) belief is used to keep track of who is subscribed.– The list[…] operator creates a new list whose values are the agent Ids from the

subscription beliefs.– The .send(…) action accepts a list of agent ids!

Page 39: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

Non ACRE: Subscriber (Service)• The service is started in the initialized rule by adopting the

belief topic(clock).+initialized : true <-

+topic(clock);

• Key Points:– The topic(?topic) beliefs are used to keep track of the topics that

initiators can request subscriptions for.

Page 40: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

Non ACRE: Subscriber (MAIN)• The main flow is triggered by the receipt of a message from

an initiator requesting a topic that the agent provides:+message(subscribe, ?agentID, ?topic) : topic(?topic) <-

.send(agree, ?agentID, ?topic),+subscription(?agentID, ?topic);

• Key Points:– The agent sends the agree message to the initiator and adopts the

subscription(…) belief, adding the agent to the service.– The agent only does this if it has a topic(…) belief relating to the

requested subscription.

Page 41: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

Non ACRE: Subscriber (MAIN)• The main flow only stops on receipt of a cancel request by the

initiator:+message(cancel, ?agentID, protocol(subscribe, ?topic)) :

subscription(?agentID, ?topic) <--subscription(?agentID, ?topic);

• Key Points:– This rule is similar to the FIPA-REQUEST cancellation rule.– The rule removes the subscription(…) belief, resulting in the service no

longer adding the agents id to the list of subscribed agent ids.

Page 42: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

Non ACRE: Subscriber (REFUSE)• The refuse exceptional flow is triggered by the receipt of a

message from an initiator requesting a topic that the agent does not provide:+message(subscribe, ?agentID, ?topic) : ~topic(?topic) <-

.send(refuse, ?agentID, ?topic);

• Key Points:– The agent does this if it does not have a topic(…) belief relating to the

requested subscription.

Page 43: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

Non-ACRE: Subscriber (Code)#agent subscriber

+initialized : true <-+topic(clock);

+topic(clock) : true <-?i = 0,while(true) {durative(.sleep(1000)),?aids = list[?aid | subscription(?aid, clock) ],if (?aids != []) .send(inform, ?aids, value(clock, ?i)),?i = ?i + 1};

+message(subscribe, ?agentID, ?topic) : topic(?topic) <-

.send(agree, ?agentID, ?topic),+subscription(?agentID, ?topic);

+message(subscribe, ?agentID, ?topic) : ~topic(?topic) <-.send(refuse, ?agentID, ?topic);

+message(cancel, ?agentID, protocol(subscribe, ?topic)) : subscription(?agentID, ?topic) <--subscription(?agentID, ?topic);

Page 44: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

Non-ACRE: Subscribee• The initiator is more complex to implement than for the FIPA-

Request protocol.– The agent needs to keep track of its subscriptions so that it can cancel the

subscription when necessary.– This requires that the agent use the agree message to record subscriptions.

• The code for requesting and recording the subscription is:+initialized : true <-.send(subscribe, agentID(subscriber, addresses("local:localhost")), clock);

+message(agree, ?agentID, ?topic) : true <-+subscribed(?topic, ?agentID);

• Issue:– The problem here is that agree is quite generic (it is also used in the FIPA-

request protocol), so it is possible that this rule will not only be used by subscription requests.

Page 45: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

Non-ACRE: Subscribee• To handle this, we must also keep track of subscription requests:

+initialized : true <-+subscribing(clock, subscriber),.send(subscribe, agentID(subscriber, addresses("local:localhost")), clock);

+message(agree, agentID(?name, ?addr), ?topic) : subscribing(?topic, ?name) <--subscribing(?topic, ?name),+subscribed(?topic, agentID(?name,?addr));

• Key Points:– Initially, we only record the name of the participant because the agent

identifier we use may not be complete.– When the agree message is returned, the full agent identifier is known as it

was provided by the participant - it can be used in the subscribed(…) belief.– It is actually required here because otherwise the initiator will not be able

to cancel the subscription!

Page 46: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

Non-ACRE: Subscribee• Because we keep track of subscription requests, we also need

to handle refuse messages (to update our beliefs accordingly):

+message(refuse, agentID(?name, ?addr), ?topic) : subscribing(?topic, ?name) <--subscribing(?topic, ?name);

• Now, we need to consider receipt of inform messages from the service.– These messages contain information that may be needed by the agent.– In keeping with the ethos adopted in the FIPA-request protocol, we

separate receipt of the message from handling of its content, which is done by a subgoal.

Page 47: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

Non-ACRE: Subscribee• The inform message handling rules for the clock example are

given below:

+message(inform, ?agentID, value(?topic, ?value)) : subscribed(?topic, ?agentID) <-!handleSubscriptionResult(?topic, ?value);

+handleSubscriptionResult(clock, ?x) : true <-if (clock(?y)) .replace(clock(?y), clock(?x))else +clock(?x);

• Key Points:– This could equally be implemented by a single rule, but in my view,

this separation of concerns offers greater flexibility in implementation.• It does not mix conversation logic and application logic.

Page 48: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

Non-ACRE: Subscribee• Finally we need a rule to trigger the cancellation of the

subscription:

+clock(?x) : subscribed(clock, ?agentID) <--subscribed(clock, ?agentID),.send(cancel, ?agentID, protocol(subscribe, clock));

• Key Points:– Here, we assume that sending the cancel message cancels the

subscription.• This is NOT guaranteed in the cancel protocol!

Page 49: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

Non-ACRE: Subscribee (Code)#agent subscribee

+initialized : true <-+subscribing(clock, subscriber),.send(subscribe, agentID(subscriber, addresses("local:localhost")), clock);

+message(agree, agentID(?name, ?addr), ?topic) : subscribing(?topic, ?name) <-

-subscribing(?topic, ?name),+subscribed(?topic, agentID(?name, ?a-ddr));

+message(refuse, agentID(?name, ?addr), ?topic) : subscribing(?topic, ?name) <--subscribing(?topic, ?name);

+message(inform, ?agentID, value(?topic, ?value)) : subscribed(?topic, ?agentID) <-!handleSubscriptionResult(?topic, ?value);

+handleSubscriptionResult(clock, ?x) : true <-if (clock(?y)) .replace(clock(?y), clock(?x))else +clock(?x);

+clock(?x) : subscribed(clock, ?agentID) <--subscribed(?topic, ?agentID),.send(cancel, ?agentID, protocol(subscribe, clock));

Page 50: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

Non-ACRE: Deploymentpublic class Main {

public static class DebugConfig extends AgentSpeakDebugConfiguration { public DebugConfig() { super(“afas", null); }

public void configure() { super.configure();

addAgent(“subscriber", “acre/subscriber.aspeak"); addAgent("subscribee", “acre/subscribee.aspeak");

}}

public static void main(String[] args) { new DebugConfig().configure();}

}

Page 51: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

ACRE: Adaptation• As in the first example, ACRE requires installation and

initialization, so we need to add the following lines of code:

module acre -> is.lill.acre.agent.module.ACREModule;

+initialized : true <-acre.init,+topic(clock);

• Next, we need to modify any rule that uses a message event as a trigger or which uses the .send(…) action…

• As we will see in this example, because ACRE manages conversations, some of the rules will not be necessary…

Page 52: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

ACRE: Subscriber• The main topic rule needs only minor adjustment:

+topic(clock) : true <-?i = 0,while(true) {.sleep(1000),?cids = list[?cid |conversationHistory(?cid, 1, received, subscribe, clock) &conversationProtocolName(?cid, subscribe) &conversationState(?cid, agreed) ],if (?cids != []) acre.advance(?cids,inform,result(clock, ?i)),?i = ?i + 1};

• Key Points:– The list construction conditions to reflect those conversations that started

with a message to subscribe to the clock topic that are subscribe conversations and which are in an agreed state.

Page 53: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

ACRE: Subscriber• The agree and refuse subscription message rules become:

+conversationAdvanced(?cid,subscribing,?index) :conversationHistory(?cid, ?index, received, subscribe, ?topic) &conversationProtocolName(?cid,subscribe) & topic(?topic) <-

acre.advance(?cid,agree,?topic);

+conversationAdvanced(?cid,subscribing,?index) :conversationHistory(?cid, ?index, received, subscribe, ?topic) &conversationProtocolName(?cid,subscribe) & ~topic(?topic) <-

acre.advance(?cid,refuse,?topic);

• And the standard cancel protocol use replaces the custom rule used in the non-ACRE version:+conversationCancelRequest(?cid) : true <-

acre.confirmCancel(?cid),acre.forget(?cid);

Page 54: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

ACRE: Subscriber#agent subscriber

module acre -> is.lill.acre.agent.module.ACREModule;

+initialized : true <-acre.init, +topic(clock);

+topic(clock) : true <-?i = 0,while(true) {.sleep(1000),?cids = list[?cid | conversationHistory(?cid, 1, received, subscribe, clock) &conversationProtocolName(?cid, subscribe) &conversationState(?cid, agreed) ],if (?cids != []) acre.advance(?cids,inform,result(clock, ?i)),?i = ?i + 1};

+conversationAdvanced(?cid,subscribing,?index) :

conversationHistory(?cid, ?index, received, subscribe, ?topic) &conversationProtocolName(?cid,subscribe) & topic(?topic) <-acre.advance(?cid,agree,?topic);

Page 55: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

ACRE: Subscriber+conversationAdvanced(?cid,subscribing,?index) :

conversationHistory(?cid, ?index, received, subscribe, ?topic) &conversationProtocolName(?cid,subscribe) & ~topic(?topic) <-

acre.advance(?cid,refuse,?topic);

+conversationCancelRequest(?cid) : true <-acre.confirmCancel(?cid),acre.forget(?cid);

Page 56: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

ACRE: Subscribee• Similar modifications are made to the initialization process for

the Subscribee:

module acre -> is.lill.acre.agent.module.ACREModule;

+initialized : true <-acre.addRepository("file:///C:/Users/rem/acre"),acre.init,acre.addContact(agentID(subscriber,addresses("local:localhost"))),acre.start(org.fipa_subscribe_1.0,subscriber,subscribe,clock);

• Key Points:– Again note the new facility to use the address: “local:localhost” for the

local message transport service!

Page 57: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

ACRE: Subscribee• The agreement and refusal message rules are modified as

follows:+conversationAdvanced(?cid,agreed,?in) :conversationHistory(?cid,?in,received,inform,result(?topic, ?value)) &conversationProtocolName(?cid,subscribe) <-!handleSubscriptionResult(?topic, ?value);

+conversationAdvanced(?cid,refused,?index) :conversationProtocolName(?cid,subscribe) <-acre.forget(?cid);

• Key Points:– The implementation of the !handleSubscriptionResult(…) goal remains

the same.– We need to forget the conversation when the subscription is refused…

Page 58: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

ACRE: Subscribee• Finally, the cancellation rule (which triggers cancellation once

the clock reaches 2) is modified as follows:+clock(?x) : ?x > 2 & conversationHistory(?cid, 1, sent, subscribe, clock) <-

acre.cancel(?cid),acre.forget(?cid);

Page 59: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

ACRE: Subscribee#agent subscribee

module acre -> is.lill.acre.agent.module.ACREModule;

+initialized : true <-acre.addRepository("file:///C:/Users/rem/acre"),acre.init,acre.addContact(agentID(subscriber,addresses("local:acre.agentspeak.ucd.ie"))),acre.start(org.fipa_subscribe_1.0,subscriber,subscribe,clock);

+conversationAdvanced(?cid,agreed,?index) :

conversationHistory(?cid, ?index, received, inform, result(?topic, ?value)) &conversationProtocolName(?cid,subscribe) <-!handleSubscriptionResult(?topic, ?value);

+conversationAdvanced(?cid,refused,?index) : conversationProtocolName(?cid,subscribe) <-are.forget(?cid);

+!handleSubscriptionResult(clock, ?x) : true <-if (clock(?y)) .replace(clock(?y), clock(?x))else +clock(?x);

+clock(?x) : ?x > 2 & conversationHistory(?cid, 1, sent, subscribe, clock) <-acre.cancel(?cid),acre.forget(?cid);

Page 60: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

ACRE: Deploymentpublic class Main {

public static class ACREDebugConfig extends AgentSpeakDebugConfiguration { public ACREDebugConfig() { super("acre", null); }

public void configure() { addServiceInspectorFactory( new ProtocolManagerServiceInspectorFactory() );

super.configure(); addPlatformService(

ProtocolManagerPlatformService.class,ProtocolManagerPlatformService.NAME );

addAgent(“subscriber", “acre/subscriber.aspeak"); addAgent("subscribee", “acre/subscribee.aspeak");

}}

public static void main(String[] args) { new ACREDebugConfig().configure();}

}

Page 61: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

SECTION 4: COMBINED PROTOCOLS

Page 62: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

Combined Protocols• In this example, we combine the request and subscribe protocols.

– Specifically, we introduce a task that returns a list of topics in the form [topic1, topic2, …]

– The initiator agent uses this list to find out which topics are available, and subscribes to all such topics.

• In this case, there is only one topic: the clock topic.

• Two agents are created in this example:– combined.aspeak: the agent that provides the subscription service &

supports subscription discovery though the listTopics task.– combinee.aspeak: the agent that queries for topics and subscribes to any

topic listed.

Page 63: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

non-ACRE: Combined#agent combined

+initialized : true <-+topic(clock);

+topic(clock) : true <-?i = 0,while(true) {durative(.sleep(1000)),?aids = list[?aid | subscription(?aid, clock) ],if (?aids != []) .send(inform, ?aids, value(clock, ?i)),?i = ?i + 1};

+message(subscribe, ?agentID, ?topic) : topic(?topic) <-

.send(agree, ?agentID, ?topic),+subscription(?agentID, ?topic);

+message(subscribe, ?agentID, ?topic) : ~topic(?topic) <-.send(refuse, ?agentID, ?topic);

+message(cancel, ?agentID, protocol(subscribe, ?topic)) : subscription(?agentID, ?topic) <--subscription(?agentID, ?topic);

canDo(listTopics);

Page 64: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

non-ACRE: Combined+message(request, ?initiator, ?task) : canDo(?task) <-

+performingTask(?initiator, ?task),.send(agree, ?initiator, ?task),try {!performTask(?initiator, ?task)} recover {if (performingTask(?initiator, ?task)) .send(failure, ?initiator, ?task)}-performingTask(?initiator, ?task);

+message(request, ?initiator, ?task) : ~canDo(?task) <-.send(refuse, ?initiator, ?task);

+message(cancel, ?initiator, protocol(request, ?task)) : performingTask(?initiator, ?task) <--performingTask(?initiator, ?task);

// Custom Tasks+!performTask(?agentID, listTopics) : true <-

?list = list[?topic | topic(?topic)],.send(inform, ?agentID, result(listTopics, ?list));

// Default Task - no implementation = task failure+!performTask(?agentID, ?task) : true<-

.send(failure, ?agentID, ?task);

Page 65: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

non-ACRE: Combinee#agent combinee

+initialized : true <-.send(request, agentID(combined, addresses("local:localhost")), listTopics);

+message(inform, ?agentID, result(?task, ?value)) : true <-!handleRequestResult(?agentID, ?task, ?value);

+!handleRequestResult(?agentID, listTopics, ?topics) : true <-?list = ?topics,while (?list != []) {

+subscribing(clock, combined),.send(subscribe, ?agentID, head(?topics)),?list = tail(?list)

}; +message(agree, agentID(?name, ?addr), ?topic) : subscribing(?topic, ?name) <-

-subscribing(?topic, ?name),+subscribed(?topic, agentID(?name, ?addr));

+message(refuse, agentID(?name, ?addr), ?topic) : subscribing(?topic, ?name) <--subscribing(?topic, ?name);

Page 66: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

non-ACRE: Combinee+message(inform, ?agentID, value(?topic, ?value)) : subscribed(?topic, ?agentID) <-

!handleSubscriptionResult(?topic, ?value);

+!handleSubscriptionResult(clock, ?x) : true <-if (clock(?y)) .replace(clock(?y), clock(?x))else +clock(?x);

+clock(?x) : ?x > 2 & subscribed(clock, ?agentID) <--subscribed(clock, ?agentID),.send(cancel, ?agentID, protocol(subscribe, clock));

Page 67: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

non-ACRE: Summary• The combined agent is simply the requester and subscriber agents

combined:– The requester code has been modified to introduce support for the listTopics

task.

• The combinee agent is more complex as it must process the topic list and subscribe to each topic:+!handleRequestResult(?agentID, listTopics, ?topics) : true <-?list = ?topics,while (?list != []) {+subscribing(clock, combined),.send(subscribe, ?agentID, head(?topics)),?list = tail(?list)};

• The bold lines above represent the start of the subscribe protocol…

Page 68: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

ACRE: Combined#agent combined

module acre -> is.lill.acre.agent.module.ACREModule;

+initialized : true <-acre.init,+topic(clock);

+topic(clock) : true <-?i = 0,while(true) {.sleep(1000),?cids = list[?cid | conversationHistory(?cid, 1, received, subscribe, clock) & conversationProtocolName(?cid, subscribe) &conversationState(?cid, agreed) ],if (?cids != []) acre.advance(?cids,inform,result(clock, ?i)),?i = ?i + 1};

+conversationAdvanced(?cid,subscribing,?index) :

conversationHistory(?cid, ?index, received, subscribe, ?topic) &conversationProtocolName(?cid,subscribe) & topic(?topic) <-acre.advance(?cid,agree,?topic);

Page 69: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

ACRE: Combined+conversationAdvanced(?cid,subscribing,?index) :

conversationHistory(?cid, ?index, received, subscribe, ?topic) &conversationProtocolName(?cid,subscribe) & ~topic(?topic) <-

acre.advance(?cid,refuse,?topic);

+conversationCancelRequest(?cid) : true <-acre.confirmCancel(?cid),acre.forget(?cid);

canDo(listTopics);

+conversationAdvanced(?cid,requested,?index) :conversationHistory(?cid, ?index, received, request, ?task) &conversationProtocolName(?cid,request) & canDo(?task) <-

acre.advance(?cid,agree,?task),try {

!performTask(?cid, ?task)} recover {

acre.advance(?cid,failure,?task)};

Page 70: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

ACRE: Combined+conversationAdvanced(?cid,requested,?index) :

conversationHistory(?cid, ?index, received, request, ?task) &conversationProtocolName(?cid,request) & ~canDo(?task) <-

acre.advance(?cid,refuse,?task);

+conversationCancelRequest(?cid) : true <-acre.confirmCancel(?cid),acre.forget(?cid);

// Custom Tasks+!performTask(?cid, listTopics) : true <-

?list = list[?topic | topic(?topic)],acre.advance(?cid,inform, result(listTopics, ?list));

// Default Task - no implementation = task failure+!performTask(?agentID, ?task) : true<-

acre.advance(?cid,failure, ?task);

Page 71: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

ACRE: Combinee#agent combinee

module acre -> is.lill.acre.agent.module.ACREModule;

// Get the topic list+initialized : true <-

acre.addRepository("file:///C:/Users/rem/acre"),acre.init,acre.addContact(agentID(combined,addresses("local:localhost"))),acre.start(org.fipa_request_1.3,combined,request,listTopics);

// Subscribe to all listed topics+conversationAdvanced(?cid,done2,?index) :

conversationHistory(?cid, ?index, received, inform, result(?task, ?value)) & conversationProtocolName(?cid,request) <-!handleRequestResult(?cid, ?task, ?value);

+!handleRequestResult(?cid, ?task, ?topics) : ?task == listTopics <-?list = ?topics,while (?list != []) {acre.start(org.fipa_subscribe_1.0,combined,subscribe,head(?topics)),?list = tail(?list)};

Page 72: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

ACRE: Combinee+conversationAdvanced(?cid,agreed,?index) :

conversationHistory(?cid, ?index, received, inform, result(?topic, ?value)) &conversationProtocolName(?cid,subscribe) <-

!handleSubscriptionResult(?topic, ?value);

+conversationAdvanced(?cid,refused,?index) : conversationProtocolName(?cid,subscribe) <-arce.forget(?cid);

+!handleSubscriptionResult(clock, ?x) : true <-if (clock(?y)) .replace(clock(?y), clock(?x))else +clock(?x);

+clock(?x) : ?x > 2 & conversationHistory(?cid, 1, sent, subscribe, clock) <-acre.cancel(?cid),acre.forget(?cid);

Page 73: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

SECTION 5: DIRECTORY FACILITATOR SERVICE

Page 74: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

Overview• The Directory Facilitator (DF) Service is a FIPA-specified platform

service that provides support for advertising and locating services provided by agents.– The service is constrained to the agent platform.– Agents register with the service– Once registered, agents can advertise services that they offer and look for

agents that provide services they need.

• The DF Service is supported in AF-AgentSpeak through the com.agentfactory.clf.library.DFSLibrary module.

• We will illustrate the use of this service by modifying the request protocol example.

Page 75: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

non-ACRE• For the requester agent, the only modifications involve connecting to

and registering with the DF Service:module dfs->com.agentfactory.clf.library.DFSLibrary;

+initialized : true <-dfs.setup,dfs.register;

• For the requestee agent, the only modification is to use the service to identify the participant in the conversation:

module dfs->com.agentfactory.clf.library.DFSLibrary;

+initialized : true <-dfs.setup,dfs.register,when (dfsService(agentID(requester, ?addr))) {.send(request, agentID(requester, ?addr), drink(beer))};

Page 76: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

non-ACRE: Requester#agent requester

module dfs->com.agentfactory.clf.library.DFSLibrary;

+initialized : true <-dfs.setup,dfs.register;

// FIPA REQUEST PROTOCOL RULES +message(request, ?initiator, ?task) : canDo(?task) <-

+performingTask(?initiator, ?task),.send(agree, ?initiator, ?task),try {!performTask(?initiator, ?task)} recover {if (performingTask(?initiator, ?task)) .send(failure, ?initiator, ?task)}-performingTask(?initiator, ?task);

+message(request, ?initiator, ?task) : ~canDo(?task) <-.send(refuse, ?initiator, ?task);

Page 77: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

non-ACRE: Requester+message(cancel, ?initiator, protocol(request, ?task)) :

performingTask(?initiator, ?task) <--performingTask(?initiator, ?task);

// TASKScanDo(drink(beer));canDo(tell_time);

+!performTask(?initiator, drink(beer)) : name(?name) <-[performingTask(?initiator, drink(beer))]

.println("[" + ?name + "] Mmmm tasty beer"),

.send(inform, ?initiator, done(drink(beer)));

+!performTask(?initiator, tell_time) : name(?name) & time(?h, ?m, ?s) <-[performingTask(?initiator, tell_time)]

.send(inform, ?initiator, result(tell_time, time(?h, ?m, ?s)));

+!performTask(?initiator, ?task) : true <-.fail;

Page 78: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

non-ACRE: Requestee#agent requestee

module dfs->com.agentfactory.clf.library.DFSLibrary;

+initialized : true <-dfs.setup,dfs.register,when (dfsService(agentID(requester, ?addr))) {

.send(request, agentID(requester, ?addr), drink(beer))};

+message(inform, ?agentID, done(drink(beer))) : true <-

.send(request, agentID(requester, addresses("local:localhost")), tell_time);

+message(inform, ?agentID, result(tell_time, time(?h, ?m, ?s))) : true <-.println("The time is: "+?h + ":"+?m+":"+?s);

Page 79: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

ACRE• For the ACRE implementation, the modifications are largely

the same, except that the initiator adds the agent as a contact once it has been discovered.

module dfs->com.agentfactory.clf.library.DFSLibrary;

+initialized : true <-dfs.setup,dfs.register,when (dfsService(agentID(requester, ?addr))) {

acre.addContact(agentID(requester,?addr)),acre.start(org.fipa_request_1.3,combined,request,drink(beer));

};

Page 80: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

ACRE: Requester#agent requester

module acre -> is.lill.acre.agent.module.ACREModule;module dfs->com.agentfactory.clf.library.DFSLibrary;+initialized : true <- acre.init, dfs.setup, dfs.register,

+conversationAdvanced(?cid,requested,?index) : conversationProtocolName(?cid,request) & canDo(?task) &conversationHistory(?cid, ?index, received, request, ?task) <-acre.advance(?cid, agree, ?task),try {!performTask(?initiator, ?task)} recover {acre.advance(?cid, failure,? task)};

+conversationAdvanced(?cid,requested,?index) : conversationProtocolName(?cid,request) & ~canDo(?task) &conversationHistory(?cid, ?index, received, request, ?task) <-acre.advance(?cid, refuse, ?task);

+conversationCancelRequest(?cid) : true <- acre.confirmCancel(?cid), acre.forget(?cid);

canDo(drink(beer));

+!performTask(?cid, drink(beer)) : name(?name) <- [conversationHistory(?cid, 1, received,request,tell_time)].println("[" + ?name + "] Mmmm tasty beer"),acre.advance(?cid, inform, done(drink(beer)));

+!performTask(?cid, ?task) : true <- .fail;

Page 81: AFAS/ACRE Examples. Introduction This guide contains practical examples of how to program protocols in AF-AgentSpeak.  It covers programming both with

ACRE: Requestee#agent requestee

module acre -> is.lill.acre.agent.module.ACREModule;

+initialized : true <-acre.addRepository("file:///C:/Users/rem/acre"), acre.init,dfs.setup,dfs.register,when (dfsService(agentID(requester, ?addr))) {acre.addContact(agentID(requester,?addr)),acre.start(org.fipa_request_1.3,combined,request,drink(beer));};

+conversationAdvanced(?cid,refused,?index) :

conversationProtocolName(?cid,request) <-acre.forget(?cid);

+conversationAdvanced(?cid,done,?index) : conversationProtocolName(?cid,request) <-acre.start(org.fipa_request_1.3,requester,request,tell_time);

+conversationMessage(?cid,inform,result(tell_time, time(?h, ?m, ?s))) : true <-.println("The time is: "+?h + ":"+?m+":"+?s);