Fork me on GitHub

Behavior Reference

This document describes the features related to the definition of a behavior in SARL. Before reading this document, we recommend that you read the General Syntax Reference, and the Agent Reference.

A Behavior is the specification of a collection of behavior units. This Behavior may be used by an agent for building its global behavior.

1. Defining a Behavior

A behavior is declared with the behavior keyword. In the behavior's body block, we can declare Mental States (in the form of attributes), Actions and Behaviors.

1.1. Defining an empty behavior

The following code illustrates the definition of a behavior named [:behaviortype1], and that is empty.

Basically, this behavior does nothing, and does not react on events.

behavior MyBehavior {
}

1.2. Behavior Attributes

The mental state of an agent is composed by the data in the knowledge of the agent. A behavior may contain a part of this mental state. Most of the time, it is implemented as a collection of attributes.

According to the General Syntax Reference, the attributes may be modifiable (when declared with the var keyword), or unmodifiable (when declared with the val keyword).

behavior MyBehavior {
    // Defining a modifiable element of the mental state
    var mentalStateElement1 : String
    // Defining an unmodifiable element of the mental state
    val mentalStateElement2 : boolean = true
}

1.3. Behavior Actions

It is allowed to define actions (methods) in the behavior. The syntax described in the General Syntax Reference is used.

The example below illustrates the creation of type actions.

behavior MyBehavior {
    uses Logging
    // Defining an action without parameter nor return type
    def myAction1 {
        info("Hello world")
    }
    // Defining an action with a variadic parameter and no return type
    def myAction2(param : int*) {
        info("params are " + param)
    }
}

1.4. Extending a Behavior

In some use cases, it is useful to specialize the definition of a behavior. This mechanism is supported by the inheritance feature of SARL, which has the same semantic as the inheritance mechanism as the Java object-oriented language.

The extended behavior is specified just after the extends keyword.

A behavior type can extend only one other behavior type. This is close to the constraint on the extension of classes in the Java language.

In the following code, a first behavior is defined with the name MyBehavior and an attribute named attr. A second behavior MySubBehavior is defined as the extension of the first behavior. It contains a function named action, which is displaying the inherited attribute.

behavior MyBehavior {
    protected var attr : String
}
behavior MySubBehavior extends MyBehavior {
    uses Logging
    def action {
        info(attr)
    }
}

1.5. Instancing and Use of a Behavior

A behavior is always owned by an agent. Consequently, it is mandatory to pass the agent as parameter of the behavior's constructor.

In the following example, a behavior of type MyBehavior is instanced (with the agent as the owner/parameter). This new behavior is then registered into the agent for enabling the reception of the events in the behavior.

agent MyAgent {
    uses Behaviors
    on Initialize {
        // Create the instance of the behavior
        var beh = new MyBehavior(this) // <- the parameter is the agent

        // Register the behavior for receiving the events.
        // This function is given by the Behaviors capacity
        registerBehavior(beh)
    }
}

1.6. Modifiers

Modifiers are used to modify declarations of types and type members. This section introduces the modifiers for the behavior. The modifiers are usually written before the keyword for defining the behavior.

The complete description of the modifiers' semantic is available in this section.

Behavior Modifiers

A behavior may be declared with one or more modifiers, which affect its runtime behavior:

Examples:

public behavior Example1 {
}
package behavior Example2 {
}
abstract behavior Example3 {
}
final behavior Example4 {
}

Field Modifiers

The modifiers for the fields in a behavior are:

Examples:

public var example0 : Object
protected var example1 : Object
package var example2 : Object
private var example3 : Object

Method Modifiers

The modifiers for the methods in a behavior are:

Examples:

// Public access function
public def example0 { }
// Protected access function
protected def example1 { }
// Package access function
package def example2 { }
// Private access function
private def example3 { }
// Abstract function
abstract def example4
// Not-overridable function
final def example5 { }
// Dispatch functions
dispatch def example7(p : Integer) { }
dispatch def example7(p : Float) { }

2. Behavior Units of a Behavior

The behaviors of an agent correspond to the units that are executed by the agent for exhibiting its general behavior.

The Behavior statement permits specifying a subset of the agent's behavior inside a single syntactic entity. Two types of behaviors are considered:

The definition of the reactive behaviors is based on the event handling mechanism of SARL. Events may be emitted in spaces, and received by the agents, and their behaviors, belonging to these spaces. A behavior may indicate that it is interesting for receiving an event by specifying an event handler using the following syntax:

on EventName [ Guard ] {
    Statements
}

EventName is the name of event to wait for Guard is the optional specification of a predicate that may be true for executing the Statements. The statements are executed only if an event with the given name is received, and if the guard is true.

In the guard and the statements, it is possible to use the instance of the received event: the occurrence. This instance is represented by the occurrence keyword. It is an implicit variable as the keywords this and it.

2.1. Initialization Handler

When a behavior is ready to be executed by the runtime environment, usually when it is registered in its owning agent, it receives the Initialize event. This event is defined as:

interface Initialize extends Event {
}

It contains the list of the parameters given that are never set for behaviors.

behavior MyBehavior {
    uses Logging
    on Initialize {
        info("I'm initializing my behavior")
    }
}

2.2. Guarded Initialization Handler

Because Initialize is an event, the handler in the behavior could use a guard. This feature enables the developer to write different initialization blocks depending on the guards of the handlers.

In the following example, the first event handler is executed when the Initialize event has no parameter. The second event handler is executed when the event has at least one parameter.

behavior MyBehavior {
    uses Logging
    on Initialize [ occurrence.parameters.empty ] {
        info("First initialization")
    }
    on Initialize [ ! occurrence.parameters.empty ] {
        info("First initialization")
    }
}

2.3. Destruction Handler

The counterpart of Initialize is the event Destroy. This event is defined as:

interface Destroy extends Event {
}

Example:

behavior MyBehavior {
    uses Logging
    on Destroy {
        info("Destroying the behavior")
    }
}

2.4. Guarded Destruction Handler

As for Initialize, the handlers of the Destroy event could be guarded.

In the following example, the first event handler is executed when the Destroy is received and there is resource stored in the corresponding field. The second event handler is executed when there is no resource.

behavior MyBehavior {
    uses Logging
    var resource : Object
    on Destroy [ resource !== null ] {
        info("Destroying the behavior when there is a resource")
    }
    on Destroy [ resource === null ] {
        info("Destroying the behavior when there is no resource")
    }
}

2.5. Reactive Behavior Units

The reactive behavior is specified with a collection of event handlers. The principle of a reactive behavior is to execute a part of the behavior when something has happening in the behavior, the agent or in its environment.

In the following example, the behavior is reacting to the reception of the SomethingChanged event.

As for all the event handlers, it could be guarded by a predicate.

behavior MyBehavior {
    uses Logging
    on SomethingChanged {
        info("Reactive behavior")
    }
}

2.6. Parallel Execution of the Reactive Behavior Units

When an event is received and the guard of the corresponding handler is true, the event handler is said to be triggered.

When multiple event handlers are triggered at the same time, they are all executed in parallel. In the following example, the two handlers for the SomethingChanged event are executed in parallel.

behavior MyBehavior {
    uses Logging
    on SomethingChanged {
        info("First reactive behavior")
    }
    on SomethingChanged {
        info("Second reactive behavior")
    }
}

2.7. Pro-active Behavior Units

A proactive behavior is a part of the global behavior of an agent that the agent is deciding to execute by itself. The execution of a reactive behavior is initiated by a part of the code external to this behavior. In opposite, the initiator of the execution of a proactive behavior is the agent itself.

In SARL, a proactive behavior is a behavior that is scheduled by the agent or one of its behaviors. The schedule mechanism is provided by the Schedules built-in capacity. In the following example, the agent execute its proactive behavior every second.

behavior MyBehavior {
    uses Schedules, Logging
    on Initialize {
        every(1000) [
            info("Run a pro-active behavior")
        ]
    }
}

3. Capacities and Skills

An agent is an autonomous entity having a set of skills to realize the capacities it exhibits. An agent has a set of built-in capacities considered essential to respect the commonly accepted competencies of agents, such autonomy, reactivity, pro-activity and social capacities.

Consequently, a behavior associated to an agent is able to use the skills of this agent.

3.1. Defining a Capacity and a Skill

The definition of a capacity or a skill is out of the scope of this reference document. For details, please read the Capacity Reference, and the Skill Reference.

In the rest of this section, it is assumed that the following capacity and skill are defined:

capacity Cap {
    def action
}

skill Ski implements Cap {
    uses Logging
    def action {
        info("Action")
    }
}

3.2. Giving a Skill to the Associated Agent

When a behavior must use a capacity, its agent must own an implementation of this capacity: a skill. It is possible for a behavior to assign a skill to its agent.

3.3. Using a Capacity with the Getters

For invoking a function implemented by a skill, the two following steps must be done:

This method of invocation is not recommended by the SARL developers. You should prefer the use of the extension methods (see below).

behavior MyBehavior {
    on SomeEvent {
        // Retreive the capacity implementation
        var s = getSkill(Cap)
        // Run the action of the skill
        s.action
    }
}

3.4. Using a Capacity with the Extension Methods

Invoking a capacity/skill with the getter method is not user-friendly. Since the General Syntax Reference describes the "extension method" mechanism, it is possible to use it for invoking the capacities.

But, instead of using an import directive, the uses keyword is provided for importing the capacities into the agent. In the following example, the Cap capacity is imported.

After a capacity was "imported", it is possible to directly call the functions of the capacity (according to the extension method syntax). In the following example, the action with the name action is invoked. This action is defined in the Cap capacity.

behavior MyBehavior {
    uses Cap
    on SomeEvent {
        // Run the action of the skill
        action
    }
}

Copyright © 2014-2018 the original authors or authors.

Licensed under the Apache License, Version 2.0; you may not use this file except in compliance with the License. You may obtain a copy of the License.

You are free to reproduce the content of this page on copyleft websites such as Wikipedia.

Generated with the translator io.sarl.maven.docs.generator 0.8.0.