% An Elevator Controller with Randomly Generated Exogenous Actions. % Primitive action declarations primitive_action(goUp). primitive_action(goDown). primitive_action(resetButton(N)). primitive_action(toggleFan). primitive_action(ringAlarm). primitive_action(wait). primitive_action(startFire). primitive_action(endFire). primitive_action(callElevator(N)). primitive_action(resetAlarm). primitive_action(changeTemp). % GOLOG Procedures proc(control, wait : while(some(n,buttonOn(n)), pi(n, ?(buttonOn(n)) : serveFloor(n)))). proc(serveFloor(N), while(-atFloor(N), if(aboveFloor(N), goDown, goUp)) : resetButton(N)). proc(rules, ?(fire & -alarmOn) : ringAlarm : while(alarmOn,wait) # ?(fire & alarmOn) # ?(tooHot & -fan) : toggleFan # ?(tooCold & fan) : toggleFan # ?(-(fire v tooHot & -fan v tooCold & fan))). requestExogenousAction(E,S) :- randomNumber(R), exoAction(E,I1,I2), I1 =< R, R =< I2, poss(E,S),!, nl, write("Generating exogenous action: "), write(E). requestExogenousAction(nil,S) :- nl, write("No exogenous action."). /* Generate a random number in the interval [0,R], where R has been declared to be the range for random numbers. */ randomNumber(Y) :- frandom(X), % System predicate for random real in [0,1]. randomRange(R), Y is X * R. randomRange(200). exoAction(changeTemp,0,10). exoAction(startFire,16,20). exoAction(endFire,23,27). exoAction(resetAlarm,42,48). exoAction(callElevator(1),116,120). exoAction(callElevator(2),123,127). exoAction(callElevator(3),130,134). exoAction(callElevator(4),137,141). exoAction(callElevator(5),144,148). exoAction(callElevator(6),151,154). % Preconditions for Primitive Actions poss(goUp,S) :- atFloor(N,S), topFloor(T), N < T. poss(goDown,S) :- atFloor(N,S), firstFloor(F), F < N. poss(resetButton(N),S) :- atFloor(N,S), buttonOn(N,S). poss(toggleFan,S). poss(ringAlarm,S) :- fire(S). poss(startFire,S) :- not fire(S). poss(endFire,S) :- fire(S). poss(callElevator(N),S) :- not buttonOn(N,S). poss(changeTemp,S). poss(resetAlarm,S) :- alarmOn(S). poss(wait,S). % Successor State Axioms for Primitive Fluents. buttonOn(N,do(A,S)) :- A = callElevator(N) ; (buttonOn(N,S), not A = resetButton(N)). fire(do(A,S)) :- A = startFire ; (not A = endFire, fire(S)). fan(do(A,S)) :- (A = toggleFan, not fan(S)) ; (not A = toggleFan, fan(S)). atFloor(N,do(A,S)) :- (A = goDown, atFloor(M,S), N is M - 1) ; (A = goUp, atFloor(M,S), N is M + 1) ; (not A = goDown, not A = goUp, atFloor(N,S)). alarmOn(do(A,S)) :- A = ringAlarm ; (not A = resetAlarm, alarmOn(S)). temp(T,do(A,S)) :- (A = changeTemp, temp(T1,S), ((not fan(S), T is T1 + 1) ; (fan(S), T is T1 - 1))) ; (not A = changeTemp, temp(T,S)). % Abbreviations. tooHot(S) :- temp(T,S), T > 3. tooCold(S) :- temp(T,S), T < -3. aboveFloor(N,S) :- atFloor(M,S), N < M. % Initial Situation. atFloor(1,s0). temp(0,s0). topFloor(6). firstFloor(1). % Restore suppressed situation arguments. restoreSitArg(buttonOn(N),S,buttonOn(N,S)). restoreSitArg(fire,S,fire(S)). restoreSitArg(fan,S,fan(S)). restoreSitArg(tooHot,S,tooHot(S)). restoreSitArg(tooCold,S,tooCold(S)). restoreSitArg(aboveFloor(N),S,aboveFloor(N,S)). restoreSitArg(alarmOn,S,alarmOn(S)). restoreSitArg(atFloor(N),S,atFloor(N,S)). restoreSitArg(temp(T),S,temp(T,S)). restoreSitArg(requestExogenousAction(E),S,requestExogenousAction(E,S)). elevator :- doR(control,rules,s0,S), prettyPrintSituation(S). prettyPrintSituation(S) :- makeActionList(S,Alist), nl, write(Alist), nl. makeActionList(s0,[]). makeActionList(do(A,S),L) :- makeActionList(S,L1), append(L1,[A],L). exoTransition(S1,S2) :- requestExogenousAction(E,S1), (E = nil, S2 = S1 ; not E = nil, S2 = do(E,S1)).