AFAPL2

From Agent Factory

Jump to: navigation, search

Contents

Overview

AFAPL2 is an extended version of the original Agent Factory Agent Programming Language (AFAPL) that combines the basic features of AFAPL:

With an additional set of features that have been motivated by the use of AFAPL in a number of Irish and European-funded research projects:

  • Additional practical Plan operators
  • A Role programming construct
  • A notion of a Goal
  • Support for specifying ontologies that the agent uses via an Ontology construct.

As is highlighted in the figure on the right-hand side, the language is based on a mental state model that consists of a number of primary mental attitudes together with a set of meta attitudes that support the primary mental attitudes. Further, the interface between the agent and its environment is implemented as a set of Java classes, together with a support class that enables the creation of internal private resources that can be used by the agent to implement any additional data structures that may be required.

Finally, as can be seen, the underlying environment is implemented as a combination of Platform Serivces; other external systems whose interfaces can either be accessed directly or alternatively via some Module; and any other agents deployed in the system.

This page provides an overview of concepts that underpin the AFAPL2 language, which is executed on a purpose-built agent interpreter. For information on how to use the language to develop agents, please read the AFAPL2 Programmers Guide.

Mental State Model

The mental state of an AFAPL2 agent consists of the following components:

  • A Belief set: this component is used to build a model of the state of the agents environment.
  • A Commitment set: this component is used to represent the decisions that the agent has made about how to act.
  • A Plan Library: this component holds a set of pre-written plans that the agent may commit to.
  • An Action set: this component holds the set of primitive activities that the agent may perform.
  • A Commitment Rule set: this component holds a set of rules that encapsulate the decision-making process of the agent (i.e. in what situations the agent should make a Commitment to a given plan or action).
  • A Role Library: this component holds a set of pre-written roles that the agent may play.
  • An Ontology set: this component holds a set of ontologies that model the kinds of facts and objects that the agent can use to reason about its environment.

The Core Java Components

In addition to the mental components listed in the previous section, AFAPL2 also makes use of three Java components:

  • Perceptors: These components implement the basic sensory apparatus of an agent, in that they are used to generate beliefs about the current state of the agent and its environment.
  • Actuators: These components implement the basic capabilities of an agent. That is, they are implementations of the Actions of an agent.
  • Modules: These components are private resources that can be used to implement additional data structures that an agent needs or to provide interfaces to external systems.

A Reuse Mechanism

AFAPL2 provides a simple mechanism for reusing code that is based on the #include statement of C, namely the IMPORT statement.

The AFAPL2 Interpreter

AFAPL2 agents function as a result of their mental state being manipulated by an underlying interpreter whose implementation is a variation on the basic execution cycle of a deliberative agent, namely:

perceive -> deliberate -> act

As can be seen in the diagram on the right-hand side, for AFAPL2, this basic cycle is implemented as a four-stage process:

In terms of the basic cycle, the perceive functionality is implemented as part of the belief update process, and the act functionality is implemented as part of the commitment management process (specifically, actions are performed in the commitment realisation phase of this process).

These steps are performed repeatedly, in the specified order, until the agent is terminated.

Further details of this algorithm can be found in relevant papers that are available from this website. Instead, this guide will focus on the practicalities of building agents using the AFAPL2 language.

Example Program

To illustrate the AFAPL2 programming language, two example agent program that implement a Vickrey-style auction are outlined. This example combines a number of concepts, such as agent communciation, plans, beliefs and commitment rules. The AFAPL2 Programmers Guide also includes a number of worked examples that illustrate these concepts in a more focused way.

The specific auction implemented in the example below is a single-shot, highest bidder wins auction. The implementation is separated into two AFAPL2 programs: Auctioneer.afapl2 and Bidder.afapl2, that implement the auctioneer and bidder behaviours respecively. An Agent UML Protocol Diagram for this auction is outlined to the right-hand side. We will explore these two programs in the following sections.

Bidder.afapl2

Let us start by exploring the simpler Bidder.afapl2 agent program:

