Advanced Knowledge: Plan Triggering Techniques

Contents [Hide]

! vs !!

The order of execution (parallel, sequential) of sub-plans, triggered inside their parent plan differs depending on the trigger symbol ! or !!:

  • The trigger !planname marks a plan +!planname to be executed in the next cycle → postponed execution.

Note: Adding !planname multiple times in one cycle will result in +!planname to be executed only once in the next cycle because the same trigger gets only added once.

  • In contrast, !!planname executes the matching plan in this (read: the same) cycle → immediate execution.

Note: As every plan body is executed sequentially, for each given !!planname the plan +!planname will be executed in that sequence.
For advanced users: With the annotation @parallel a plan can be modified to execute all plan-body statements in parallel (see → parallel annotations).

If the plan signature +!planname contains a variable N, e.g. +!planname(N), multiple different instances of triggers will be created (one for each unique N).

Examples

Consider the following AgentSpeak(L++) plan +!largerThan5(N) where N must be larger than 5 for the plan to succeed:

+!largerThan5(X)
  : X > 5 <-
    generic/print(X, "is larger than 5")

  : X <= 5 <-
    generic/print(X, "is NOT larger than 5");
    fail
.

Notice the fail statement in the X <= 5 branch, which will result in the plan to fail. This is intended to show different execution behaviour.

Postponed Execution

For example, having a plan-body containing

!largerThan5(23);
!largerThan5(3)

with different variables, two individual trigger instances will be created and queued for execution in the next cycle. The result will be two plans (one for N = 3 and the second for N = 23) to be run in parallel in the next cycle, yielding

3.0   is NOT larger than 5
23.0   is larger than 5

(The order of output might differ due to concurrency effects.)

Immediate Execution

Whereas, having a plan-body containing

!!largerThan5(23);
!!largerThan5(3)

the two plans will be executed immediately chained in the given order, i.e. +!largerThan5(23)+!largerThan5(3).

Note: If denoted and executed in opposite order

!!largerThan5(3);
!!largerThan5(23)

the output will be just

3.0   is NOT larger than 5

because the plan +!largerThan5(3) fails (as intended).

Further execution in the current plan-context stops, i.e +!largerThan5(23) will not be executed and the parent plan will also fail (see → Failing is Intentional on how to handle failing → actions and sub-plans).

Duplicated Triggers

Adding the same trigger multiple time yields different results depending on delayed execution ! and immediate execution !!.

!largerThan5(23);
!largerThan5(23)

will yield (despite plan parameters resulting in succeeding plans)

23.0   is NOT larger than 5

to be printed only once as previously explained.

This could be avoided by defining one or both plans to be executed in the this cycle, e.g.

!largerThan5(23);
!!largerThan5(23)

will execute the plan triggered in the second row in this cycle, or

!!largerThan5(23);
!!largerThan5(23)

which will execute both plans in this cycle. In both cases the result will be

23.0   is NOT larger than 5
23.0   is NOT larger than 5