% Clauses for the Delivery Robot with Exogenous Events % Action preconditions. poss(puMail,S) :- loc(mr,S), mailPresent(P,S). poss(giveMail(P),S) :- carryingMail(P,S), loc(office(P),S). poss(giveCoffeeS(P),S) :- coffeeRequested(P,S), loc(office(P),S). poss(giveCoffeeF(P),S) :- coffeeRequested(P,S), loc(office(P),S). poss(go(L),S) :- not going(L1,S), not L = blackHole, loc(L1,S), not L1 = blackHole, not L1 = L. poss(endUpAt(L),S) :- going(L,S). poss(getLost(L),S) :- going(L,S). poss(exo(M,C,Sm),S) :- findall(P,person(P),Ps), findall(P,(member(P,Ps), not coffeeRequested(P,S)),Cs), findall([M,C,Sm], P^Prm^Prc^Prob^ (subset(M,Ps), % Filter out those sets of mail arrivals with very small probabilies. exoProbMailArrives(M,S,Prm), Prm > 0.0001, subset(C,Cs), % Filter out those sets of mail arrivals and coffee requests with % very small combined probabilities. exoProbRequestCoffee(C,S,Prc), Prob is Prm * Prc, Prob > 0.0001, (Sm = stealMail, once(carryingMail(P,S)) ; Sm = noStealMail)), Args), member([M,C,Sm],Args). % Successor State Axioms going(L,do(A,S)) :- A = go(L) ; going(L,S), not A = endUpAt(L), not A = getLost(L). mailPresent(P,do(A,S)) :- A = exo(M,_,_), member(P,M) ; not A = puMail, mailPresent(P,S). coffeeRequested(P,do(A,S)) :- A = exo(_,C,_), member(P,C) ; coffeeRequested(P,S), not A = giveCoffeeS(P). carryingMail(P,do(A,S)) :- A = puMail, mailPresent(P,S) ; carryingMail(P,S), not A = giveMail(P), not A = exo(_,_,stealMail). loc(L,do(A,S)) :- A = endUpAt(L) ; A = getLost(L1), L = blackHole ; loc(blackHole,S), L = blackHole ; loc(L,S), not L = blackHole, not A = getLost(L1), not (A = endUpAt(L1), not L = L1). choice(giveCoffee(P),C) :- C = giveCoffeeS(P) ; C = giveCoffeeF(P). choice(go(L),C) :- C = go(L). choice(puMail,C) :- C = puMail. choice(giveMail(P),C) :- C = giveMail(P). % Probabilities. prob0(giveCoffeeS(P),giveCoffee(P),S,Pr) :- Pr = 0.95 . prob0(giveCoffeeF(P),giveCoffee(P),S,Pr) :- Pr = 0.05 . prob0(giveMail(P),giveMail(P),S,Pr) :- Pr = 1.0 . prob0(puMail,puMail,S,Pr) :- Pr = 1.0 . prob0(go(L),go(L),S,Pr) :- Pr = 1.0 . exoProb(endUpAt(L),S,Pr) :- loc(L0,S), dist(L0,L,D), Pr is 1000 / (1000 + D). exoProb(getLost(L),S,Pr) :- loc(L0,S), dist(L0,L,D), Pr is D / (1000 + D). exoProb(exo(M,C,SM),S,Pr) :- exoProbMailArrives(M,S,PM), exoProbRequestCoffee(C,S,PC), exoProbMailStolen(SM,S,PS), Pr is PM * PC * PS. exoProbMailStolen(SM,S,Pr) :- carryingMail(P,S), going(L,S), loc(L0,S), dist(L0,L,D), (SM = stealMail, Pr is D / (5000 + D) ; SM = noStealMail, Pr is 5000 / (5000 + D)) ; not (carryingMail(P,S), going(L,S)), (SM = stealMail, Pr is 0.0 ; SM = noStealMail, Pr is 1.0). exoProbMailArrives(M,S,Pr) :- % First compute the probability, Pr1, that mail arrives for % all people in M. findall(Prob, P^(member(P,M), probMailArrives(P,S,Prob)), ProbList1), multiplyNumbers(ProbList1,Pr1), % Next, compute the probability, Pr2, that mail doesn't % arrive for those people not in M. findall(P,person(P),Ps), findall(Prob, P^ProbM^(member(P,Ps), not member(P,M), probMailArrives(P,S,ProbM), Prob is 1 - ProbM), ProbList2), multiplyNumbers(ProbList2,Pr2), Pr is Pr1 * Pr2. probMailArrives(P,S,Pr) :- Pr = 0.005 . exoProbRequestCoffee(C,S,Pr) :- % First compute the probability, Pr1, that all people % in C issue a request for coffee. findall(Prob, P^(member(P,C), probRequestsCoffee(P,S,Prob)), ProbList1), multiplyNumbers(ProbList1,Pr1), % Next, compute the probability, Pr2, that those people % not in C do not request coffee. findall(P,person(P),Ps), findall(Prob, P^ProbC^(member(P,Ps), not member(P,C), probRequestsCoffee(P,S,ProbC), Prob is 1 - ProbC), ProbList2), multiplyNumbers(ProbList2,Pr2), Pr is Pr1 * Pr2. probRequestsCoffee(P,S,Pr) :- coffeeRequested(P,S), Pr = 0.0 ; not coffeeRequested(P,S), Pr = 0.01 . multiplyNumbers([],1.0). multiplyNumbers([P | Ps],Prod) :- multiplyNumbers(Ps,Pr), Prod is P * Pr. % Initial situation. person(P) :- P = pat ; P = sue ; P = alf ; P = sam ; P = ann ; P = bob. loc(mr,s0). carryingMail(P,s0) :- P = pat ; P = sue ; P = alf. coffeeRequested(P,s0) :- P = sue ; P = alf. % The offices are strung out along a single line. mr is on the left. % office(pat) is to its immediate right at a distance of 10. office(sue) is % to the immediate right of office(pat) at a distance of 10. Etc. distances([mr,10,office(pat),10,office(sue),10,office(ann),10, office(bob),10,office(sam),10,office(alf)]). dist(X,Y,D) :- distances(A), (dist0(X,Y,A,D), ! ; dist0(Y,X,A,D)). dist0(X,X,A,0). dist0(X,Y,A,D) :- tail([X,DX | [Z | L]],A), dist0(Z,Y,[Z | L],DR), D is DX + DR. tail(L,L). tail(L,[X | Xs]) :- tail(L,Xs). restoreSitArg(coffeeRequested(P),S,coffeeRequested(P,S)). restoreSitArg(mailPresent(P),S,mailPresent(P,S)). restoreSitArg(loc(L),S,loc(L,S)). restoreSitArg(carryingMail(P),S,carryingMail(P,S)). restoreSitArg(going(L),S,going(L,S)). primitive_action(endUpAt(_)). primitive_action(getLost(_)). primitive_action(exo(_,_,_)). proc(exoProgram, ?(-some(l,going(l))) # pi(l,?(going(l)) : pi(m, pi(c, pi(sm, exo(m,c,sm)))) : (endUpAt(l) # getLost(l)))).