IMPORT com.agentfactory.afapl2.core.agent.FIPACore;

ONTOLOGY Bidder {
    PREDICATE bid(?item, ?amt);
}

ACTION randomBid(?item) {
    PRECONDITION BELIEF(true);
    POSTCONDITION BELIEF(true);
   
    USES Bidder;
   
    CLASS actuator.RandomBid;
}

BELIEF(fipaMessage(cfp, sender(?name, ?addr), auction(?item))) =>
COMMIT(?self, ?now, BELIEF(true),
    PAR(randomBid(?item),
        DO_WHEN(BELIEF(bid(?item, ?amt)),
            propose(agentID(?name, ?addr), bid(?item, ?amt))
        )
    )
);

The first statement of this program imports a pre-existing AFAPL2 agent program that specifies all of the actions and perceptors necessary to support FIPA ACL-based agent communication. This includes a Perceptor that generates beliefs about messages received by the agent, and Actions that support sending of messages using any of the standard FIPA performatives.

The next statement declares an Ontology that includes one predicate - bid(?item, ?amt) - that can be used to represent the bid that an agent makes for an item. Beliefs of this form are generated by the randomBid(...) Action, which is declared in the third statement. The pre- and post-conditions associated with this Action are default values that are often used, and which always evaluate to true. The USES statement associates this Action with the Bidder Ontology. This is used to simplify the declaration of beliefs in the corresponding Actuator which is declared on the final line (CLASS) of the ACTION statement. This Actuator is implemented as follows:

package actuator;

import com.agentfactory.logic.agent.Actuator;
import com.agentfactory.logic.agent.Belief;
import com.agentfactory.logic.lang.FOS;
import java.util.Random;

public class RandomBid extends Actuator {
    static final Random random = new Random();
  public boolean act(FOS action) {
    String item = action.argAt(0).toString();

    int amt = random.nextInt();
    Belief belief = createBelief("bid");
    belief.bind("?item", item);
    belief.bind("?amt", "" + amt);
    adoptBelief(belief);
    return true;
  }
}

Note that the createBelief(...) method creates a template belief based on the PREDICATE defined in the associated Ontology, in this case the Bidder Ontology. Individual variables can the be bound to values using the bind(...) method, and the Belief adopted via the adoptBelief(...) method.

The last statement of the Bidder.afapl2 agent program is a Commitment Rule, which defines the behaviour of this agent. Specifically, the rule states that: in the situate where the agent believes that it has received a cfp message from another agent that has the content action(?item), then the agent should adopt the following Plan to generate and return a random bid, and then send a propose message to the agent that sent the cfp message with the coresponding bid for the item.

Auctioneer.afapl2

In contrast, the Auctioneer.afapl2 agent program is more complex:

IMPORT com.agentfactory.afapl2.core.agent.FIPACore;

ONTOLOGY Auctioneer {
    PREDICATE wantToAuction(?item);
    PREDICATE duplicateAuction(?item);
    PREDICATE unknownAuction(?item);
    PREDICATE client(?name, ?addr);
    PREDICATE winner(?item, ?agentID, ?amt);
    PREDICATE loser(?item, ?agentID);
}

LOAD_MODULE auction module.Auctions;

PERCEPTOR auctionView {
    USES Auctioneer;

    CLASS perceptor.AuctionView {
        module=auction;
    }
}

ACTION startAuction(?item) {
    PRECONDITION BELIEF(true);
    POSTCONDITION BELIEF(true);
    
    USES Auctioneer;
    
    CLASS actuator.StartAuction {
        module=auction;
    }
}

ACTION recordBid(?item, ?name, ?bid) {
    PRECONDITION BELIEF(true);
    POSTCONDITION BELIEF(true);
   
    USES Auctioneer;
   
    CLASS actuator.RecordBid {
        module=auction;
    }
}

ACTION endAuction(?item) {
    PRECONDITION BELIEF(true);
    POSTCONDITION BELIEF(true);
    
    USES Auctioneer;
   
    CLASS actuator.EndAuction {
            module=auction;
    }
}

