Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 6

Chapter 3

Exercise 3.5.1

The robot used in Example 3.4 has plans (identified by h1-h3)


triggered when the agent has a goal that
unifies has(owner,beer) despite the source of the goal (self or
delegated). Change these plans to be triggered only if the source of
the goal is the owner agent.
The first thing to do is to make the plans h1-h3 to be relevant
only for events with source(owner) annotation:

@h1
+!has(owner,beer)[source(owner)]
:available(beer,fridge)&nottoo_much(beer)
<....
@h2
+!has(owner,beer)[source(owner)]
:notavailable(beer,fridge)
<...
@h3
+!has(owner,beer)[source(owner)]
:too_much(beer)&limit(beer,L)
<...

However, the robot itself adds a has(owner,beer) goal instance, in


the plan @a1, this plan needs to be changed as follows (or
alternatively, the plans above change to allow
both owner or self as source):

@a1
+delivered(beer,Qtd,OrderId)[source(supermarket)]
<+available(beer,fridge);
!has(owner,beer)[source(owner)].

Exercise 3.5.2

Improve the code of the Supermarket agent of the example so that


it manages its stock. It initially has, for instance, 100 bottles of beer
and this value will decrease as it delivers beers to the robot. Of
course, it can only deliver beer when it has enough beer in stock,
otherwise it should inform the robot that it has no more beer in
stock.
The complete new code for the supermarket is as follows:

last_order_id(1).//initialbelief
stock(beer,100).//initialstockofbeer
//plantoachievethegoal"order"foragentAg
+!order(Product,Qtd)[source(Ag)]
:stock(Product,S)&S>=Qtd
<?last_order_id(N);
OrderId=N+1;
+last_order_id(OrderId);
+stock(Product,SQtd);
.print("newstockof",Product,"is",SQtd);
deliver(Product,Qtd);
.send(Ag,tell,delivered(Product,Qtd,OrderId)).
+!order(Product,Qtd)[source(Ag)]
<.print("outofstockof",Product);
.send(Ag,tell,not_available(Product)).

Exercise 3.5.3

The robot asks the supermarket for more beer only when the fridge
is empty (see +stock plans). Modify the robot code so that its
behaviour is more pro-active and it asks for more beers before they
finish. Note that: (i) it is not the case of simply changing 0 to 1 in
plan @a2, because even with only 1 beer remains in the fridge,
there is still beer available, so the belief about beer being available
should not be removed; (ii) plan @h2 can be removed from the
code because the robot is now pro-active and there will always be
beer available; (iii) when some beer is delivered (see plan @a1),
the robot does not need the achieve the goal has(owner,beer)anymore.

We consider here that the belief available(beer,fridge) is not


necessary anymore, so all related code is commented out.
The complete new code for the robot is:

/*Initialbeliefs*/
//initially,Ibelievethatthereissomebeerinthefridge
//available(beer,fridge).
//myownershouldnotconsumemorethan10beersaday:)
limit(beer,10).
/*Rules*/
too_much(B):
.date(YY,MM,DD)&
.count(consumed(YY,MM,DD,_,_,_,B),QtdB)&
limit(B,Limit)&
QtdB>Limit.
/*Plans*/
@h1
+!has(owner,beer)[source(owner)]
://available(beer,fridge)&
nottoo_much(beer)
<!at(robot,fridge);
open(fridge);
get(beer);
close(fridge);
!at(robot,owner);
hand_in(beer);
//rememberthatanotherbeerhasbeenconsumed
.date(YY,MM,DD);.time(HH,NN,SS);
+consumed(YY,MM,DD,HH,NN,SS,beer).
//@h2
//+!has(owner,beer)[source(owner)]
//:notavailable(beer,fridge)
//<.send(supermarket,achieve,order(beer,5));
//!at(robot,fridge).//gotofridgeandwaitthere.
@h3
+!has(owner,beer)[source(owner)]
:too_much(beer)&limit(beer,L)

<.concat("TheDepartmentofHealthdoesnotallowme",
"togiveyoumorethan",L,
"beersaday!Iamverysorryaboutthat!",M);
.send(owner,tell,msg(M)).
@m1
+!at(robot,P):at(robot,P)<true.
@m2
+!at(robot,P):notat(robot,P)
<move_towards(P);
!at(robot,P).
//whenthesupermarketmakesadelivery,trythe'has'
//goalagain
//@a1
//+delivered(beer,Qtd,OrderId)[source(supermarket)]:true
//<+available(beer,fridge);
//!has(owner,beer)[source(owner)].
//whenthefridgeisopened,thebeerstockisperceived
//andthustheavailablebeliefisupdated
//@a2
//+stock(beer,0)
//:available(beer,fridge)
//<available(beer,fridge).
/*newplantoproactivelyaskformorebeer*/
+stock(beer,1)
<.send(supermarket,achieve,order(beer,5)).
//@a3
//+stock(beer,N)
//:N>0&notavailable(beer,fridge)
//<+available(beer,fridge).

Exercise 3.5.4

In the robot code, we have two plans for the goal


if we change their order (@m2 before @m1)?

!at.

What happens

Nothing changes since the context of the plans are mutually


exclusive.
What happens if the second plan does not have a context, as in the
following code?

@m1+!at(robot,P):at(robot,P)<true.
@m2+!at(robot,P):true
<move_towards(P);
!at(robot,P).
Is the behaviour of the robot the same as with the original code?
Yes, whenever the agent arrives to the destination the first
plan is selected and that stops the recursion (triggered by
@m2).
In this case, what happens if we change the order of the plans?
However, if we change the order in this case (where @m2 has
no context) @m2 will be always selected and the recursion will
never end.
Exercise 3.5.5

Create a new supermarket agent, initially with the same code as the
supermarket of the example. Change the code of both supermarkets
so that, once they have started, they send the following message to
the robot, informing their price for beer.
.send(robot,tell,price(beer,3))
The robot should then buy beer from the cheapest supermarket. To
help coding the robot, write a (Prolog-like) rule that finds the
cheapest supermarket according to the robot's belief base. Note
that the robot will always have two beliefs of price from different
sources (the two supermarkets).
The new project file that creates two supermarkets is as
follows:

MASdomestic_robot{

environment:HouseEnv(gui)
agents:robot;
owner;
supermarketagentArchClassSupermarketArch#2;
}

Changes in the code of supermarket:

!send_price(beer).//initialgoaltosendthepriceofbeertothe
robot
+!send_price(P)//plantosendtheprice;usesmath.randomto
announce
//differentpricesforeachagent
<.send(robot,tell,price(P,5+math.random(10))).

The new rule for the robot:

cheapest(Product,Seller):
//basedonbeliefprice/2,createsalistofoffers,
//eachelementofthelistis"offer(Price,Sender)"
.findall(offer(Price,S),price(Product,Price)[source(S)],ListOffers)
&
.print("Offers:",ListOffers)&
//use.mintoselectthefirstelementofanorderedlistofoffers
.min(ListOffers,offer(_,Seller)).

The new version of the plan that asks form more beer:

+stock(beer,1)
:cheapest(beer,S)
<.print("Buyingbeerfrom",S);

.send(S,achieve,order(beer,5)).

You might also like