In Teams, a team is a distinct BDI reasoning entity which is characterised by the roles it performs and the roles it requires others to perform. The formation of a given team is achieved by attaching sub-teams (either statically or dynamically) capable of performing the roles required by the team. Note that a sub-team may be attached to more than one role in a containing team. As the sub-teams of the given team may require roles to be performed on their behalf, a multi-level hierarchy (or perhaps a more complex structure) may result. The team is automatically provided with objects to hold the actual sub-team selections. These objects are known as role containers.
Team definitions take the form shown below:
team TeamType extends Team
{
// team declarations and definitions
// all JACK agent declarations can also be used
// constructor
public TeamType(String name)
{
super(name);
}
}
Each component of this definition is explained in the following table:
Syntax Term |
Description |
team |
A Teams Language keyword used to introduce a Team definition. |
TeamType |
The name of your derived Team class |
extends Team |
This part of the statement plays the same role as in Java – it indicates that the role being defined inherits from a Team's base class called Team. The Role base class implements all the underlying methods that provide a team's core functionality. |
Table 2-1: Components of a Team definition
The team type definition has the same range of declarations available as an agent definition. In addition, it has declarations that are specific to the team concept. These are the declarations that relate to roles required, roles performed and belief propagation in the team structure. The team declarations are described in the following sub-sections.
The statement of the form #requires role RoleType reference(min,max) is a declaration that teams of the type being defined require a sub-team or sub-teams in the given role, RoleType.
Technically, the #requires role statement adds a field to the team class of name reference and type RoleTypeContainer. The arguments specify the upper and lower bounds for the number of role performers. A value of zero for max specifies the default upper bound. A zero upper bound is an unlimited upper bound. A zero for the minimum value specifies a zero lower bound.
The RoleTypeContainer type is created automatically by the compiler when there is a role defined of type RoleType.
A #requires role statement:
This statement is a declaration that the team of the type being defined is able to perform a given role, RoleType.
A #performs role statement:
This is a declaration that can be found within a team that is a role tenderer. A role tenderer will have #requires role declarations specifying that it requires sub-teams to perform particular roles on its behalf.
The declaration has the form
#synthesizes teamdata DataType ref(r1.s1, r2.s2, ...)
where
Note that one or more belief connection sources are required. Belief propagation is described further in the chapter on Team Belief Connections.
This is a declaration that can be found within a team that is a role performer. A role performer will have #performs role declaration(s) specifying that it can perform a particular role on behalf of a role tenderer.
The declaration has the form
#inherits teamdata DataType ref(r1.s1, r2.s2, ...)
where
Note that one or more belief connection sources are required. Belief propagation is described further in the chapter on Team Belief Connections.
The base class Team has a constructor taking a String argument that represents the name of the team to be constructed. A team definition must thus include a constructor that invokes the base class (Team) constructor with the team name provided. As part of the construction, the kernel posts a TeamFormationEvent for establishing the team structure (also known as the role obligation structure), and a TeamStartEvent to trigger application level initialisation.
The TeamFormationEvent extends MessageEvent, but uses BDI behaviour with the following BDI behaviour attributes set:
Behaviour Attribute |
Setting |
Effect |
Recover |
repost |
The event is reposted on plan failure, so that another applicable plan can be tried. If no new applicable plan is found, then event processing fails. |
ApplicableSet |
once |
The applicable set is computed only once, rather than being recomputed after each plan failure. On event failure, the next applicable plan is selected from the set computed initially for the event. |
ApplicableChoice |
first |
The plan instance generated by the #uses plan declaration that occurs first in the body of the agent or capability is chosen. |
ApplicableExclusion |
failed |
Plans that have failed are excluded from the applicable plan set. |
PlanBindings |
single |
One applicable plan of each relevant plan type is added to the applicable plan set. |
Table 2-2: The BDI behaviour attributes for the TeamFormationEvent
There is a default plan for the TeamFormationEvent. This plan uses the default team manager, described in the next section.
The team manager is responsible for coordinating the assembly of the team structure. This can be done using team initialisation files, or in the code.
The team structure can be specified by using a Java property to point to a file that contains details of the teams required. The most straightforward way of doing this is by associating a file to be read in with the Team.Structure property via the -D flag. This flag is used when running your application with Java.
An example of the use of this flag follows:
java -DTeam.Structure=filename ApplicationClass
The team initialisation file is specified using the JACOB Object Modelling Language. The format of a team initialisation file is as follows.
<Team :name "TeamName"
:roles (
<Role :type "RoleType" :name "roleinstance_ref"
:fillers (
<Team :name "TeamName">
)
>
)
>
The following table details the meaning of each of the syntactical elements in the team initialisation file:
Entity |
Label |
Code Entity Mapping |
Team |
:name |
Class name of the Team. |
:roles |
An aggregation of role bindings. |
|
Role |
:type |
Class name of the role. |
:name |
A reference to the role instance as it appears in code. |
|
:fillers |
A section that specifies the fillers of the role. This can be a reference to a team that is specified later in the file or the team can be fully specified inline. |
Table 2-3: The syntactical elements in the team initialisation file
Note: In the above example, the TeamName for the fillers is mentioned. This format requires that the TeamName be fully specified in another separate Team entry in the team initialisation file.
Alternatively you can specify the entire team structure inline.
This allows the entire team structure to be specified as one monolithic Team entry, or as a number of distinct team/role relationships.
The initialisation file can specify a structure that is a superset of those team entities that you declare in code. This allows the provision of a central, predetermined and precise structure for the team. Using this method, the team structure can be better planned and changes can be made quickly and easily in the one location.
Relationships described in the initialisation file as part of role and team relationships must be legal according to the existing #requires role, #performs role and Class (Team and Role) declarations in code.
Note:
It is possible to write custom team formation plans to allow any part of a team structure to be constructed dynamically at runtime. This is a powerful technique which allows, for example, dynamic specification of team structure at the top level while the lower level structure is handled by the team initialisation file.
To specify that a manually formed team is preferred, add a plan to the team's plan set to handle the TeamFormationEvent. The default plan has a rank of zero, so adding any plan with the standard plan rank (5) will cause this default to be overridden.
The plan to handle the team formation event is then responsible for specifying the structure of roles as they relate to the current team. Specification of team structure involves attaching teams to roles and roles to teams. This can be achieved by posting a RoleControl event with its assign(String role, String container, String actor) posting method. To detach teams the RoleControl event is posted with its revoke() posting method. This is discussed in more detail in the chapter on Team Formation.
If the plan that processes the TeamFormationEvent succeeds, a StartTeamEvent is posted by the kernel. Its purpose is to enable team-specific initialisations.
The default plan handling StartTeamEvent succeeds without doing anything.
This plan could be overridden to start an application. Any plan that reacts to a StartTeamEvent will do as the default plan has a plan rank of zero. Any new plan you write with a default rank of 5 will therefore be executed in preference to the default plan.
StartTeamEvent extends Event, but uses BDI behaviour with the following non default BDI behaviour attributes:
Behaviour Attribute |
Setting |
Effect |
ApplicableSet |
once |
The applicable set is computed only once, rather than being recomputed after each plan failure. On event failure, the next applicable plan is selected from the set computed initially for the event. |
ApplicableChoice |
first |
The first plan instance generated by the #uses plan declaration that occurs first in the body of the agent or capability is chosen. |
PlanBindings |
single |
Only one applicable plan of each relevant plan type is added to the applicable plan set. |
Table 2-4: The BDI behaviour attributes for the StartTeamEvent
The Team class is used as the base class for teams. It provides the implementations for the team 'lifetime' and includes the core team capabilities. The following methods are available within a team:
void canPerformRole(String role, boolean yes)
//
// A support method whereby a team marks whether it actually can
// perform a role. See also RoleContainer.active.
//
RoleContainer findContainer(String role,String cntr)
//
// Looks up the role container matching a #required role
// declaration.
//
RoleContainer findContainer(String role)
//
// Looks up the role container matching a #performed role
// declaration.
//
Role findPerformedRole(String team,String role,String cntr)
//
// Looks up the role object that for a performer represents the
// activated obligation of performing the given role for the named
// team, and that team's container.
//
Role findRequiredRole(String team,String role,String cntr)
//
// Looks up the role object that for a role tenderer represents the
// activated role obligation of a team performing the given role in
// the given container.
//
RoleInfo [] getRoles()
//
// Gets the RoleInfo table for this team. This contains
// the RoleInfo object corresponding to the #requires role
// statements, and is used by the default team formation procedure.
//
void postWhenFormed(Event e)
//
// This is the same as the postEvent method in an agent,
// but it waits until the team formation stage is
// complete before posting the event.
//
boolean rolesInitialized(RoleInfo[] roles)
//
// A reflection support method that uses the RoleInfo table as
// guide in determining whether required roles have been initialised.
//
Team(String n)
//
// The base class constructor. All team instances need to be assigned
// unique names at construction. The team will be registered with the
// communication system under that name, and other agents/teams can
// thus send messages to this team using that name.
//