The V-World Workbook

Donald Nute
Artificial Intelligence Center
The University of Georgia
Athens, GA 30605
donald@nute.ws

Copyright 2005 Donald Nute

<Previous> <Workbook Home Page> <Next>


Exercise 3: Bumble 1.1

Bumble 1.0 (the agent defined in bumble_1.0.agt) does not modify its behavior in response to changes in its Strength or Damage. We will begin by introducing states that our agent may be in and that affect his behavior. He should act differently when he is hungry or hurt. You will modify Bumble so that he becomes hungry when his Strength drops below 1000, and he ceases to be hungry when his Strength goes above 3000. And you will modify Bumble so that he is hurt when his Damage goes above 50, and he ceases to be hurt when his Damage drops back to 0.

Look at the first line of code in bumble_1.0.agt, that is, the first line in the file after the comments that begin with %. It says

:- dynamic [agent/2,tried/0,last/1,pushed/0].

This line tells WIN-PROLOG that these predicates are dynamic, that is, that clauses for these predicates can be added to the program, deleted from the program, or examined during program execution using the built-in Prolog predicate clause/2. (The V-World program operates by using clause/2 to look at the definition of agent/2 in an agent file. The other predicates in this list are used by Bumble to keep track of what it did last.) Change this line to read

:- dynamic [agent/2,tried/0,last/1,pushed/0,hungry/0,hurt/0].

Now our agent program can add the clauses hungry. or hurt. to itself as it runs and use the presence or absence of these clauses to help it decide what to do in any situation.

The next few lines of code in Bumble 1.0 are

agent(Perceptions,Action) :-

bumble(Perceptions,Action).

In V-World, an agent is defined as a function from perceptions to actions. Our sample agent computes this function by calling the function bumble/2. We will modify Bumble so that before he decides on what action to take, he first determines what state he is in. Change the definition of agent/2 to

agent(Perceptions,Action) :-

set_bumble_states(Perceptions),

bumble(Perceptions,Action).

Then add the following code immediately below the definition of agent/2.

set_bumble_states([Strength,Damage|_]) :-

is_bumble_hungry(Strength),

is_bumble_hurt(Damage).

You may want to add more conditions to this code later as you find more useful states to use in steering Bumble's behavior, but these will do for now. Notice that Bumble's Perceptions consist of a list of values, and the first two of these are his Strength and his Damage. We only need to use Strength to determine whether Bumble is hungry, and we only need to use Damage to determine whether he is hurt.

Define is_bumble_hungry/1 so Bumble becomes hungry (assert(hungry)) when his Strength drops below 1000, and he ceases to be hungry (retractall(hungry)) when his Strength goes above 3000. When his Strength is between 1000 and 3000, his hunger state should not change. So sometimes he will be hungry and sometimes he won't when his Strength is in this range.

Define is_bumble_hurt/1 so Bumble becomes hurt (assert(hurt)) when his Damage goes above 50, and he ceases to be hurt (retractall(hurt)) when his Damage goes down to 0. When his Damage is between 0 and 50, his hurt state should not change. This will not matter in the risk worlds because the only way Bumble can reduce his Damage in these worlds is to press a red cross, and this drops his Damage all the way to 0. But in other worlds, there may be actions that will reduce Bumble's Damage by some fixed amount without reducing it all the way to 0.

Once you have states established, you can use them to modify Bumble's behavior. If you want him to behave in a certain way if he is hurt, then add the condition hurt to the rule defining that particular behavior; if you want him to act some other way when he is not hurt, then add the condition \+ hurt to that rule. Hint: you can also use conditions like this to define is_bumble_hungry/1 and is_bumble_hurt/1.

Here are the changes in behavior you should build into Bumble 1.1.

1. If Bumble is not hungry, he ignores trees and fruit.
2. If Bumble is hungry and he is beside fruit, he eats it.
3. If Bumble is hungry and he is beside a tree but he is not beside fruit, he presses on the tree.
4. If Bumble is not hurt, he ignores hornets and red crosses.
5. If Bumble is hurt, and he is beside a red cross, he presses it.

Other than these changes, Bumble 1.1 should behave just like Bumble 1.0.

Save your code in a file called <yourname>- bumble_1.1.agt and test it in the worlds test1--test7.

3.1 Is Bumble 1.1 a simple reflex agent? A model-based reflex agent? A goal-based agent? A utility-based agent? A learning agent? Remember that Bumble 1.1 could belong to more than one of these categories. Justify your answers and compare then to the answers you gave for Bumble 1.0. If Bumble 1.0 and Bumble 1.1 belong to the same category, is there any difference in how well each of them represents that category?

3.2 Using the same evaluation criteria you used before, is Bumble 1.1 more or less rational than Bumble 1.0? Explain.

3.3 Can you make any suggestions for changing the way hunger and pain affect Bumble that will tend to extend his "lives"?

Discussion: Bumble 1.1 should perform better than Bumble 1.0in test2 and test3. In fact, Bumble 1.1 should routinely survive 5,000 moves in test2, and at least occasionally survive 5,000 moves in test3. When Bumble 1.1 dies in test3, it will usually be because he was stung to death rather than because he starved. The hornets have a tough time keeping Bumble 1.1 away from food. However, Bumble 1.1 does not perform better than Bumble 1.0 in test4--test7 because both versions have the same problems locating the resources they need to survive.


Last revised 8/17/2005.