;;; 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)

;;; 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)
		(prin1 "the temperature in ")
		(prin1 (room-name place))
		(prin1 " is now ")
		(prin1 new-temp)
		(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)
		(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))

(defmethod turn-off ((heater heater))
	(setf (heater-state heater) 'off)
	(prin1 "turning off heater in ")
	(prin1 (slot-value heater 'location))

;;; 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))


Close Window