1. Understanding an ASTRA agent
An ASTRA agent has beliefs about its situation, goals it tries to achieve and plans describing how it responds to events. A belief says what the agent currently takes to be true. A goal asks it to bring about a result. A plan connects an event to the steps the agent should take.
These concepts are related, but they are separate parts of the program. The belief light("on") records a state; the goal !light("on") asks for that state. Writing the goal does not automatically change the belief or establish that the light is on.
Read a complete program
Create src/main/astra/LightModel.astra in your Quick Start project:
agent LightModel {
module Console console;
module System system;
types lighting {
formula light(string);
}
initial light("off");
plan +!main(list args) {
!light("on");
query(light(string State));
console.println("light = " + State);
system.exit();
}
plan +!light(string Target) : light(Target) { }
plan +!light(string Target) : light(string Current) {
-light(Current);
+light(Target);
}
}
Run mvn clean compile astra:run -Dastra.main=LightModel. The agent prints light = on with its agent-name prefix, then exits. system.exit() ends the whole application; it is appropriate for this finite demonstration.
The file name matches the agent class name. The module declarations give the agent access to console and runtime actions. The types block declares the shape of its beliefs. initial supplies its starting knowledge. +!main(list args) handles the startup goal posted by the runner.
When the main plan adopts !light("on"), ASTRA selects a plan whose event matches and whose context holds. The first light plan covers a goal already satisfied. Otherwise, the second plan replaces the current light belief. The calling plan resumes after the subgoal completes.
This is a mental model: changing a belief changes the agent’s knowledge, not a physical device. Chapter 5 introduces an action that changes a simulated device and observations that report its state.
Follow the reasoning cycle
Conceptually, the interpreter receives observations and events, selects applicable plans and advances active intentions. An intention is an execution of a plan together with its subgoals. Several intentions may be in progress, and their statements can interleave.
A normal subgoal, !g(...), runs within its caller’s intention. A separately adopted goal, !!g(...), creates another intention; the caller continues without waiting for its result. Use the latter when the work is independent, not when the next statement depends on its completion.
A belief addition can trigger a plan such as plan +light(string State). It is a reaction to an observation or update, rather than an explicit subgoal call. Later chapters use these reactions to connect observed changes to goals.
Keep the model small
Give each predicate a clear meaning. Here the single light has one current state. In a system with several lights, use light(string Device, string State) so that their states cannot be confused. Avoid adding unrelated beliefs merely because they are convenient temporary variables; local variables belong inside plans.