// Start an auction for the given item
BELIEF(wantToAuction(?item)) =>
COMMIT(?self, ?now, BELIEF(true),
    auction(?item)
);

PLAN auction(?item) {
    PRECONDITION BELIEF(true);
    POSTCONDITION BELIEF(true);
   
    BODY
        SEQ(startAuction(?item),
            FOREACH(BELIEF(client(?name, ?addr)),
                PAR(cfp(agentID(?name, ?addr), auction(?item)),
                    OR( DO_WHEN(BELIEF(fipaMessage(propose, sender(?name, ?addr2), bid(?item, ?amt))),
                            recordBid(?item, agentID(?name, ?addr2), ?amt)
                        ),
                        SEQ(DELAY(5),
                            recordBid(?item, agentID(?name, ?addr), 0)
                        )
                    )
                )
            ),
            PAR(FOREACH(BELIEF(winner(?item, ?agentID, ?amt)),
                    accept-proposal(?agentID, auction(?item, ?amt))
                ),
                FOREACH(BELIEF(loser(?item, ?agentID, ?amt)),
                    reject-proposal(?agentID, auction(?item))
                )
            ),
            endAuction(?item)
        );
}

Similarly to the #Bidder.afapl2 agent program, this program starts by importing the FIPACore AFAPL2 program, which defines any actions, perceptors and ontologies associated with FIPA ACL-based agent communication. The second statement then defines the associated "Auctioneer" Ontology of predicates that will be used to form beliefs in the program. This includes:

  • wantToAuction(?item): represents the fact that the agent wants to auction a specific item.
  • duplicateAuction(?item): represents the fact that there is already an auction taking place for that item.
  • unknownAuction(?item): represents the fact that there is no current auction for that item.
  • client(?name, ?addr): represents the fact that ?name is a client of the auctioneer and should be involved in any auction that takes place. Further, the client can be contacted via any of the transport addresses specified in ?addr.
  • winner(?item, ?agentID, ?amt): represents the fact that the agent with identifier ?agentID won the auction for ?item with a bid of ?amt.
  • loser(?item, ?agentID): represents the fact that the agent with identifier ?agentID lost the auction for ?item.

Following the Ontology declaration, a number of actions and perceptors are declared. All of these components make use of an internal Module which is declared first via the LOAD_MODULE construct. The module has an id "auction" and is implemented by the module.Auctions Java class, which is outlined below:

public class Auctions extends Module {
    Map<String, List<Bid>> auctions;

    @Override
    public void init() {
        auctions = new HashMap<String, List<Bid>>();
    }
   
    public boolean auctionExists(String item) {
        return auctions.containsKey(item);
    }
   
    public void startAuction(String item) {
        auctions.put(item, new LinkedList<Bid>());
    }
   
    public void endAuction(String item) {
        auctions.remove(item);
    }
   
    public void recordBid(String item, Bid bid) {
        auctions.get(item).add(bid);
    }
    
    public Collection<String> getItems() {
        return auctions.keySet();
    }
    
    public List<Bid> getBids(String item) {
        return auctions.get(item);
    }
}

This uses an auxhiliary class to store the bid information:

public class Bid {
    public String agentID;
    public int amount;
}

The auctionView Perceptor generates beliefs about the current state of any currently active auctions. As is indicated, via the USES statement, the beliefs that Perceptor generates should come from the "Auctioneer" Ontology. Specifically, as can be seen in the implementation below, this Perecptor generates beliefs using the winner and loser predicates.

--INSERT PERCEPTOR CODE HERE--

A useful note here is how the Perceptor gains access to the information stored in the Module. This is primarily through the getModuleByName(...) helper method that is provided by the AFAPL2 API, and which locates a Module instance based on a given Module identifier. In this case, the Module identifier is retrieved from the configuration of Perceptor which is declared in the curly brackets {...} at the end of the CLASS statement in the PERCEPTOR construct. As can be seen above, a configuration is declared that associates the key "module" with the value "auction", which is the identifier of the Module.