!
vs !!
The order of execution (parallel, sequential) of sub-plans, triggered inside their parent plan differs depending on the trigger symbol !
or !!
:
!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.
!!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
).
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 theX <= 5
branch, which will result in the plan to fail. This is intended to show different execution behaviour.
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.)
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).
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