5092d8a5 |
;;; ****************************************************************
;;; OPS5 Interpreter ***********************************************
;;; ****************************************************************
;;; This Common Lisp version of OPS5 is in the public domain. It is based
;;; in part on based on a Franz Lisp implementation done by Charles L. Forgy
;;; at Carnegie-Mellon University, which was placed in the public domain by
;;; the author in accordance with CMU policies. Ported to Common Lisp by
;;; George Wood and Jim Kowalski. CMU Common Lisp modifications by
;;; Dario Guise, Skef Wholey, Michael Parzen, and Dan Kuokka.
;;; Modified to work in CLtL1, CLtL2 and X3J13 compatible lisps by
;;; Mark Kantrowitz on 14-OCT-92.
;;;
;;; This code is made available is, and without warranty of any kind by the
;;; authors or by Carnegie-Mellon University.
;;;
;;;; Definitions and functions for backing up.
(in-package "OPS")
;;; Internal Global Variables
|
6c4d2158 |
(defvar *refracts* nil)
(defvar *record* nil)
(defvar *record-array* nil)
(defvar *recording* nil)
(defvar *max-record-index* nil)
(defvar *record-index* nil)
|
5092d8a5 |
(defun backup-init ()
(setq *recording* nil)
(setq *refracts* nil)
(setq *record-array* (make-array 256 :initial-element ())) ;jgk
(initialize-record))
(defun back (k)
(dotimes (i k)
(declare (ignore i))
(let ((r (aref *record-array* *record-index*))) ; (('))
(when (null r) (return '|nothing more stored|))
(setf (aref *record-array* *record-index*) nil)
(record-index-plus -1.)
(undo-record r))))
|
983cb74c |
;; *max-record-index* holds the maximum legal index for record-array
;; so it and the following must be changed at the same time
|
5092d8a5 |
(defun begin-record (p data)
(setq *recording* t)
(setq *record* (list '=>refract p data)))
(defun end-record ()
(when *recording*
(setq *record*
|
983cb74c |
(cons *cycle-count* (cons *p-name* *record*)))
|
5092d8a5 |
(record-index-plus 1.)
(setf (aref *record-array* *record-index*) *record*)
(setq *record* nil)
(setq *recording* nil)))
(defun record-change (direct time elm)
(when *recording*
(setq *record*
|
983cb74c |
(cons direct (cons time (cons elm *record*))))))
|
5092d8a5 |
|
983cb74c |
;; to maintain refraction information, need keep only one piece of information:
;; need to record all unsuccessful attempts to delete things from the conflict
;; set. unsuccessful deletes are caused by attempting to delete refracted
;; instantiations. when backing up, have to avoid putting things back into the
;; conflict set if they were not deleted when running forward
|
5092d8a5 |
(defun record-refract (rule data)
(when *recording*
(setq *record* (cons '<=refract (cons rule (cons data *record*))))))
(defun refracted (rule data)
(when *refracts*
(let ((z (cons rule data)))
(member z *refracts* :test #'equal)))
|
983cb74c |
#+(or)
(prog (z)
(and (null *refracts*) (return nil))
(setq z (cons rule data))
(return (member z *refracts* :test #'equal))))
|
5092d8a5 |
(defun record-index-plus (k)
(incf *record-index* k)
(cond ((< *record-index* 0.)
|
983cb74c |
(setq *record-index* *max-record-index*))
((> *record-index* *max-record-index*)
(setq *record-index* 0.))))
|
5092d8a5 |
|
983cb74c |
;; the following routine initializes the record. putting nil in the
;; first slot indicates that that the record does not go back further
;; than that. (when the system backs up, it writes nil over the used
;; records so that it will recognize which records it has used. thus
;; the system is set up anyway never to back over a nil.)
|
5092d8a5 |
(defun initialize-record nil
(setq *record-index* 0.)
(setq *recording* nil)
(setq *max-record-index* 31.)
(setf (aref *record-array* 0.) nil))
;; replaced per jcp
;;; Commented out
|
983cb74c |
#+(or)
|
5092d8a5 |
(defun undo-record (r)
(prog (save act a b rate)
|
983cb74c |
;;### (comment *recording* must be off during back up) ;
(setq save *recording*)
(setq *refracts* nil)
(setq *recording* nil)
(and *ptrace* (back-print (list '|undo:| (car r) (cadr r))))
(setq r (cddr r))
top (and (atom r) (go fin))
(setq act (car r))
(setq a (cadr r))
(setq b (caddr r))
(setq r (cdddr r))
(and *wtrace* (back-print (list '|undo:| act a)))
(cond ((eq act '<=wm) (add-to-wm b a))
((eq act '=>wm) (remove-from-wm b))
((eq act '<=refract)
(setq *refracts* (cons (cons a b) *refracts*)))
((and (eq act '=>refract) (still-present b))
(setq *refracts* (delete (cons a b) *refracts*))
(setq rate (rating-part (gethash a *topnode-table*)))
(removecs a b)
(insertcs a b rate))
(t (%warn '|back: cannot undo action| (list act a))))
(go top)
fin (setq *recording* save)
(setq *refracts* nil)
(return nil)))
|
5092d8a5 |
;;; End commented out
(defun undo-record (r)
(prog (save act a b rate)
|
983cb74c |
;;### (comment *recording* must be off during back up)
(setq save *recording*)
(setq *refracts* nil)
(setq *recording* nil)
(and *ptrace* (back-print (list '|undo:| (car r) (cadr r))))
(setq r (cddr r))
top (and (atom r) (go fin))
(setq act (car r))
(setq a (cadr r))
(setq b (caddr r))
(setq r (cdddr r))
(and *wtrace* (back-print (list '|undo:| act a)))
(cond ((eq act '<=wm) (add-to-wm b a))
((eq act '=>wm) (remove-from-wm b))
((eq act '<=refract)
(setq *refracts* (cons (cons a b) *refracts*)))
((and (eq act '=>refract) (still-present b))
(setq *refracts* (tree-remove (cons a b) *refracts*))
(setq rate (rating-part (gethash a *topnode-table*)))
(removecs a b)
(insertcs a b rate))
(t (%warn '|back: cannot undo action| (list act a))))
(go top)
fin (setq *recording* save)
(setq *refracts* nil)
(return nil)))
;; still-present makes sure that the user has not deleted something
;; from wm which occurs in the instantiation about to be restored; it
;; makes the check by determining whether each wme still has a time tag.
|
5092d8a5 |
(defun still-present (data)
(prog nil
|
983cb74c |
loop
(cond ((atom data) (return t))
((creation-time (car data))
(setq data (cdr data))
(go loop))
(t (return nil)))))
|
5092d8a5 |
(defun back-print (x)
(let ((stream (trace-file)))
(format stream "~&~S" x)))
;;; *EOF*
|