FEATHERWEIGHT AGENT LANGUAGE
A Core Calculus for Agents and Artifacts
Ferruccio Damiani
Dipartimento di Informatica, Universit`a degli Studi di Torino, Corso Svizzera 185, 10149 Torino, Italy
Paola Giannini
Dipartimento di Informatica, Universit`a del Piemonte Orientale, Via Bellini 25/G, 15100 Alessandria, Italy
Alessandro Ricci, Mirko Viroli
DEIS, Universit`a di Bologna, Via Venezia 52, 47023 Cesena, Italy
Keywords: Multi-agent systems, Concurrency, Core calculi, Type systems.
Abstract:
The widespread diffusion and availability of multicore architectures is going to make more and more aspects
of concurrency and distribution to be part of mainstream programming and software engineering. The SIMPA
framework is a recently proposed library-based extension of JAVA that introduces on top of the OO layer a
new abstraction layer based on agent-oriented concepts. A SIMPA program is organized in terms of dynamic
set of autonomous pro-active task-oriented entities – the agents – that cooperate by exploiting some artifacts,
that represents resources and tools that are dynamically constructed, shared and co-used by agents. In this
paper we promote the applicability of the agent and artifact metamodel in OO programming a step further.
Namely, we propose a core calculus that integrates techniques coming from concurrency theory and from OO
programming languages to provide a first basic formal framework for designing agent-oriented languages and
studying properties of agent-oriented programs.
1 INTRODUCTION
Multi-core architectures, Internet-based computing
and Service-Oriented Architectures/Web Services,
are increasingly introducing concurrency issues (and
distribution) in the context of a large class of appli-
cations and systems—up to making them key factors
of almost any complex software system. As noted in
(Sutter and Larus, 2005), even though concurrency
has been studied for about 30 years in the context
of computer science fields such as programming lan-
guages and software engineering, this research has
not significantly impacted on mainstream software
development. However, it appears more and more im-
portant to introduce higher-level abstractions, which
can “help build concurrent programs, just as object-
oriented abstractions help build large component-
based programs” (Sutter and Larus, 2005).
The A&A (Agents and Artifacts) meta-model, re-
cently introduced in the context of agent-oriented
programming and software engineering as a novel
foundational approach for modelling and engineer-
ing complex software systems (Omicini et al., 2009),
goes in this direction. Agents and artifacts are the ba-
sic high-level and coarse-grained abstractions avail-
able in A&A: agents are used to model (pro)-active
and task-oriented components of a system, which
encapsulate the logic and control of their execu-
tion, while artifacts model purely-reactive function-
oriented components of a system, used by agents to
support their (invidual and collective) activities.
In (Ricci and Viroli, 2007) it is introduced SIMPA,
a library-based extension of JAVA providing program-
mers with agent-oriented abstractions on top of the
basic OO layer, to be used as basic building blocks to
define the architecture of complex (concurrent) appli-
cations. In SIMPA, the underlying OO computational
model of JAVA is still adopted, but only for defining
agents and artifacts programming and data storage,
namely, for defining the purely computational part of
218
Damiani F., Giannini P., Ricci A. and Viroli M. (2009).
FEATHERWEIGHT AGENT LANGUAGE - A Core Calculus for Agents and Artifacts.
In Proceedings of the 4th International Conference on Software and Data Technologies, pages 218-225
DOI: 10.5220/0002257102180225
Copyright
c
SciTePress
applications. On the other hand, agents and artifacts
are used to define aspects related to system architec-
ture, interaction, and synchronisation.
In this paper we promote the applicability of
A&A metamodel in OO programming a step fur-
ther, by introducing FAL (FEATHERWEIGHT AGENT
LANGUAGE), a core calculus formalizing the key fea-
tures of SIMPA. The formalization is largely inspired
to FJ, (FEATHERWEIGHT JAVA) (Igarashi et al.,
2001), and is based on reduction rules applied at cer-
tain evaluation contexts. On the other hand, being
concurrency-oriented, this calculus uses techniques
coming from concurrency theory, as e.g. in process
algebras. A system configuration is seen as a parallel
composition of agents and artifacts instances (seen as
independent and asynchronous processes), the former
keeping track of a tree of (sub-)activities to be exe-
cuted in autonomy, the latter holding a set of pending
operations to be executed in response to agent actions
over the artifact.
Organisation of the Paper. Section 2 introduces the
SIMPA programming model. Section 3 presents syn-
tax, and operational semantics of the FAL calculus.
Section 4 briefly discusses the properties that result
from type soundness. Section 5 discusses some re-
lated work and Section 6 concludes by outlining pos-
sible directions for further work.
2 THE PROGRAMMING MODEL
In this section we describe an abstract version of
SIMPA programming model by exploiting the syntax
of the FAL calculus.
The Agent Programming Model. In essence, an
agent in SIMPA is a stateful entity whose job is to
pro-actively execute a structured set of activities as
specified by the agent programmer, including possi-
bly non-terminating activities, which finally result in
executing sequences of actions, either internal actions
inspecting/changing its own state or external ac-
tions interacting with its environment. All actions
are executed atomically.
The state of an agent is represented by an associa-
tive store, called memo-space, which represents the
long-term memory where the agent can dynamically
attach, associatively read and retrieve chunks of in-
formation called memo. A memo is a tuple, charac-
terised by a label and an ordered set of arguments,
either bound or not to some data object (if some is not
bound, the memo is hence partially specified). For
instance, the philosopher agent uses a memo
hungry
to take note that its state is now hungry and it needs
the forks, and
stopped
to keep track that it needs to
agent Main {
activity main() { Table t = make Table(new boolean[5]);
spawn Philosopher(0,1,t); spawn Philosopher(1,2,t);
spawn Philosopher(2,3,t); spawn Philosopher(3,4,t);
spawn Philosopher(4,0,t); }
}
artifact Table { boolean[] isBusyFork;
operation getForks(int left, int right)
:guard ((not(.isBusyFork[left]) and (not(.isBusyFork[right])))
{ .isBusyFork[left] = true; .isBusyFork[right] = true;
signal(forks_acquired);
}
operation releaseForks(int left, int right) :guard true
{ .isBusyFork[left] = false; .isBusyFork[right] = false; }
}
agent Philosopher { Sns s;
activity main(int left, int right, Table table)
:agenda ( prepare() :pre true,
living(left,right,table) :pre memo(hungry)
:pers not(memo(stopped)) ) { }
activity prepare() { +memo hungry; }
activity living(int left, int right, Table table)
:agenda ( eating(left,right,table) :pre memo(hungry),
thinking() :pre completed(eating),
shutdown() :pre failed(eating) ) { }
activity thinking() { ... /* think */ +memo hungry; }
activity eating(int left, int right, Table table)
{ use table.getForks(left,right) :sns s
sense s :filter forks_acquired;
... /* eat */
use table.releaseForks(left,right);
-memo(hungry);
}
activity shutdown() { +memo(stopped); }
}
Figure 1: The five dining philosophers problem.
terminate. A basic set of internal actions is available
to agents to work atomically with the memo-space:
+memo
is used to create a new memo with a specific
label and a variable number of arguments,
?memo
and
-memo
to get/remove a memo with the specified label.
The computational behaviour of an agent can be
defined as a hierarchy of activities (corresponding to
the execution of some tasks). Activities can be simple
or structured. A simple activity is composed by just a
flat sequence of actions, as a single control flow, while
structured activities have a non-empty agenda speci-
fying sub-activities, which in turn can be possibly ex-
ecuted in the context of such super-activity—hence
leading to the hierarchical structure of behaviour. At
the language level, simple activities are represented
by
activity
blocks, providing the name of the activ-
ity and parameters. By default each agent has a
main
activity, which can be either simple or structured.
In the dining philosophers example shown in Fig-
ure 1, the
Philosopher
agent has the simple activ-
ities,
prepare
,
eating
,
thinking
, and
shutdown
. A
structured activity has a non-empty agenda, specify-
FEATHERWEIGHT AGENT LANGUAGE - A Core Calculus for Agents and Artifacts
219
ing a set of todos representing sub-activities that must
be executed in the context of the parent activity—also
called super-activity. In the philosophers example,
main
and
living
are structured activities. A todo
contains the name of the sub-activity to be executed, a
precondition overthe inner state of the agent that must
be hold for the specified sub-activity to start, and at-
tributes related to sub-activity execution, such as per-
sistency. Preconditions are expressed as a boolean
expression over a basic set of predefined predicates.
Essentially, the predicates make it possible to specify
conditions on the current state of the activity agenda,
in particular on (i) the state of the sub-activitities (if
they started, completed, or aborted) and on (ii) the
local inner state of the agent, that is the memo space.
For instance, the predicate
memo(M)
is true if the spec-
ified memo
M
is found in the memo space. In the ex-
ample, in the structured activity
living
, sub-activity
eating
is executed as soon as a memo
hungry
is
found in the memo space. When the precondition of
a todo item holds (for an activity in execution list-
ing such todo in the agenda), the todo is removed
from the agenda and an instance of the sub-activity
is created and executed. So, multiple sub-activities
can be executed concurrently and asynchronously, in
the context of the same parent activity. Sub-activities
execution can be then synchronized by properly spec-
ifying preconditions in todos, hence in a declarative
way. If a todo is declared persistent, as soon as the
sub-activity is completed the todo is re-inserted into
the agenda. The persistency attribute can specify also
the condition under which the activity should per-
sist. For instance, the todo item about
living
sub-
activity in philosopher agent is declared persistent un-
til a
stopped
memo is found.
The Artifact Programming Model. An artifact is
composed by three main parts: (i) observable prop-
erties, which are attributes that can be observed by
agents without an explicit agent action towards the
artifact; (ii) a description of the inner non-observable
state, composed by set of state variables analogous to
private instance fields of objects; and (iii) operations,
which embody the computational behaviour of arti-
facts. The
Table
artifact in the philosopher example
in Figure 1 has no observableproperties, an inner state
variable
isBusyFork
, an array of booleans, and two
operations,
getForks
and
releaseForks
, the first
used to acquire two forks and the latter for releasing
forks. Both state variables and observable properties
are declared similarly to instance fields in objects; ob-
servable properties are prefixed by
obsprop
qualifier.
In both cases, a dot notation (e.g.
.isBusyFork
) is
used both for l-valueand r-value, to syntacatically dis-
tinguish them from parameters.
Operations can be defined by method-like blocks
qualified as
operation
, specifying the name and pa-
rameters of the operation and a computational body.
It is worth noting that no return parameter is speci-
fied, since operations in artifacts are not exactly like
methods in objects. For each
operation
, implicitly
an interface control in the usage interface is defined,
with the specified signature. Operations can be either
atomic, executed as a single computational step, or
structured, i.e. composed by multiple atomic opera-
tion steps. For sake of space, in this paper we con-
sider only atomic operations. For each operation a
guard can be specified (
:guard
declaration), repre-
senting the condition that must hold for the related
control in the usage interface to be enabled. For in-
stance, the
getForks
operation in
Table
artifact is
available – i.e. the related control is enabled in the us-
age interface – when the specified forks are not busy.
To be useful, an artifact typically should pro-
vide some level of observability. This is achieved
both by generating observable events through the
signal
primitive, and by defining observable prop-
erties. In the former case, the primitive generates
observable events that can be observed by the agent
using the artifact i.e. by the agent which has ex-
ecuted the operation. An observable event is repre-
sented by a labelled tuple, whose label represents the
kind of the event and the information content. For
instance, in the
Table
artifact
getForks
operation
generates the
forks acquired(Left,Right)
tuple.
Actually, the observableevent
op exec completed
is
automatically generated without explicit
signals
as soon as the execution of an operation is com-
pleted. In the latter case, observable properties are
instance variables qualified as
obsprop
. Any time
the property changes, an observable event of type
prop updated
is fired with the new value of the prop-
erty as a content. The observable events is observed
by all the agents that are focussing (observing) the
artifact (more details in next subsection). An exam-
ple of simple artifact with observable properties is the
Counter
artifact shown in Figure 2: this artifact
working as an observable counter has just a single
observable property named
count
and an
inc
oper-
ation to update this count. Each time the operation
is executed, the observable property and the event
prop update(count,Value)
are automatically gen-
erated.
The Agent-artifact Interaction Model. As already
stated, artifact use and observation are the basic form
of interaction between agents and artifacts. Artifact
use by an agent involves two basic aspects: (i) ex-
ecuting operations on the artifact, and (ii) perceiving
throughagent sensors the observableevents generated
ICSOFT 2009 - 4th International Conference on Software and Data Technologies
220
artifact Counter { obsprop int count;
Counter(int c){ .count = c; }
operation inc() { .count = .count+1; }
}
agent Main {
activity main() {
Counter c = make Counter(0);
spawn Observer(c); spawn User(c); spawn User(c); }
}
agent Observer { Sns s;
activity main(Counter c)
:agenda ( prepare(c),
monitoring(c) :pre completed(prepare)
:pers (not memo(finished)) { }
activity prepare(Counter c) { focus (c,s); }
activity monitoring(Counter c) {
sense s :filter prop_updated;
int value = observe c.count;
... // do something
if (value >= 100 ){ +memo(finished); } }
}
agent User {
activity main(Counter c)
:agenda ( usingCount(c) :pers true ) {}
activity usingCount(Counter c) { use c.inc(); }
}
Figure 2: A simple program with an
Observer
agent con-
tinuously observing a
Counter
Artifact, which is concur-
rently used by two
User
agents.
by the artifact. Conceptually sensors represent a kind
of “perceptual memory” of the agent, used to detect
events coming from the environment, organize them
according to some policy e.g. FIFO and priority-
based – and finally make them available to the agent.
In the abstract language presented here, sensors used
by an agent are declared at the beginning of the
agent
block.
In order to trigger operation execution, the
use
action is provided, specifying the target artifact, the
operation to execute or, more precisely, the usage
interface control to act upon, which activates the op-
eration and optionally, a timeout and the identifier
of the sensor used to collect observable events gener-
ated by the artifact. The action is blocked until either
the action execution succeeds – which means that the
specified interface control has been finally selected
and the related operation has been started or fails,
either because the specified usage interface control is
invalid (for instance it is not part of the usage inter-
face) or the timeout occurred. If the action execution
fails an exception is generated. In the philosopher
example, a
Philosopher
agent (within its
eating
activity) executes a
use
action so as to execute the
getForks
operation, specifying the
s
sensor. On the
artifact side, if the forks are busy the
getForks
usage
interface control is not enabled, and the
use
is sus-
pended. As soon as the forks become available the
operation is executed and the
use
action succeeds.
It is important to note that no control coupling ex-
ists between an agent and an artifact while an oper-
ation is executed. However, operation triggering is
a synchronization point between the agent (user) and
the artifact (used): if the use action is successfully
executed, then this means that the execution of the
operation on the artifact has started.
In order to retrieve events collected by a sensor,
the
sense
primitive is provided. The primitive waits
until either an event is collected by the sensor, match-
ing the pattern optionally specified as a parameter (for
data-driven sensing), or a timeout is reached, option-
ally specified as a further parameter. As result of a
successful execution of a
sense
, the event is removed
from the sensor and a perception related to that event
is returned. In the philosopher example, after exe-
cuting
getForks
the philosopher agent blocks until a
forks acquired
event is perceived on the sensor
s
.
If no perception are sensed for the duration of time
specified, the action generates an exception. Pattern-
matching can be tuned by specifying custom event-
selection filter: the default filter is based on regular-
expression patterns, matched over the event type (a
string).
Besides sensing events generated when explicitly
using an artifact, a support for continuous observa-
tion is provided. If an agent is interested in observ-
ing every event generated by an artifacts includ-
ing those generated as a result of the interaction with
other agents two actions can be used,
focus
and
unfocus
. The former is used to start observing the
artifact, specifying a sensor to be used to collect the
events and optionally the filter to define the set of
events to observe. The latter one is used to stop ob-
serving the artifact. In the example shown in Figure 2,
an
Observer
agent continuously observes a
Counter
artifact, which is used by two
User
agents. After exe-
cuting a
focus
on the artifact in the
prepare
activity,
in the
monitoring
activity the observer prints on a
console artifact the value of the observable property
count
as soon as it changes.
3 THE CORE CALCULUS
The syntax of FAL is summarised in Figure 3 where
we assume a set of basic values, ranged over by the
metavariable c. Types for basic values are ranged over
by the metavariable C. We only assume the basic val-
ues true and false (of type Bool) which are used
as the result of the evaluation of preconditions, persis-
tency predicates and guards. We use the overbar se-
FEATHERWEIGHT AGENT LANGUAGE - A Core Calculus for Agents and Artifacts
221
U ::= G | A | C Agent / artifact / basic value types
T ::= U |
Sns
Types
GD
::=
agent
G {
Sns
¯s;
Act
} Agent (class) definition
Act
::=
activity a
(T x)
:agenda
(
SubAct
) {e;} Activity definition
SubAct
::=
a
(e)
:pers
e
:pre
e Subactivity definition
AD
::=
artifact
A {U f; U p;
Op
} Artifact (class) definition
Op
::=
operation
o(U x)
:guard
e {e;} Operation definition
e ::= x | c Expressions: variable / basic value
|
spawn
G(e) |
make
A(e) agent and artifact instance creation
| e;e sequential composition
| .f | .f = e artifact-field access / update
| .p | .p = e artifact-property access / update
|
signal
(l(e)) event generation
| .s |
use
e.o(e)
:sns
e |
sense
e
:filter
l sensor / operation use / event sensing
|
focus
(e, e) |
unfocus
(e, e) focus / unfocus
|
observe
e.p get property value
|
?memo
(l) |
-memo
(l) |
+memo
(l(e)) memo operations
|
memo
(l) memo predicate
|
started
(
a
) |
completed
(
a
) |
failed
(
a
) activity state predicates
| fail activity error
Figure 3: Syntax.
quence notation according to (Igarashi et al., 2001).
There are minor differences between the syntax of
the calculus and the one of the language used for the
examples. Namely: instead of tuples for memos in
memo-spaces (and event in sensors) we use values;
and specifiers (
:agenda
,
:pers
,
:pre
,
:guard
and
:sns
), that are optional in the language, are manda-
tory in the calculus.
Labels are used as keys for the associative maps
representing the content of sensors and memo-spaces.
The metavariable l range over labels.
The expression fail model failures in activities,
such as the evaluation of
?memo
(l) and
-memo
(l) in
an agent in which the memo-space does not have a
memo with label l. Note that the types of parame-
ters, in artifact operations and the type of fields and
properties may not be sensors so artifacts. Moreover,
the signal expression,
signal
(l(e)), does not spec-
ify a sensor. Therefore, sensors may not be explicitly
manipulated by artifacts.
The language is provided with a standard type
system enforcing the fact that expressions occur in
the right context (artifact or agent), operation used,
and activities mentioned in todo lists are defined, and
only defined fields and properties are accessed/modi-
fied.
Operational Semantics. The operational semantics
is described by means of a set of reduction rules that
transform sets of instances of agents/artifacts/sensors.
Each agent/artifact/sensor instance has a unique
identity, provided by a reference. The metavariable γ
ranges over references to instance of agents, α over
artifacts, σ over sensors. Configurations are non-
empty sets of agent/artifact/sensor instances.
Sensor instances are represented by σ = hlvi
Sns
,
where σ is the instance identifier, and lv is the queue
of association labels/values representing the events
generated (and not yet perceived) on the sensor.
Agent instances are represented by γ = hl v, σ, Ri
G
,
where γ is the agent identifier, G is the type of the
agent, lv is the content of the memo-space, σ is the
sequence of references to the instances of the sensors
that the agent uses to perceive, and R is the state of
the activity,
main
, that was started when the agent was
created. The sensor instances in σ are in one-to-one
correspondence with the sensor variables declared in
the agent and are needed since every agent uses it own
set of sensor instances.
An instance of an activity, R, describes a running ac-
tivity. As explained in Section 2, before evaluating
the body of an activity we have to complete the ex-
ecution of its sub-activities, so we also represent the
state of execution of the sub-activities.
R ::=
a
(
v
)[Sr
1
··· Sr
n
]{e} | failed
a
The name of the activity is
a
, v are the actual pa-
rameters of the current activity instance, Sr
1
··· Sr
n
is
the set of sub-activities running, and e is the state of
evaluation of the body of the activity. (Note that the
evaluation of the body starts only when all the sub-
activities have been fully evaluated.) With failed
a
we say that activity
a
has failed. If the evaluation of a
sub-activity is successful then it is removed from the
ICSOFT 2009 - 4th International Conference on Software and Data Technologies
222
set Sr
1
··· Sr
n
. So when n = 0 starts the evaluation of
the body e.
For a sub-activity, Sr, the process of evaluating its
precondition (we do not consider the persistency
predicate that would be similar), is represented by
the term,
a
(v)hei where e is different from true or
false (it is the state of evaluation of the precondi-
tion) when e = true, the term
a
(v)htruei is replaced
with the initial state of the evaluation of the activity
a
with parameters v. When e = false the evaluation
of the precondition of
a
is rescheduled. Therefore:
Sr ::=
a
(v)hei | R
Artifact instances are represented by α = hf =
v, p = w, σ, O
1
··· O
n
i
A
where α is the artifact identi-
fier, A the type of the artifact, the sequence of pairs
f v associates a value to each the field of A, the se-
quence of pairs p w associates a value to each property
of A, the sequence σ represents the sensors that agents
focusing on A are using, and O
i
, 1 i n, are the op-
erations that are in execution. We consider O
1
··· O
n
a
queue with first element O
n
and last O
1
. (For simplic-
ity, we do not consider steps in this paper, although
we have a full formalization including them.) Arti-
facts are single threaded and (differently from agents
that may have more activity running at the same time)
only the operation O
n
is being evaluated.
A running operation, O, is defined as follows.
O ::= (σ, ohei{e
})
where σ identifies the sensor associated with the op-
eration which was specified by the agent containing
the use that started the operation, and that is used to
collect events generated during the execution of the
operation by signal. If the expression hei is differ-
ent from true or false the operation is evaluating its
guard e. If e = true then the operation is evaluating
its body. If e = false then the operation is removed
from the queue and put at the end of it so that when it
will be rescheduled it will restart evaluating its guard.
Reduction Rules by Examples. The initial configu-
ration for the program in Fig. 1 is:
1
γ
Main
= h
/
0,
/
0,
main
Tablet=make Table(newBool[5]);
spawn Philosopher(0,1,t);
...
spawn Philosopher(4,0,t)
{ }i
Main
The expression
new Bool[5]
reduces to the array
[f,f,f,f,f]
(In the array we use
f
for false
and
t
for true.) Then the expression
make
Table([f,f,f,f,f])
reduces to an artifact reference
α and adds to the configuration the initial artifact in-
stance that follows:
1
The syntax of FAL does not include local variables and
array object values. In this example, we will handle the lo-
cal variable
t
by replacing, after its declaration/inizializa-
tion, all its occurrences with its value.
α = h
.isBF
=
[f,f,f,f,f]
,
/
0,
/
0,
/
0i
Table
After the initialization of the local variable
t
the agent
instance γ
Main
becomes
γ
Main
= h
/
0,
/
0,
main
spawn Philosopher(0,1,
α
);
...
spawn Philosopher(4,0,
α
)
{ }i
Main
The five spawn expressions are evaluated from left
to right. The evaluation of the expressions
spawn
Philosopher(0,1,
α
)
reduces to γ
0
and adds to the
configuration the agent instance
(1) γ
0
= h
/
0, σ
0
,
main
"
prepare()
htruei ,
living(0,1,
α
)
h
memo(hungry)
i
#
{ }i
Phil.
and the sensor instance σ
0
= h
/
0i
Sns
.
Similarly, the reduction of the other spawn expres-
sions generates four agent instances and four sensor
instances producing the configuration:
γ
Main
= h...i σ
0
= h
/
0i ··· σ
4
= h
/
0i α = h...i γ
0
= h...i · ·· γ
4
= h...i
in which the agent γ
Main
is inactive, having finished
the evaluation of its body. The artifact α does not
have any pending operation, and all the agent philoso-
phers may start the execution of the sub-activities of
their main activity (by starting the evaluation of the
preconditions of
prepare
and
living
). Our model-
ing make use of nondeterministic evaluation rules, but
parallel execution could be modeled.
Going back to (1), since the precondition of the run-
time sub-activity
prepare()
of the activity
main
of
the agent γ
0
is true the expression prepare() htruei
is replaced by prepare()[ ]{+memo(hungry)} (whose
evaluation causes the insertion of the label
hungry
into
the memo of γ
0
) and then since the body is fully eval-
uated
prepare
is removed from the sub-activities of
main
, yielding
(2) γ
0
= h
hungry
, σ
0
,
main
living(0,1,
α
)
hmemo(hungry)i
{ }i
Phil.
If instead of evaluating the sub-activity
prepare
we
would have evaluated the precondition of the sub-
activity
living
, the result would have being
γ
0
= h
/
0, σ
0
,
main
prepare()
htruei,
living(0,1,
α
)
hfalsei
{ }i
Phil.
Next time the sub-activity
living
was scheduled for
execution
living(0,1,
α
)
hfalsei would have been
replaced with
living(0,1,
α
)
hmemo(hungry)i.
Continuing from (2) the precondition
memo(hungry)
of
living
evaluates to
true
and the sub-activity
living(0,1,
α
)
htruei is replaced by the correspond-
ing run-time activity resulting in the following:
living(0,1,
α
)
eating(0,1,
α
)
hmemo(hungry)i ,
thinking()
h
completed(eating)
i,
shutdown()
h
failed(eating)
i
{}
The precondition
memo(hungry)
evaluates to
true
and the sub-activity
eating(0,1,
α
)
htruei is replaced
by the corresponding run-time activity resulting in
FEATHERWEIGHT AGENT LANGUAGE - A Core Calculus for Agents and Artifacts
223
the following
(3)
eating(0,1,
α
)[ ]
use
α
.getForks(0,1) :sns
σ
0
;
sense
σ
0
:filter forks acquired
;
/* eat */
use
α
.releaseForks(0,1)
;
-memo(hungry)
(Note that both
completed(eating)
and
failed(eating)
would evaluate to false.) The
evaluation of the body of
eating
can now start by
reducing the expression
use
α
.getForks(0,1) :sns
σ
0
, that schedules the operation
getForks
in the
artifact instance α yielding
α = h
.isBF
=
[f,f,f,f,f]
,
/
0,
/
0, (σ
0
, getForks he
0
i {e
0
})i
Table
where e
0
is
(not(.isBF[0]) and (not(.isBF[1])))
and e
0
is
.isBF[0] = true; .isBF[1] =true; signal(forks acquired)
.
The guard e
0
reduces to
true
. The reduction of e
0
updates the array ι to
[t, t, f, f, f]
and adds the
label
forks acquired
to the queue of events of the
sensor instance σ
0
, yielding σ
0
= h
forks acquired
i
Sns
.
Other agents may schedule operation the artifact
α. For instance, if the agent γ
1
and γ
2
invoke the
operation
getForks
on α, when the evaluation of
getForks
for the agent γ
0
was completed the state of
the artifact would be
α = h
.isBF
=
[t,t,f,f,f]
,
/
0,
/
0,
(σ
2
,
getForks
he
2
i {e
2
}) (σ
1
,
getForks
he
1
i {e
1
})i
Table
So the guard e
1
(
( not(.isBF[1]) and (not(.isBF[2])) )
)
would evaluate to
false
, and the associated operation
would be rescheduled and put at the rear of the queue
yielding the following
α = h
.isBF
=
[t,t,f,f,f]
,
/
0,
/
0,
(σ
1
,
getForks
he
1
i {e
1
}) (σ
2
,
getForks
he
2
i {e
2
})i
Table
so the evaluation of the guard of the
getForks
opera-
tion invoked by γ
2
may start (and will successfully ac-
quire the forks for γ
2
). At the same time, the expres-
sion
sense
σ
0
:filter forks acquired
in (3) could
be evaluated, perceiving the event
forks acquired
and removing it from the sensor instance σ
0
which
becomes σ
0
= h
/
0i
Sns
. The code
/* eat */
may
be executed and, at the end of its execution the ex-
pression
use
α
.releaseForks(0,1)
schedules the op-
eration
releaseForks
on the artifact α and then
-memo(hungry)
removes the label
hungry
from the
memo completing the execution of the sub-activity
eating
. The sub-activity
eating
is discarded and
therefore the predicate
completed(eating)
becomes
true and the sub-activity
thinking
could be executed
resulting in γ
0
to be:
h
/
0, σ
0
,
main
[
living(0,1,
α
)
thinking()[]
{
/* think */ +memo(hungry)
}
shutdown() hfailed(eating)i
{ } ]{ }i
Phil.
(If the evaluation of the predicate
completed(eating)
was done before completion of predicate
eating
the
result would have been
false
, and then its evaluation
rescheduled.) Once the sub-activity
living
completes
its execution, in the example of Fig. 1 it would be
rescheduled (since its persistency condition is
true
).
4 PROPERTIES
We have defined a type system for FAL – not reported
in the paper for lack of space. The soundness of the
type system implies that the execution of well-typed
agents and artifacts does not get stuck. The following
properties of interaction between well-typed agents
and artifacts, which are useful in concurrent program-
ming with SIMPA, hold: (i) there is no
use
action
specifying an operation control that is not part of the
usage interface of the artifact; (ii) there is no
observe
action specifying an observable property that does not
belong to the specified artifact; and (iii) an executing
activity may be blocked only in a
sense
action over
a sensor that does not contain the label specified in
the filter—i.e., the agent explicitly stops only for syn-
chronization purposes. Moreover, a type restriction
on sensors not present in the current type system
may be defined to enforce that there is no
sense
action
indefinitely blocked on sensing event
e
due to the fact
that the corresponding triggered operation was not de-
signed to generate
e
.
5 RELATED WORK
The extension of the OO paradigm toward concur-
rency i.e. object-oriented concurrent programming
(OOCP) has been (and indeed still is) one of the
most important and challenging themes in the OO
research. Accordingly, a quite large amount of the-
oretical results and approaches have been proposed
since the beginning of the 80’s, surveyed by works
such as (Briot et al., 1998; Yonezawa and Tokoro,
1986; Agha et al., 1993; Philippsen, 2000). We re-
fer to (Ricci et al., 2008) for a comparison of the
agent and artifact programmingmodel with active ob-
jects (Lavenderand Schmidt, 1996) and actors (Agha,
1986) and with more recent approachesextending OO
with concurrency abstractions, namely POLYPHONIC
C# (Benton et al., 2004) and JOIN JAVA (Itzstein and
Kearney, 2001) (both based on Join Calculus (Four-
net and Gonthier, 1996)). Another recent proposal
is STATEJ (Damiani et al., 2008), that proposes state
classes, a construct for making the state of a concur-
rent object explicit. The objective of our approach is
quite more extensive in a sense, because we introduce
an abstraction layer which aims at providing an effec-
tive support for tackling not only synchronisation and
ICSOFT 2009 - 4th International Conference on Software and Data Technologies
224
coordination issues, but also the engineering of pas-
sive and active parts of the application, avoiding the
direct use of low-level mechanisms such as threads.
6 CONCLUSIONS
We described FAL, a core calculus to provide a rig-
orous formal framework for designing agent-oriented
languages and studying properties of agent-oriented
programs. To authors knowledge, the only attempt
that has been done so far applying OO formal mod-
elling techniques like core calculi to study properties
of agent-oriented programs and of agent-oriented ex-
tensions of object-oriented systems is (Ricci et al.,
2008). A main limitation of the formalization pro-
posed in (Ricci et al., 2008) is the lack of a type sys-
tem that is able to guarantee well-formedness proper-
ties of programs. In this paper we formalized a larger
set of features (including agent agenda and artifact
properties) and provided a type soundness result.
The type system paves the way towards the anal-
ysis of the computational behaviour of agents. Prop-
erties that we are investigating mainly concerns the
correct execution of activities, in particular: (i) there
is no activity which are never executed because of
their pre-condition; (ii) post-conditions for activity
execution can be statically known, expressed as set of
memos that must be part of the memo space as soon as
the activity has completed; (iii) invariants for activity
execution can be statically known, expressed as set of
memos that must be part of the memo space while the
activity is in execution; (iv) there is no internal action
reading or removing memos that has not been previ-
ously inserted. We are investigating the suitable defi-
nition of pre/post/invariant conditions in terms of sets
of memos that must be present or absent in the memo
space, so that it would be possible to represent high-
level properties related to set of activities, such as the
fact that an activity A would be executed always after
an activity A or that an activity A and A cannot be
executed together. On the artifact side, the computa-
tional model of artifacts ensures a mutually exclusive
access to artifact state by operations executed concur-
rently; more interesting properties could be stated by
considering not only atomic but also structured oper-
ations, not dealt in this paper. We are also planning
of integrating and comparing our approach based on
static analysis with traditional verification techniques
such as model-checking.
REFERENCES
Agha, G. (1986). Actors: a model of concurrent compu-
tation in distributed systems. MIT Press, Cambridge,
MA, USA.
Agha, G., Wegner, P., and Yonezawa, A., editors (1993). Re-
search directions in concurrent object-oriented pro-
gramming. MIT Press, Cambridge, MA, USA.
Benton, N., Cardelli, L., and Fournet, C. (2004). Modern
concurrency abstractions for C#. ACM Trans. Pro-
gram. Lang. Syst., 26(5):769–804.
Briot, J.-P., Guerraoui, R., and Lohr, K.-P. (1998). Con-
currency and distribution in object-oriented program-
ming. ACM Comput. Surv., 30(3):291–329.
Damiani, F., Giachino, E., Giannini, P., and Drossopoulou,
S. (2008). A type safe state abstraction for coordi-
nation in java-like languages. Acta Inf., 45(7-8):479–
536.
Fournet, C. and Gonthier, G. (1996). The reflexive chemical
abstract machine and the join calculus. In POPL’96,
pages 372–385. ACM.
Igarashi, A., Pierce, B., and Wadler, P. (2001). Feather-
weight Java: A minimal core calculus for Java and
GJ. ACM TOPLAS, 23(3):396–450.
Itzstein, G. S. and Kearney, D. (2001). Join Java: an alterna-
tive concurrency semantics for Java. Technical Report
ACRC-01-001, Univ. of South Australia.
Lavender, R. G. and Schmidt, D. C. (1996). Active ob-
ject: an object behavioral pattern for concurrent pro-
gramming. In Pattern languages of program design 2,
pages 483–499. Addison-Wesley Longman Publish-
ing Co., Inc., Boston, MA, USA.
Omicini, A., Ricci, A., and Viroli, M. (2009). Artifacts in
the A&A meta-model for multi-agent systems. Au-
tonomous Agents and Multi-Agent Systems, 19. Spe-
cial Issue on Foundations, Advanced Topics and In-
dustrial Perspectives of Multi-Agent Systems.
Philippsen, M. (2000). A Survey of Concurrent Object-
Oriented Languages. Concurrency Computat.: Pract.
Exper., 12(10):917–980.
Ricci, A. and Viroli, M. (2007). SIMPA: An agent-oriented
approach for prototyping concurrent applications on
top of java. In PPPJ’07, pages 185–194. ACM.
Ricci, A., Viroli, M., and Cimadamore, M. (2008). Proto-
typing concurrent systems with agents and artifacts:
Framework and core calculus. Electron. Notes Theor.
Comput. Sci., 194(4):111–132.
Sutter, H. and Larus, J. (2005). Software and the concur-
rency revolution. ACM Queue: Tomorrow’s Comput-
ing Today, 3(7):54–62.
Yonezawa, A. and Tokoro, M., editors (1986). Object-
oriented concurrent programming. MIT Press, Cam-
bridge, MA, USA.
FEATHERWEIGHT AGENT LANGUAGE - A Core Calculus for Agents and Artifacts
225