;;; This is one of the example programs from the textbook: ;;; ;;; Artificial Intelligence: ;;; Structures and strategies for complex problem solving ;;; ;;; by George F. Luger and William A. Stubblefield ;;; ;;; These programs are copyrighted by Benjamin/Cummings Publishers. ;;; ;;; We offer them for use, free of charge, for educational purposes only. ;;; ;;; Disclaimer: These programs are provided with no warranty whatsoever as to ;;; their correctness, reliability, or any other property. We have written ;;; them for specific educational purposes, and have made no effort ;;; to produce commercial quality computer programs. Please do not expect ;;; more of them then we have intended. ;;; ;;; A version of the thermostat simulation of chapter 15 ;;; designed to run under CLOS. The contents of this file ;;; implement a simple thermostat system, including a few initial ;;; instances (room-325). ;;; ;;; to run it, try compiling this file, and evaluating a call like ;;; ;;; (change-setting room-325 70) ;;; ;;; or ;;; ;;; (change-temp room-325 -5) ;;; ;;; A general thermostat class. (defclass thermostat () ((setting :initform 65 :accessor therm-setting))) ;;; a thermostat designed to control heaters (defclass heater-thermostats (thermostat) ((heater :allocation :class :initarg heater-obj))) ;;; the heater class (defclass heater () ((state :initform 'off :accessor heater-state) (location :initarg loc) (rooms-heated))) ;;; a room class (defclass room () ((temperature :initform 65 :accessor room-temp) (thermostat :initarg therm :accessor room-thermostat) (name :initarg name :accessor room-name))) ;;; the change-temp method simulates the result of changing ;;; the temperature in a room (defmethod change-temp ((place room) temp-change) (let ((new-temp (+ (room-temp place) temp-change))) (setf (room-temp place) new-temp) (terpri) (prin1 "the temperature in ") (prin1 (room-name place)) (prin1 " is now ") (prin1 new-temp) (terpri) (check-temp place))) ;;; The change-setting method simulates the effect of changing ;;; the setting of a thermostat (defmethod change-setting ((room room) new-setting) (let ((therm (room-thermostat room))) (setf (therm-setting therm) new-setting) (prin1 "changing setting of thermostat in ") (prin1 (room-name room)) (prin1 " to ") (prin1 new-setting) (terpri) (check-temp room))) ;;; check-temp examines the temperature of a room. If it ;;; is less than the thermostat setting, it turns the heater ;;; on. Otherwise, it turns the heater off. (defmethod check-temp ((room room)) (let* ((therm (room-thermostat room)) (heater (slot-value therm 'heater))) (cond ((> (therm-setting therm) (room-temp room)) (send-heater heater 'on)) (t (send-heater heater 'off))))) ;;; send-heater simulates a message to turn a heater on or off (defmethod send-heater ((heater heater) new-state) (case new-state (on (if (equal (heater-state heater) 'off) (turn-on heater)) (heat-rooms (slot-value heater 'rooms-heated) 1)) (off (if (equal (heater-state heater) 'on) (turn-off heater))))) (defmethod turn-on ((heater heater)) (setf (heater-state heater) 'on) (prin1 "turning on heater in ") (prin1 (slot-value heater 'location)) (terpri)) (defmethod turn-off ((heater heater)) (setf (heater-state heater) 'off) (prin1 "turning off heater in ") (prin1 (slot-value heater 'location)) (terpri)) ;;; this function raises the temperature of a list of rooms (defun heat-rooms (rooms amount) (cond ((null rooms) nil) (t (change-temp (car rooms) amount) (heat-rooms (cdr rooms) amount)))) ;;; sample instance for running the simulation: (setf office-heater (make-instance 'heater 'loc 'office)) (setf room-325 (make-instance 'room 'therm (make-instance 'heater-thermostats 'heater-obj office-heater) 'name 'room-325)) (setf (slot-value office-heater 'rooms-heated) (list room-325))