! 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
!plannamemultiple times in one cycle will result in+!plannameto 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
!!plannamethe plan+!plannamewill be executed in that sequence.
For advanced users: With the annotation@parallela 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
failstatement in theX <= 5branch, 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