CS5940 Model Map ⌂ Modules
Deliberative agentWeek 36 techniques

AgentSpeak(L)

BDI as a real programming language. The agent keeps beliefs, reacts to events by picking a plan from its library, and runs each intention as a stack of half-finished plans. It's Prolog-style matching plus a BDI loop.

Kind: deliberative agent (BDI language).
Week: 3 (slides 15 to 25, appendix A slides 47 to 52).
Book: not in Wooldridge (only its ancestor PRS, 4.4). The slides are the source.
Techniques on this page: the agent’s state, beliefs, goals and events, writing plans, finding the applicable unifier, selection functions, tracing the execution cycle.

The problem it solves

The BDI control loop is an algorithm on paper. To actually build BDI agents you need a language. PRS (1987) was one of the first working BDI systems, but its “language” was just its implementation: nothing small and precise to reason about or teach. AgentSpeak(L) (Rao 1996) distils PRS into a language with a small syntax and a precise meaning.

Like PRS, it doesn’t plan from scratch: it picks plans from a library the programmer wrote. That makes it fast and predictable, at the cost of only handling situations someone wrote a plan for.

Words you’ll hear

Word or symbol Plain meaning
belief a fact like location(robot, kitchen)
!b achievement goal: “make \(b\) true” (usually triggers a plan)
?b test goal: “is \(b\) true?” (a query that can fill in variables)
+p, -p events: belief \(p\) was added / removed (external)
+!p event: a goal \(p\) was posted by a running plan (internal)
plan trigger : context <- body.
relevant the plan’s trigger matches the event
applicable relevant and its context holds given the beliefs
substitution \(\theta\), \(\sigma\) which value each variable gets, e.g. \(\{R/rock145\}\)
intention a stack of partly executed plans
Jason the standard AgentSpeak interpreter

Technique 1: the agent’s state

Problem it solves: knowing what’s inside an AgentSpeak agent.

Component Contents
belief base \(B\) ground facts, like Agent0’s beliefs
event store \(E\) pending events to react to
intentions \(I\) plans currently running (each a stack)
plan library \(P\) the agent’s plans
primitive actions what it can do directly

There are no separate desires: goals appear inside plans and as events.

Technique 2: beliefs, goals and events

Problem it solves: the vocabulary every trace uses.

  • Goals: ?b tests whether \(b\) follows from beliefs (and binds variables). !b asks to bring about a world where \(b\) is believed; it posts an internal event that triggers a plan.
  • Events: +p / -p come from perception or messages: external. +!p comes from a running intention \(i\) meeting !p: internal, stored as \((+!p, i)\), “achieve \(p\) as part of intention \(i\)”.
  • Intention: a stack \([r_k, \dots, r_1]\). \(r_1\) started it; the top \(r_k\) is running now; each plan was pushed to achieve a subgoal of the one below.

Technique 3: writing plans

Problem it solves: the program itself.

triggering_event : context <- body.
     e           : b1 & ... & bm <- h1; ...; hk.
  • the trigger says which events the plan is relevant to;
  • the context is belief conditions that must hold for it to be applicable;
  • the body is actions, ! goals and ? goals, in order.
+!quench_thirst : have_glass <-
        !have_soft_drink;
        fill_glass;
        drink.

+!have_soft_drink : soft_drink_in_fridge <-
        open_fridge;
        get_soft_drink.

+rock_seen(R) : not battery(low) <-
        ?location(R, L);
        !move_to(L);
        pick_up(R).

Technique 4: the applicable unifier

Problem it solves: decides whether a plan can handle an event, and fills in its variables.

