When defining an operation, a guard can be specified as a condition that must be verified to start operation execution, otherwise such execution is suspended. This can be done by including a guard attribute in the @OPERATION annotation, specifying the name of the boolean method (guard method) - annotated with @GUARD, representing the condition to be tested. Guard methods are called passing the same parameters of the guarded operation (so they must declare the same parameters). Typically guard methods do checks on the value of internal and observable state of the artifact, without changing it. Operations with guards are useful to realise artifacts with synchronisation functionalities. In the following example, guards are used to implement a bounded buffer artifact in a producers-consumers architecture.

MAS example04_prodcons {

    environment:
    c4jason.CartagoEnvironment

    agents:
    producer agentArchClass c4jason.CAgentArch #10;
    consumer agentArchClass c4jason.CAgentArch #10;

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

Ten producers agents and ten consumers agents exchange information items by exploiting the bounded buffer. Guarded operations allow for realising a simple coordinated behaviour, such that consumers' get action is suspended if the buffer is empty, and producers' put action is suspended if the buffer is full. Bounded buffer code:

public class BoundedBuffer extends Artifact {

  private LinkedList

Producers code:

item_to_produce(0).

!produce.

+!produce: true <-
  !setupTools(Buffer);
  !produceItems.

+!produceItems : true <-
  ?nextItemToProduce(Item);
  put(Item);
  !!produceItems.

+?nextItemToProduce(N) : true
 <- -item_to_produce(N);
    +item_to_produce(N+1).

+!setupTools(Buffer) : true <-
  makeArtifact("myBuffer","c4jexamples.BoundedBuffer",[10],Buffer).

-!setupTools(Buffer) : true <-
  lookupArtifact("myBuffer",Buffer).

Consumers code:

!consume.

+!consume: true
  <- ?bufferReady;
     !consumeItems.

+!consumeItems: true
  <- get(Item);
     !consumeItem(Item);
     !!consumeItems.

+!consumeItem(Item) : true
  <- .my_name(Me);
     println(Me,": ",Item).

+?bufferReady : true
  <- lookupArtifact("myBuffer",_).
-?bufferReady : true
  <-.wait(50);
     ?bufferReady.

Highlights: