Tutorial: Trigger

This tutorial explains the functionality of agent triggering. For understanding the purpose of triggers you have to understand the concept of events, which is a well-known concept in UI programming.

Contents [Hide]

Previous Knowledge

The AgentSpeak 15min tutorial defines the basic knowledge and working scenario.

What are triggers?

A short definition of triggers in LightJason’s agent concept: a trigger is

an event written in a first-order logical literal

On the other hand, the agent is

an event listener which executes a plan if an event is released

What kinds of triggers do exist?

An agent is a logical program which defines some knowledge elements e.g. beliefbase and the beliefs, so there are different kinds of triggers to distinguish the elements:

  • add goal (+!) tells the agent try to reach the goal which is named by the trigger
  • delete goal (-!) tells the agent that something is going wrong, the delete goal is executed iif a plan failed
  • add belief (+) is created if a belief is pushed into the beliefbase
  • delete belief (-) is created if a belief is removed from the beliefbase

How can I use them?

From a global viewpoint, a trigger is created based on a semantic definition, so there is no defined type for calling a certain trigger in a situation. It depends on your conceptional view of your multi-agent system and your individual execution model.

The usage is very simple, the agent class supports a trigger-method, so create your trigger and call this method.

Java Implementation

A trigger is a combination of a literal and a trigger type. Both elements are defined as classes CTrigger and ITrigger.EType. The code shows the usage of a add goal trigger which defines with the first argument at line 71 the type of the trigger and with the second argument at line 73-75 the literal.


package myagentproject;
import org.lightjason.agentspeak.language.CLiteral;
import org.lightjason.agentspeak.language.CRawTerm;
import org.lightjason.agentspeak.language.instantiable.plan.trigger.CTrigger;
import org.lightjason.agentspeak.language.instantiable.plan.trigger.ITrigger;
import java.io.FileInputStream;
import java.util.Collections;
import java.util.Set;
import java.util.logging.LogManager;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
final class App
{
    static
    {
        
        LogManager.getLogManager().reset();
    }
    
    private App()
    {
    }
    
    public static void main( final String[] p_args )
    {
        if ( p_args.length < 2 )
            throw new RuntimeException( "arguments are not set: ASL script, number of agents" );
        
        
        
        
        final Set<MyAgent> l_agents;
        try
            (
                final FileInputStream l_stream = new FileInputStream( p_args[0] );
            )
        {
            
            l_agents = Collections.unmodifiableSet(
                new MyAgentGenerator( l_stream )
                    .generatemultiple( Integer.parseInt( p_args[1] ) )
                    .collect( Collectors.toSet() )
            );
        }
        catch ( final Exception l_exception )
        {
            l_exception.printStackTrace();
            return;
        }
        
        IntStream
            .range(
                0,
                p_args.length < 3
                ? Integer.MAX_VALUE
                : Integer.parseInt( p_args[2] )
            )
            .forEach( j -> l_agents.parallelStream()
                                   .forEach( i ->
                                   {
                                       try
                                       {
                                           i.call();
                                           
                                           
                                           if ( Math.random() < 0.5 )
                                               i.trigger(
                                                   CTrigger.from(
                                                       
                                                       ITrigger.EType.ADDGOAL,
                                                       
                                                       CLiteral.from(
                                                           "special-goal",
                                                           CRawTerm.from( 100 * Math.random() )
                                                       )
                                                   )
                                               );
                                       }
                                       catch ( final Exception l_exception )
                                       {
                                           l_exception.printStackTrace();
                                       }
                                   } ) );
    }
}

AgentSpeak Implementation

The agent (in detail the ASL script) can handle the trigger iif a plan (an instantiated goal) exists which matches the literal. For this example the agents need only to define a plan which matches the literal (line 11) and executes a print message (line 12)


!main.
+!main <-
    generic/print("Hello World on agent", MyName);
    !mynextgoal
.
+!mynextgoal <-
    generic/print( "Hello World again on agent", MyName );
    !mynextgoal
.
+!special-goal(X) <-
    generic/print( "special goal with value", X, "triggered on agent", MyName )
.

Notes

The trigger-method allows you to control the agent from Java-side, so that your system can execute any plans inside the agent. You can push the trigger at any time to the agent and the agent will execute the trigger as soon as possible, except you tell the agent that the trigger should be executed immediately (see the second argument of the method documentation). The agent can sleep, so in that case the trigger will be discarded.

Reference Solution

The reference solution is based on the agentspeak-in-15min tutorial; we extended this tutorial with trigger behaviour. If you struggled at some point or wish to obtain our exemplary solution with code documentation of this tutorial, you can download the archive containing the source code and an executable jar file:

We run the program two times with 3 agents and 4 cycles and get the following output, first run

Hello World on agent   980.697.799
Hello World on agent   595.995.566
Hello World on agent   1.142.993.467
Hello World again on agent   595.995.566
Hello World again on agent   980.697.799
special goal with value   2.2248289532471044   triggered on agent   980.697.799
Hello World again on agent   1.142.993.467
special goal with value   76.80922753529944   triggered on agent   1.142.993.467
Hello World again on agent   980.697.799
Hello World again on agent   595.995.566
special goal with value   37.108561892490954   triggered on agent   595.995.566
Hello World again on agent   1.142.993.467
Hello World again on agent   980.697.799
special goal with value   2.0871955837920453   triggered on agent   980.697.799
Hello World again on agent   595.995.566
special goal with value   98.1913332685896   triggered on agent   595.995.566
Hello World again on agent   1.142.993.467

second run

Hello World on agent   212.890.971
Hello World on agent   1.082.569.346
Hello World on agent   1.258.955.623
Hello World again on agent   212.890.971
Hello World again on agent   1.082.569.346
Hello World again on agent   1.258.955.623
special goal with value   92.44063483887761   triggered on agent   1.258.955.623
Hello World again on agent   212.890.971
Hello World again on agent   1.082.569.346
Hello World again on agent   1.258.955.623
Hello World again on agent   212.890.971
Hello World again on agent   1.082.569.346
special goal with value   61.76316960019202   triggered on agent   1.082.569.346
Hello World again on agent   1.258.955.623

Based on the random execution of the trigger the results are different.