This document describes how to define Capacities in SARL. Before reading this document, we recommend that you read the General Syntax Reference.
An Action is code (a public method or function) that transforms a part of the designed system or its environment. This transformation guarantees resulting properties if the system before the transformation satisfies a set of constraints. An Action is defined in terms of pre- and post-conditions.
A Capacity is the specification of a collection of Actions. This specification makes no assumptions about the implementation of each Action. It is used to specify what an Agent can do, what behavior is required for its execution.
A Skill is a collections of Actions implementing a Capacity as described in this specification.
An Agent can dynamically evolve by acquiring (learning) new Capacities, and it can also dynamically change the Skill associated with a given Capacity. Acquiring a new Capacity enables an Agent to get access to new behaviors. This provides Agents with a self-adaptation mechanism that allows them to dynamically change their architecture according to their current needs and goals.
A Capacity is the specification of a collection of Actions. Consequently, only Action signatures can be defined inside a Capacity: no attribute or field is allowed, and no body (code) for the Action may be present.
The definition of a Capacity is done with the capacity
keyword. Below, a Capacity that permits logging messages
is defined. This Capacity enables an Agent to log information and debugging messages.
Note Defining a Capacity without Actions is a symptom of a design problem.
capacity Logging {
// Log an information message
def info(text : String)
// Log a debugging message
def debug(text : String)
}
In some situations, it is useful to specialize the definition of a Capacity. Capacity specialization is supported by the inheritance feature of SARL, which has the same semantics as the inheritance mechanism of the Java object-oriented language.
The extended Capacity is specified just after the extends
keyword.
Very Important Note A Capacity type can extend zero-to-many other Capacity types. This is similar to the implementation of interfaces in the Java language.
In the following code, the Logging
Capacity (defined above) is extended to enabling the output of error messages.
capacity ErrorLogging extends Logging {
// Log a error message
def error(text : String)
}
In some situations, it is useful to define a Capacity by extending more than one Capacity.
Below, the Cap3
Capacity is defined as an extension of the Capacities Cap1
and Cap2
.
capacity Cap1 {
def action1
}
capacity Cap2 {
def action2
}
capacity Cap3 extends Cap1, Cap2 {
def action3
}
Modifiers are used to modify declarations of types and type members. This section introduces the modifiers for Capacity. The modifiers are usually written before the keyword defining the Capacity.
The complete description of the modifier semantics is available in this section.
A Capacity may be declared with one or more modifiers, which affect its runtime behavior:
public
: the Capacity is accessible from any other type (default);package
: the Capacity is accessible only from types in the same package.Examples:
public capacity Example1 {
}
package capacity Example2 {
}
The modifiers for the Actions (methods) in a Capacity are:
public
: the Action is accessible from any type.Example:
// Public access function
public def example1
Several Capacities are defined and reserved by the SARL Core Specification. They compose the minimal set of Capacities that a runtime environment must support to run a SARL program.
Very Important Note You must not define a Capacity with a fully qualified name equals to one of the reserved Capacities.
The built-in Capacities are defined in the Built-in Capacity Reference.
The use of a Capacity is related to the associated Skills. A Capacity cannot be called by itself since it does not provide an implementation: this is the role of the Skill.
When a function fct
of the Capacity C
is called, it means that the Agent silently does:
S
associated to C
; andfct
on the object S
.Details on the use of the Capacities may be found in the following:
As described within the previous section, when a capacity’s function is invoked, the function’s implementation is retreived from the skill that was associated to the capacity.
The standard way for associating a capacity and a skill is to call the setSkill
function within an agent or a behavior, as
detailed in the agent’s documentation.
Nevertheless, let the case in which we would like to bind a capacity to a default skill.
In other words, we would like to specify that a skill should be associated by default to a capacity if the setSkill
function
is not invoked.
The way to realize this it is to the @DefaultSkill
.
This annotation may be attached to a capacity’s declaration in order to specify the skill that should be binded by default to
the capacity.
In the following example, the MyCapacity
capacity and the MySkill
skill are declared.
The [:defaultskillannon] annotation specifies that an instance of MySkill
should be binded to the
MyCapacity
capacity if the developer does not change the binding programmatically.
Examples:
@DefaultSkill(typeof(MySkill))
capacity MyCapacity {
def myfunction
}
skill MySkill implements MyCapacity {
def myfunction {
}
}
Copyright © 2014-2024 SARL.io, the Original Authors and Main Authors.
Documentation text and medias are licensed under the Creative Common CC-BY-SA-4.0; you may not use this file except in compliance with CC-BY-SA-4.0. You may obtain a copy of CC-BY-4.0.
Examples of SARL code are licensed under the Apache License, Version 2.0; you may not use this file except in compliance with the Apache License. You may obtain a copy of the Apache License.
You are free to reproduce the content of this page on copyleft websites such as Wikipedia.
Generated with the translator docs.generator 0.14.0.