A plan e' : b1 & ... & bm <- body is applicable to event \(e\) if

  1. the trigger unifies with the event: \(e\theta = e'\theta\), and
  2. the context follows from current beliefs under some further \(\sigma\).

\(\theta\sigma\) is the applicable unifier. It’s Prolog: match the head, then solve the body against the beliefs.

Worked example (slide 25). Plan: +rock_seen(R) : not battery(low) & location(R, L) <- !move_to(L); pick_up(R). The robot perceives +rock_seen(rock145), believes location(rock145, (3,5,1)), and doesn’t believe battery(low).

  1. Unify the trigger: \(\theta = \{R/rock145\}\).
  2. Context: not battery(low) holds (not in \(B\): negation as failure). location(rock145, L) matches, giving \(\sigma = \{L/(3,5,1)\}\).
  3. Body: !move_to((3,5,1)); pick_up(rock145).

If the robot believed battery(low), step 2 fails: the plan is still relevant but not applicable.

Worked example: an order. Plan +order(Item, Qty) : stock(Item, S) & price(Item, P) <- !reserve(Item, Qty); bill(P). Beliefs stock(tea, 40), price(tea, 3), price(coffee, 5).

  • Event +order(tea, 2): \(\theta = \{Item/tea, Qty/2\}\), \(\sigma = \{S/40, P/3\}\), body !reserve(tea, 2); bill(3).
  • Event +order(coffee, 1): relevant, but stock(coffee, S) can’t be proved, so not applicable.

Technique 5: selection functions

Problem it solves: when several things could happen next, who decides?

  • \(S_E\) picks the event to handle;
  • \(S_O\) picks the option: which applicable plan;
  • \(S_I\) picks which intention to run a step of.

These are not written in AgentSpeak. Usual defaults (Jason’s): \(S_E\) oldest event first, \(S_O\) first applicable plan in the order written, \(S_I\) round-robin. So the order of your plans matters, as in Prolog.

Discussion (slide 23): is “precise syntax, unprogrammable semantics” progress? The most important choice, which plan to run, sits outside the language. A fair position: the opacity has been narrowed and relocated, not removed. Everything else now has a precise meaning, and the three functions can be fixed and documented.

Technique 6: tracing the execution cycle

Problem it solves: the long exam question: list the actions and the intention stack step by step.

Each cycle:

  1. perceive, update \(B\); each change becomes a +b or -b event;
  2. \(e := S_E(E)\);
  3. pick an applicable plan with \(S_O\);
  4. if \(e\) is internal (from intention \(i\)), push the plan on top of \(i\); otherwise start a new intention;
  5. \(i := S_I(I)\); look at the first step of \(i\)’s top plan: an action runs; !b posts \((+!b, i)\) and \(i\) waits; ?b binds variables if it follows from beliefs, otherwise “???”;
  6. if the top plan’s body is empty, pop it; if the intention is empty, remove it.

Worked example: quench thirst. Beliefs \(\{have\_glass, soft\_drink\_in\_fridge\}\); event +!quench_thirst.

Step Event → plan Intention (top on the right) Action
1 +!quench_thirst → plan 1 [P1: !have_soft_drink; fill_glass; drink] none: posts +!have_soft_drink
2 +!have_soft_drink → plan 2, pushed [P1: fill_glass; drink, P2: open_fridge; get_soft_drink] open_fridge
3 none [P1: fill_glass; drink, P2: get_soft_drink] get_soft_drink, P2 popped
4 none [P1: drink] fill_glass
5 none [] → removed drink

Actions: open_fridge, get_soft_drink, fill_glass, drink; the stack reaches depth 2. With no drink in the fridge, step 2 finds no applicable plan and the intention fails before any action.

Worked example: the cleaning robot (appendix A). Rooms a - b - c - d; robot at a, bin at d, it perceives +location(waste, c).

The waste plan posts !location(robot, c); a recursive plan moves one room at a time (move(a,b), move(b,c)) until the base case holds; then pickup(waste); then !bin(waste) gives move(c,d) and drop(waste).

Actions: move(a,b), move(b,c), pickup(waste), move(c,d), drop(waste). The deepest stack is 4 plans. Events like +location(robot, b) have no relevant plan (robot doesn’t unify with waste), so they’re discarded.

Slide 51’s “???”. The slides deliberately leave a failed test goal open. In Jason, the plan fails and a goal-deletion event -!g is generated, which a failure plan can handle; otherwise the intention is dropped. A subgoal with no applicable plan fails the same way.

Jason (slide 52) is AgentSpeak’s practical implementation: it adds strong negation, plan-failure handling, speech-act communication, organisations (Moise) and distribution (JADE). You don’t need its details for the exam.

What to read in the book

Source Read? Why
AgentSpeak(L) Not in the book Slides 15 to 25 and appendix A are the source
4.4 The Procedural Reasoning System, pp. 79 to 82 Read PRS, which AgentSpeak was distilled from. Short
Rao (1996); Bordini, Hübner and Wooldridge (2007), Programming Multi-Agent Systems in AgentSpeak using Jason Optional The original paper and the standard textbook

Page numbers are the book’s; in the scanned PDF add 21.

Practice prompt

I'm studying CS5940 Intelligent Agents (Rao's AgentSpeak(L) and the Jason interpreter; Wooldridge 4.4 on PRS). I want practice on AGENTSPEAK(L):
- the agent's state (beliefs, events, intentions as stacks, plan library) and why there are no separate desires
- test goals ?b vs achievement goals !b; external events (+p, -p) vs internal events (+!p)
- reading and writing plans "trigger : context <- body."
- relevant vs applicable plans, and computing theta, sigma and the instantiated body for a given event and belief base (including negation as failure in contexts)
- the selection functions S_E, S_O, S_I, their usual defaults, and why plan order matters
- tracing the execution cycle step by step: which plan is chosen, how the intention stack grows and shrinks, which actions run
- what happens when a test goal or subgoal fails

Please:
1. Use plain, everyday language and explain any notation in one short sentence.
2. Give me ONE question at a time, easy first, then harder; give the plan library and beliefs in full.
3. Wait for my answer, then mark it and show the full trace with the intention stack at each step.
4. If I get it wrong, explain the mistake and give me a similar question.
5. Every 5 questions, summarise my strengths and what to practise.