;;; -*- Mode:LISP; Package:USER; Base:10; Readtable:CL -*- (define-standard-structure continuation previous-continuation fctn machine-state) (define-standard-structure history-subproblem valid-flag previous-subproblem next-subproblem reductions) (define-standard-structure history-reduction valid-flag previous-reduction next-reduction continuation) (define-standard-structure history current-subproblem current-reduction) (defun create-double-linked-structures (size maker linker) (let ((elements '())) (dotimes (count size) (push (funcall maker) elements)) (do ((count 0 (1+ count)) (skeleton (apply #'circular-list elements) (rest skeleton))) ((= count size) elements) (let ((this-element (first skeleton)) (next-element (second skeleton))) (funcall linker this-element next-element))))) (defun create-reduction-ring (size) (create-double-linked-structures size #'(lambda () (make-history-reduction :valid-flag nil :previous-reduction nil :next-reduction nil :continuation nil)) #'(lambda (this-reduction next-reduction) (setf (history-reduction-next-reduction this-reduction) next-reduction) (history-reduction-previous-reduction next-reduction) this-reduction))) (defun create-subproblem-ring (size reduction-ring-size) (create-double-linked-structures size #'(lambda () (make-history-subproblem :valid-flag nil :previous-subproblem nil :next-subproblem nil :reductions (first (create-reduction-ring reduction-ring-size)))) #'(lambda (this-subproblem next-subproblem) (setf (history-subproblem-next-subproblem this-subproblem) next-subproblem (history-subproblem-previous-subproblem next-subproblem) this-subproblem)))) (defun create-history (subproblems reductions) (let ((s-ring (create-subproblem-ring subproblems reductions))) (make-history :current-subproblem (first s-ring) :current-reduction (history-subproblem-reductions (first s-ring))))) (defun spread-history (history receiver) (funcall receiver (history-current-subproblem history) (history-current-reduction history))) (defun rotate-reduction-ring (direction history) (let ((next-reduction (funcall direction (history-current-reduction history)))) (setf (history-current-reduction history) next-reduction) next-reduction)) (defun rotate-subproblem-ring (direction history) (spread-history history #'(lambda (current-subproblem current-reduction) (setf (history-subproblem-reductions current-subproblem) current-reduction) (let ((next-subproblem (funcall direction current-subproblem))) (setf (history-current-subproblem history) next-subproblem (history-current-reduction history) (history-subproblem-reductions next-subproblem)) next-subproblem)))) (defvar *maximum-subproblems-to-record* 10.) (defvar *maximum-reductions-to-record* 5.) (defvar *history*) (defun print-cont-result (values) (inspect values) (format t "~%Returning to LISP~% ~S" values)) (defun startup (fctn arglist) (setq *history* (create-history *maximum-subproblems-to-record* *maximum-reductions-to-record*)) (top-level-continuation-driver fctn (make-continuation :previous-continuation () :fctn #'print-cont-result :machine-state ()) arglist)) (defun top-level-continuation-driver (initial-fctn initial-continuation initial-state) (do ((fctn initial-fctn) (continuation initial-continuation) (state initial-state)) ((null continuation) (apply fctn state)) (let ((next-continuation (catch 'continue (apply fctn continuation state)))) ; Debugging ; (format t "~%Received ~S ~S ~S" ; (continuation-fctn next-continuation) ; (continuation-machine-state next-continuation) ; (continuation-previous-continuation next-continuation)) (setq fctn (continuation-fctn next-continuation) continuation (continuation-previous-continuation next-continuation) state (continuation-machine-state next-continuation))))) (defun do-reduction (fctn continuation arglist) (let ((reduction-continuation (make-continuation :previous-continuation continuation :fctn fctn :machine-state arglist))) (let ((reduction (rotate-reduction-ring #'history-reduction-next-reduction *history*))) (setf (history-reduction-continuation reduction) reduction-continuation (history-reduction-valid-flag reduction) t)) (throw 'continue reduction-continuation))) (defun do-subproblem (subproblem-fctn subproblem-args current-continuation return-fctn return-args) (let ((return-continuation (make-continuation :previous-continuation current-continuation :fctn return-fctn :machine-state return-args)) (next-subproblem (rotate-subproblem-ring #'history-subproblem-next-subproblem *history*))) (setf (history-subproblem-valid-flag next-subproblem) t (history-reduction-valid-flag (history-subproblem-reductions next-subproblem)) nil) (do-reduction subproblem-fctn return-continuation subproblem-args))) (defun do-return (continuation return-value) (setf (continuation-machine-state continuation) (cons return-value (continuation-machine-state continuation)) (history-subproblem-valid-flag (history-current-subproblem *history*)) nil) (rotate-subproblem-ring #'history-subproblem-previous-subproblem *history*) (throw 'continue continuation))