Deploying Multiple Agents

Agent Programming Languages are designed to support the development of multi-agent systems. By default, it is expected that such systems will consist of more than one agent and more than one agent type. In many Agent Programming Languages, support for deploying multiple agents is provided through deployment files that allow the developer to specify the initial community of agents that are to be deployed.

ASTRA does not do this, instead, you simply write an agent that creates more agents. The core functionality to support this approach is provided through the System API. In this lesson, we will explore how to use thisAPI to create some basic multi-agent systems. However, we will not discuss communication here – this is discussed in a later lesson on Agent Communication.

Creating Agents Dynamically

Coding an agent to create another agent is quite simple in ASTRA. You simply call the createAgent(…) action that is part of the System API.

To illustrate this, the program below consists of 2 agent classes: The first class is the one you run and the second class is used by the first class when it creates agents. Basically, the idea is that the “main” agent creates 5 “hello” agents that print out “Hello World, X” where X is their name.

  package examples;
  
  agent Main {
      module System system;
      
      initial !init();
      
      rule +!init() {
          int X = 0;
          while (X < 5) {
              system.createAgent("hello"+X, "examples.HelloWorld");
              X = X + 1;
          }
      }
  }
  
  package examples;
  
  agent HelloWorld {
      module System system;
      module Console console;
      
      initial !init();
      
      rule +!init() {
          console.println("Hello World, " + system.name());
      }
  }

Self Terminating Agents

Agents are able to terminate themselves by calling the terminate() action from the System API. This allows an agent to be created, to complete a task, and then to terminate itself. For example, in the example above, the HelloWorld agents continue to run after they have printed out their “Hello World, X” message to the console – a better solution is to terminate the agent after it has finished:

  package examples;
  
  agent HelloWorld {
      module System system;
      module Console console;
      
      initial !init();
      
      rule +!init() {
          console.println("Hello World, " + system.name());
          system.terminate();
      }
  }

Unfortunately, this would still leave the “main” agent running, but it is possible for this agent to monitor how many agents are left in the community and also terminate itself when all of its children have been terminated.

  package examples;
  
  agent Main {
      module System system;
      module Console console;
      module Prelude prelude;
      
      initial !init();
      
      rule +!init() {
          int X = 0;
          while (X < 5) {
              system.createAgent("hello"+X, "examples.HelloWorld");
              X = X + 1;
          }
          !awaitChildTermination();
      }
      
      rule +!awaitChildTermination() {
          int N = prelude.size(system.getAgents());
          while (N > 1) {
              console.println("there are: " + N + " agents.");
              system.sleep(1000);
              N = prelude.size(system.getAgents());
          }
          console.println("Finished Task");
          system.exit();
      }
  }

As can be seen, this can be achieved by creating an +!awaitChildTermination() rule that is invoked after the other agents are created. This agent checks how many other agents are on the platform. If there is more than 1 (i.e. more than itself), then it sleeps for 1 second and checks again. Once there is only one agent left (itself), the “main” agent terminates itself.

Of course, this is a simple example, but the basic approach can be fine-tuned for many more complex scenarios. Also, it is possible to introduce Agent Communication into the mix, which would allow the created agents to send back results of any task (or other appropriate information).

Controlled Termination of Agents

An alternative to self-termination is to make the main agent terminate the HelloWorld agents. An agent is able to terminate another agent only if it was the agent that created the other agent. In the example used on this page, that agent is the main agent. As a simple example, we can modify the original program so that the “main” agent creates the “HelloWorld” agents, goes to sleep for a minute, and then terminates those agents. In this case, we only need to modify the Main class (the original HelloWorld class can be used):

  package examples;
  
  agent Main {
      module System system;
      module Console console;
      
      initial !init();
      
      rule +!init() {
          int X = 0;
          while (X < 5) {
              system.createAgent("hello"+X, "examples.HelloWorld");
              X = X + 1;
          }
          
          system.sleep(1000);
          
          X = 0;
          while (X < 5) {
              system.terminateAgent("hello"+X);
              X = X + 1;
          }
          system.exit();
      }
  }

Again, when combined with communication, the above solution can be made more elegant, but again, the basic concept applies – when the task is complete, the agent that created the other agents terminates them all and then terminates itself.

Examples

Agent Creation and Termination

This program creates a second agent called “worker” which is an instance of the “example.Hello” class:

  package example;
  
  agent Starter {
      module Console console;
      module System system;
  
      rule +!main(list args) {
          system.createAgent("worker", "example.Hello");
          system.sleep(1000);
          system.terminateAgent("worker");
      }
  }
  
  package example;
  
  agent Hello {
      module Console console;
  
      initial !init();
  	
      rule +!init() {
          console.println("Hello World!");
      }
  }

Agent Types

This program prints out a list of all the agents that have the same type as the program:

  package example;
  
  agent Types {
      module Console console;
      module System system;
      
      rule +!main(list args) {
          if (system.hasType("example.Types")) console.println("it's alive");
          console.println("Searching for agents of type: " + system.getType());
          console.println("Agents: " + system.getAgentsOfType(system.getType()));
          console.println("Explicit List of Agents: " +
                                   system.getAgentsOfType("example.Types"));
          system.exit();
      }
  }