git.fiddlerwoaroof.com
src/ops-backup.lisp
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*