The second example program illustrates the use of goals (and in particular, subgoals) in AgentSpeak(L) programs. The program itself is a slightly modified version of the Hello World program that moves the code to print out “Hello World” into a subgoal.
01 !init(). 02 03 +!init() <- 04 !printHello(). 05 06 +!printHello() <- 07 println(hello world).
This program is a slight modification of the previous program where the print action is moved to a separate rule that is used to handle the adoption of the !printHello() goal (lines 06-07). This goal is invoked as a subgoal on line 04 of the program (in the previous program, this line contained the actual print action),
In terms of execution, the following happens: on iteration 1, the agent removes the +!init() goal adoption event from the event queue and matches it to the first rule (lines 03-04), causing an intention to be created. This intention is then selected by the agent and the first step is executed. This step is a subgoal plan operator, which has the effect of creating a +!printHello() goal adoption event. Because it is a subgoal, the intention is also suspended (this means that the intention cannot be selected for execution). The goal adoption event also includes a reference to this intention, indicating that the event corresponds to a subgoal. On iteration 2, the agent removes the +!printHello() goal adoption event from the event queue and matches it to the second rule (lines 06-07). Because the event was generate by a subgoal plan operator, the agent appends the plan part of the rule to the intention from which the subgoal was invoked, and resumes that intention. The result of this is that the agent has a single intention that combines the first and the second rules. This is achieved by making an intention a stack. Each element of the stack contains a plan body and a program counter to indicate what step of that plan body is next. In this example, after the second event is handled, the intention contains 2 elements: an entry that represents the body of the !init() rule (lines 03-04) with a program counter indicating that the first step has been completed; a second entry then represents the body of the !printHello() rule (lines 06-07) indicating that no steps have been completed. The second entry is at the top of the stack. This intention is then selected by the agent, and the next step is executed.In this case, the agent peeks at the top of the stack and executes the first rule of the second entry (which calls the print action). On the 3rd iteration, the agent has no new events to process, so it simply selects the intention and executes the next step. When it peeks at the top entry in the intention, it notes that the entry is completed, so it removes that entry and then peeks at the new top entry. Again, the agent notices that this entry is also complete, so it removes the second entry, leaving the stack empty. This indicates to the agent that the intention has been completed, so it is dropped.