Example 01 – Artifact definition, creation and use

This example shows the basics about artifact creation and use, including observation. Two agents create, use and observe a shared artifact.

MAS example01_useobs {


  user user agentArchClass c4jason.CAgentArch #1;
  observer observer agentArchClass c4jason.CAgentArch #1;

  classpath: "../../../lib/cartago.jar";"../../../lib/c4jason.jar";

The user agent creates a c0 artifact of type c4jexamples.Counter and then uses it twice, executing the inc action (operation) two times:


+!create_and_use : true
  <- !setupTool(Id);
     inc [artifact_id(Id)].

+!setupTool(C): true
  <- makeArtifact("c0","c4jexamples.Counter",[],C).


  • Artifact creation: To create the artifact, the agent exploits the makeArtifact action, provided by the workspace artifact. An empty list of parameters is specified, and the artifact id is retrieved, bound to the C variable.
  • Operation invocation with no target artifact specified: operation invocation -i.e. action execution – can be done either specifying or not which is the specific target artifact providing the operation. No artifact is specified in the first inc: the artifact is automatically selected from the workspace. If there are no artifacts providing such action, the action fails. If more than one artifact is found, first artifacts created by the agent itself are considered. If more than one artifact is found, one is selected non deterministically. Then, the rest of the artifacts are considered, and one is selected non deterministically.
  • Operation invocation with the target artifact specified: The second time the inc is executed, the target artifact is specified. This can be done by adding the annotation [artifact_id(Id)], where Id must be bound to the artifact identifier. Alternatively, the annotation [artifact_name(Name)] can be used, where Name must be bound to the logic name of the artifact.
  • Operation invocation with the target workspace specified: As a further variant, the workspace identifier can be specified, instead of the target artifact, by means of the wsp_id annotation. Ex: inc [wsp_id(WspID)].

The Counter artifact is characterised by a single inc operation and a count observable property, updated by the operation. The operation also generates a tick signal.

package c4jexamples;

import cartago.*;

public class Counter extends Artifact {

  void init(){

  @OPERATION void inc(){
    ObsProperty prop = getObsProperty("count");


  • Artifact definition:: an artifact template can be implemented by defining a class – whose name corresponds to the artifact template name – extending the Artifact base class.
  • Artifact initialization: the init method in artifact classes represents artifact constructor, useful to initialize the artifact as soon as it is created. The actual parameter of the init method – in this case there are no parameters – can be specified when executing the makeArtifact action.
  • Operations: Operations are implemented by methods annotated with @OPERATION and with void return parameter. Methods parameter corresponds to operations parameters.
  • Observable properties: New observable properties can be defined by the defineObsProp primitive. In their most general form, an observable properties is represented by a tuple, with a functor and one or multiple arguments, of any type. In this case the count property has a single argument value, of integer type. To retrieve the reference to an observable property the getObsProperty primitive is provided, specifying the property name. Then updateValue methods can be used to change the value of the property.
  • Signals: like observable properties, also signals can be tuple structures, with a functor and one or multiple arguments, of any type. In this case the tick signal generated by the operation has no argument. The primitive signal is provided to generate signals. It comes in two flavours:
    • signal(String signalName, Object... params) : generates a signal which is perceivable by all the agents that are observing the artifact (because they did a focus).
    • signal(AgentId id, String signalName, Object... params): generates a signal which is perceivable only by the specified agent. The agent must be observing the artifact, anyway.
  • Atomicity and transactionality: Operations are executed transactionally with respect to the observable state of the artifact. So no interferences can occur when multiple agents concurrently use an artifact, since the operations are executed atomically. Changes to the observable properties of an artifact are made observable only when:
    • the operation completes, successfully
    • a signal is generated
    • the operation is suspended (by means of an await, described in next examples)

    If an operation fails, changes to the observable state of the artifact are rolled back.

Finally, an observer agent observes the counter and prints on standard output a message each time it perceives
a change in count observable property or a tick signal:


+!observe : true
  <- ?myTool(C);  // discover the tool

  <- println("observed new value: ",V).

+tick [artifact_name(Id,"c0")]
  <- println("perceived a tick").

+?myTool(CounterId): true
  <- lookupArtifact("c0",CounterId).

-?myTool(CounterId): true
  <- .wait(10);


  • Artifact lookup: agents can discover the identifier of an artifact by means of the lookupArtifact action provided by the workspace artifact, specifying either the logic name of the artifact to discover or its type (in this last case, if multiple artifacts are found, one is chosen non deterministically). In the example, if the observer agent executes a lookupArtifact before the artifact has been created (by the other agent), then the lookupArtifact fails and the repairing plan -?myTool(...) is executed. Variants:
  • Focus action: agents can select which parts (artifacts) of the environment to observe by means of the focus action, provided by the workspace artifact, specifying the identifier of the artifact to focus.
    • focus(ArtifactId id, IEventFilter filter) specifies a filter to select the percepts to receive.
    • focusWhenAvailable(String artName) focuses the specified artifact as soon as it is available in the workspace.
  • Observable properties – Beliefs mapping by focussing an artifact, artifact observable properties are mapped
    into the agent’s belief base. So changes to the observable properties are detected as changes to the belief base. In the example: +count(V) triggering event. Beliefs related to observable properties are decorated with annotations that can be used to select the relevant/applicable plan, in particular:

    • source(percept), percept_type(obs_prop): define the percept type
    • artifact_id(Id), artifact_name(id,name), artifact_type(id,type),
      workspace(id,wspname): provide information about the source artifact and workspace. It is important to remark that, being beliefs, the value of observable properties can be accessed by means of test goals (e.g. ?count(X), when specifying context conditions, and so on).
    • Percept mixing: due to the belief base model adopted in Jason, beliefs (and so observable properties) with the same functor and argument are collapsed together, mixing the annotations.
  • Signals percept: by focussing an artifact, signals generated by an artifact are detected as changes in the belief base – in the example: +tick – even if in this case the belief base is not changed. As in the case of observable properties, annotations that can be used to select the relevant/applicable plan, in particular:
    • source(ArtifactId), percept_type(obs_ev) – define the percept type
    • artifact_id(Id)), artifact_name(id,name), artifact_type(id,type), workspace(id,wspname) – provide information about the source artifact and workspace.

Leave a Reply

Your email address will not be published. Required fields are marked *


You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>