CLF::AMS Library

From Agent Factory

Jump to: navigation, search

This library provides support for interacting with the FIPA Agent Management Service which is deployed by default on all agent platforms. It can be used with any agent that is implemented using a language that is based on the Common Language Framework. All of the examples provided on this page are based on AF-AgentSpeak. Details of other libraries provided with the Common Language Framework can be found here.

Contents

Installing the Library

To use the AMS Library, you must add the following line to your AgentSpeak program:

module ams -> com.agentfactory.clf.library.AMSLibrary;

All actions may then be accessed by using the prefix "ams". This is because you associated the library with this identifier. If you change the module identifier, then any action call must be prefixed by the new identifier.

Actions

This module provides actions to allow the agent to access the functionality of the FIPA AMS platform service.

Action Description

.setup

Initializes the library and binds the agent to the FIPA Agent Management Service.
Example:

#agent example

module ams -> com.agentfactory.clf.library.AMSLibrary;

+initialized : true <-
    ams.setup;

The AMS Library is now initialised and ready to use.

.create(?name, ?design)

Creates a local agent with the given name (if an agent with this name does not already exist) that is based on the given design.
Example:

#agent example

module ams -> com.agentfactory.clf.library.AMSLibrary;

+initialized : true <-
    ams.setup,
    ams.create("Rem", "example.aspeak");

Creates an agent called "Rem" that is based on the "example" agent. The agent is created in a suspended state.

.terminate(?name)

Terminates the agent with the given name (if it exists).
Example:

#agent example

module ams -> com.agentfactory.clf.library.AMSLibrary;

+initialized : name(?name) <-
    ams.setup,
    ams.terminate(?name);

The agent terminates itself.

.resume(?name)

Resume execution of the agent with the given name (if it exists). If the agent is already in an active state, then the action is ignored.
Example:

#agent example

module ams -> com.agentfactory.clf.library.AMSLibrary;

+initialized : name(?name) <-
    ams.setup,
    ams.create("Rem", "example.aspeak");
    ams.resume(Rem);

Create the agent "Rem" and start it.

.suspend(?name)

Suspends execution of the agent with the given name (if it exists). If the agent is already suspended, then the action is ignored.
Example:

#agent example

module ams -> com.agentfactory.clf.library.AMSLibrary;

+initialized : name(?name) <-
    ams.setup,
    ams.suspend(?name);

The agent suspends itself.

Sensors

Sensors provide beliefs that the agent can use to make decisions about how best to act. The Core API comes with a number of default sensors that are listed below.

Action Generates Description

.agents

localAgent(?name)
agentType(?name, ?type)
agentState(?name, ?state)
agentID(?name, ?addr)

The first belief relates to the agents that are residing on the local platform. One instance of this belief is generated per agent on the platform - each belief holds the name of one of the agents currently residing on the agent platform.

The second belief associates a type with each local agent. One instance of this belief is generated per agent on the platform. Here, ?type refers to the type of agent (e.g. AF-AgentSpeak, AF-APL, AF-TR, AF-RMA, ...).

The third belief associates a state with each local agent. One instance of this belief is generated per agent on the platform. Here, ?state refers to the current state of the agent, and may be one of: {active, initiated, suspended, terminated, transit, waiting}. These states have been chosen in compliance with the FIPA standards.

The fourth belief represents the agent identifier of each local agent. This is in the same form as the belief that the agent has about its own agent identifier.

Examples

This section provides some basic examples that illustrate how to use the AMS Library.

Creating Agents Dynamically

Perhaps the most powerful feature of the AMS API is the ability to create agents dynamically (i.e. at run-time). The program below outlines how to do this based on a simple scenario in which 10 agents are created. Once started, each agent then creates the next agent in the sequence.

#agent creator

module ams -> com.agentfactory.clf.library.AMSLibrary;

+initialized : true <-
    ams.setup,
    ?next = 0,
    ?count = 1,
    while (?count < 11) {
        if (~localAgent(agent+?count) & ~name(agent+?count)) {
            ?next = ?count,
            ?count = 11
        } else {
            ?count = ?count + 1
        }
    },
    if (?next > 0) {
        ams.create(agent+?next, launcher.aspeak),
        .println("Agent: agent" + ?count + " has been created."),
        ams.resume(agent+?next)
    };

To run the platform, we create a single agent, called "initial" that is an instance of the above program (lets call it launcher.aspeak). When run, the overall system goal is to create 10 agents labelled agent1-agent10 respectively. Each agent that is created at runtime is responsible for creating the next agent in the sequence. The plan that is used to achieve this can be broken into 3 parts:

  • line 1: this first part of the plan sets up the AMS API by performing the ams.setup action. This links the API to the underlying platform service.
  • lines 2-11: this second part of the plan uses the localAgent(...)' belief of the AMS API to work out which agent should be created next. Basically, this is a while loop in which the ?count variable is incremented repeatedly until there is a value for ?count such that there is no local agent with the name "agent+?count" and also, this is not the name of the agent itself (as there will not be a belief that the agent is itself a localAgent). Once such a name is identified, the ?next variable is set to the corresponding value of ?count. If no name is found (i.e. agent10 has been created), then ?next remains bound to 0 (which indicates that no agent should be created).
  • lines 12-15: the final part of the plan creates the next agent (if required). It uses the ams.create(...) action to create the next agent, and the ams.resume(...) action to start the agent once it has been created.

Suspending Agents

To illustrate how to suspend agents at runtime, we can extend the example used in the previous section to include a fourth step to the plan in which the agent suspends itself once it has created and resumed the next agent.

#agent suspender

module ams -> com.agentfactory.clf.library.AMSLibrary;

+initialized : true <-
    ams.setup,
    ?next = 0,
    ?count = 1,
    while (?count < 11) {
        if (~localAgent(agent+?count) & ~name(agent+?count)) {
            ?next = ?count,
            ?count = 11
        } else {
            ?count = ?count + 1
        }
    },
    if (?next > 0) {
        ams.create(agent+?next, launcher.aspeak),
        .println("Agent: agent" + ?count + " has been created."),
        ams.resume(agent+?next)
    },
    foreach(name(?name)) {
        ams.suspend(?name)
    };

Here, the name(...) belief is used with a foreach(...) plan operator to bind the variable ?name to the agents name. This is then used in the ams.suspend(...) action.

Terminating Agents

For this final example, we show a simple agent program that is designed initially to be used by an agent with name A. Agent A its name, creates an agent called agent B, and terminates itself. Agent B, once started, checks its name, creates an agent with name A, and terminates itself. This continues on until the agent platform is stopped. The program is called "switcher.aspeak"

#agent terminator

module ams -> com.agentfactory.clf.library.AMSLibrary;

+initialized : name(?name) <-
    ams.setup,
    durative(.sleep(1000)),
    if (?name == A) {
        ams.create(B, switcher.aspeak),
        .println("Creating B"),
        ams.resume(B)
    } else {
        ams.create(A, switcher.aspeak),
        .println("Creating A"),
        ams.resume(A)
    },
    ams.terminate(?name);