AAL sources (4 of 8)

Jonathan Amsterdam jba at wheaties.ai.mit.edu
Sun Jun 11 07:30:25 AEST 1989


;;; -*- Mode: LISP; Syntax: Common-lisp; Package: USER; Base: 10 -*-

;;; Copyright 1988 by Jonathan Amsterdam.  All Rights Reserved.

(provide 'initial)

;;; Initial stuff for AAL.  This file should be loaded before the others
;;; (except streams, which doesn't depend on anything).
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Macros.

#-3600
(defmacro defprop (sym value indicator)
  ;; Like putprop, but doesn't evaluate its arguments.  The Symbolics 3600
  ;; already has this defined.
  `(setf (get ',sym ',indicator) ',value))

(defmacro defunp (prop-symbol arglist &body body)
  ;; Allows defining a function to be the value of a property on a symbol.  See
  ;; the deducer, execute-action and keywords in the compiler for usage.
  (let* ((prop (first prop-symbol))
	 (symbol (second prop-symbol))
	 (name (symbol-append prop '- symbol '- 'func)))
    `(progn
       (defun ,name ,arglist , at body)
       (defprop ,symbol ,name ,prop))))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Structures.

;;; Changed slightly from the article--instead of a failure string, you can
;;; have any action.
(defstruct requirement
  pattern
  (failure-action				;action to take on failure
    '(lisp (format t "You can't do that.")))
  succeeded?					;used internally by check-reqs
)


(defstruct timer			; used for timers and demons
  before-after				;:before, :after
  turn-tick				;:turn, :tick
  time-to-run				;number indicating when to run
  action				;code to run 
  (renew-time 0)			;if 0, not renewable; else this is
					;added to time-to-run when expired 
)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Constants.

(defconstant *initial-lisp-names* 
	     '(eql member cons car cdr + - * / setf incf decf push print eval
	       get null = zerop)
	     "The action and pattern parsers translate these automatically")

(defconstant *initial-global-specs*
	     '(*agent *command *obj *instr *verb *loc (*turn 0) (*tick 0)))


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Global variables.

(defvar *report* nil "Controls debugging messages")

;;; The following are modified by the compiler.

(defvar *objects* nil "A list of all the objects in the game (including locs)")
(defvar *assertion-rules* nil "Forward rules to run on assertions")
(defvar *retraction-rules* nil "Forward rules to run on retractions")
(defvar *initial-actions* nil "Actions executed when the game starts")
(defvar *initial-rules* nil "Rules asserted when the game starts")
(defvar *initial-timers* nil)

(defvar *lisp-names* nil "Used in parsing actions and patterns")
(defvar *global-specs* nil "Used in declaring globals")
(defvar *backward-predicates* nil "Used in parsing actions and patterns")


;;; The following are modified during the game.

(defvar *tick* nil "The current tick")
(defvar *turn* nil "The current turn")
(defvar *abort-action* nil "Indicates when an action has been aborted in the middle")

(defvar *globals* nil "An alist of the AAL globals")
(defvar *protected-vars* nil "An alist of variables protected from renaming")
(defvar *db*      nil "The database, which holds a list of all the facts")
(defvar *indices* nil "The symbols used as indices by the database indexer")
(defvar *timers*  nil "Lists of the currently active timers")


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Initialization.

(defun play (filename)
  (cold-init)
  (load filename)
  (reverse-lists)
  (replay))

(defun reverse-lists ()
  ;; Reverse the objects, so the ones earlier in the file are first.
  ;; Reverse the initial actions, so that the ones earlier in the file are done
  ;; before those later.
  (setq *objects* (nreverse *objects*))
  (setq *initial-actions* (nreverse *initial-actions*))
  (dolist (obj *objects*)
    (setf (get obj 'initial-actions) (nreverse (get obj 'initial-actions)))))
  
(defun replay ()
  (warm-init)
  (run))

(defun cold-init ()
  ;; Set up stuff necessary to load a new file.
  (setq *objects* nil)
  (setq *assertion-rules* nil)
  (setq *retraction-rules* nil)
  (setq *initial-actions* nil)
  (setq *initial-rules* nil)
  (setq *initial-timers* nil)
  (setq *lisp-names* *initial-lisp-names*)
  (setq *global-specs* *initial-global-specs*)
  (setq *backward-predicates* nil)
)

(defun warm-init ()
  ;; Do things necessary for replaying an already loaded game.
  (setq *tick* 0)
  (setq *turn* 0)
  (setq *abort-action* nil)
  (setq *protected-vars* nil)
  (clear-database)
  (clear-timers)
  (init-vars)
  (init-timers)
  ;; Add the b-rules before the facts, because adding facts might trigger
  ;; rules.  Also, this will put the rules at the end of the database, where
  ;; they should be (so facts can override them).
  (init-rules)
  (init-actions)
)

(defun clear-database ()
  (setq *db* nil)
  (dolist (index *indices*)
    (setf (get index 'database) nil))
  (setq *indices* '(*)))

(defun clear-timers ()
  ;; We need to do a copy-tree because this list is destructively modified.
  (setq *timers* (copy-tree '((:after . ((:tick . nil) (:turn . nil)))
			      (:before . ((:tick . nil) (:turn . nil)))))))

(defun init-vars ()
  (setq *globals* (specs->alist *global-specs*))
  (dolist (obj *objects*)
    (setf (get obj 'vars) (specs->alist (get obj 'var-specs)))))


(defun specs->alist (specs)
  ;; A variable spec is either a variable name, in which case it's bound to
  ;; NIL, or a list (<name> <value>).
  (mapcar #'(lambda (spec) (if (symbolp spec)
			       (cons spec nil) 
			       (cons (first spec) (second spec))))
	  specs))
  
(defun init-rules ()
  (dolist (rule *initial-rules*)
    (assert rule)))

(defun init-timers ()
  (mapc #'add-timer (mapcar #'eval *initial-timers*)))

(defun init-actions ()
  ;; First do all the actions local to objects.  Then do the global actions.
  (dolist (obj *objects*)
    (dolist (action (get obj 'initial-actions))
      (execute-action-in-object obj action)))
  (dolist (action *initial-actions*)
    (execute-action action *globals*)))


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Utilities.

(defun symbol-append (&rest symbols)
  (intern (apply #'string-append symbols)))

(defun report (&rest args)
  (if *report*
      (apply #'format t args)))


;;; End initial.lisp.



More information about the Alt.sources mailing list