% Delivery Robot in Prolog % Declare nature's choices. choice(giveCoffee(P),C) :- C = giveCoffeeS(P) ; C = giveCoffeeF(P). choice(go(L),C) :- C = endUpAt(L) ; C = getLost(L). choice(puMail,C) :- C = puMail. choice(giveMail(P),C) :- C = giveMail(P). % Action precondition and successor state axioms. 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(endUpAt(L),S) :- not L = blackHole, loc(L1,S), not L1 = blackHole, not L1 = L. poss(getLost(L),S) :- not L = blackHole, loc(L1,S), not L1 = blackHole, not L1 = L. mailPresent(P,do(A,S)) :- not A = puMail, mailPresent(P,S). coffeeRequested(P,do(A,S)) :- coffeeRequested(P,S), not A = giveCoffeeS(P). carryingMail(P,do(A,S)) :- A = puMail, mailPresent(P,S) ; carryingMail(P,S), not A = giveMail(P). 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). % 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(endUpAt(L),go(L),S,Pr) :- loc(L0,S), dist(L0,L,D), Pr is 1000 / (1000 + D). prob0(getLost(L),go(L),S,Pr) :- loc(L0,S), dist(L0,L,D), Pr is D / (1000 + D). % Initial database. 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)).