Update of /project/cells/cvsroot/cells
In directory common-lisp.net:/tmp/cvs-serv6620
Modified Files:
build.lisp calc-n-set.lisp cell-types.lisp cells.asd
cells.lisp dataflow-management.lisp debug.lisp defmodel.lisp
detritus.lisp family-values.lisp family.lisp flow-control.lisp
fm-utilities.lisp initialize.lisp link.lisp md-slot-value.lisp
md-utilities.lisp model-object.lisp optimization.lisp
propagate.lisp qells.lisp qrock.lisp slot-utilities.lisp
strings.lisp strudel-object.lisp synapse.lisp
Added Files:
build-sys.lisp
Removed Files:
buildold.lisp cells-read-me.txt datetime.lisp
Log Message:
Preparing for first CVS of Cello
Date: Tue Dec 16 10:02:59 2003
Author: ktilton
Index: cells/build.lisp
diff -u cells/build.lisp:1.1.1.1 cells/build.lisp:1.2
--- cells/build.lisp:1.1.1.1 Sat Nov 8 18:43:38 2003
+++ cells/build.lisp Tue Dec 16 10:02:58 2003
@@ -1,102 +1,71 @@
-;; -*- mode: Lisp; Syntax: Common-Lisp; Package: cl-user; -*-
-;;;
-;;; Copyright © 1995,2003 by Kenneth William Tilton.
-;;;
-;;; Permission is hereby granted, free of charge, to any person obtaining a copy
-;;; of this software and associated documentation files (the "Software"), to deal
-;;; in the Software without restriction, including without limitation the rights
-;;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-;;; copies of the Software, and to permit persons to whom the Software is furnished
-;;; to do so, subject to the following conditions:
-;;;
-;;; The above copyright notice and this permission notice shall be included in
-;;; all copies or substantial portions of the Software.
-;;;
-;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-;;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-;;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-;;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-;;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-;;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-;;; IN THE SOFTWARE.
-
-(defpackage #:cells-build-package
- (:use #:cl))
-(in-package :cl-user) ;;#:cells-build-package)
-
-;;; ***********************************************************************
-;;; Begin configuration section
-;;;
-;;; Step 1
-;;; ------
-;;; Edit the definition of *CELLS-SOURCE-DIRECTORY* so the build script
-;;; knows where to find its source. For example:
-;;;
-;;; Unix:
-;;; (defvar *cells-source-directory* #p"/usr/local/src/cells/")
-;;;
-;;; Windows:
-;;;
-;;;(defparameter *cells-source-directory*
-;;; (make-pathname #+lispworks :host #-lispworks :device "C"
-;;; :directory "/dev/cells"))
-
-;;; Validation of *cells-source-directory*
-;;;
-(unless (boundp '*cells-source-directory*)
- (error "*CELLS-SOURCE-DIRECTORY* not supplied, please edit build.lisp to specify the location of the source."))
-
-(unless (probe-file (merge-pathnames "cells.asd" *cells-source-directory*))
- (error "cells.asd not found in:~& *CELLS-SOURCE-DIRECTORY* => ~a"
- *cells-source-directory*))
-
-;;; Step 2
-;;; ------
-;;; Help the build script find ASDF if not already loaded
-#-asdf
-(load (merge-pathnames (make-pathname :name "asdf" :type "lisp")
- *cells-source-directory*))
-
-;;; Step 3
-;;; ------
-;;; Decide if you want to run the Cells regression test suite [optional]
-(defparameter *test-cells* t)
-
-;;; Yer done
-;;;
-;;; End configuration section
-;;; ***********************************************************************
-
-
-(defparameter *cells-test-directory*
- (merge-pathnames (make-pathname :directory '(:relative "cells-test"))
- *cells-source-directory*))
-
-;;;
-;;; Implementation-specific weirdness goes here
-;;;
-
-(let (;; Let's assume this is fixed in CMUCL 19a, and fix it later if need be.
- #+cmu18
- (ext:*derive-function-types* nil)
-
- #+lispworks
- (hcl::*handle-existing-defpackage* (list :add))
- )
-
-;;;
-;;; Now, build the system
-;;;
-
- (push *cells-source-directory* asdf:*central-registry*)
- (asdf:operate 'asdf:load-op :cells)
-
- (when *test-cells*
- (push *cells-test-directory* asdf:*central-registry*)
- (asdf:operate 'asdf:load-op :cells-test)
- (format t "~&~%Warning on refined c-echo-slot-name is expected because")
- (format t "~&cells-test is loaded. To run the test suite, evaluate:")
- (format t "~&~% (cells::cv-test)")
- (format t "~&~%and simply confirm it runs to completion.")))
-
-(delete-package '#:cells-build-package)
\ No newline at end of file
+;; -*- mode: Lisp; Syntax: Common-Lisp; Package: cl-user; -*-
+
+(in-package :cl-user)
+
+;;; ***********************************************************************
+;;; Begin configuration section
+;;;
+;;; Before building Cells, review and customize the following settings:
+;;;
+(let (
+ ;; Step 1
+ ;; ------
+ ;; The path to ASDF. This is only necessary if it's not already loaded.
+ ;;
+ ;; Examples:
+ ;; Unix: (asdf-path (pathname "/usr/local/src/asdf.lisp"))
+ ;; Windows: (asdf-path (pathname "C:\\dev\\asdf.lisp"))
+ ;; Windows: (asdf-path (make-pathname :directory '(:absolute "dev")
+ ;; :name "asdf" :type "lisp"))
+ (asdf-path nil)
+
+ ;; Step 2
+ ;; ------
+ ;; The path to the Cells source directory.
+ ;;
+ ;; Examples:
+ ;; Unix: (cells-path (pathname "/usr/local/src/cells/"))
+ ;; Windows: (cells-path (pathname "C:\\dev\\cells\\"))
+ ;; Windows: (cells-path (make-pathname
+ ;; :directory '(:absolute "dev" "cells")
+ ;; #+lispworks :host #-lispworks :device
+ ;; "C"))
+ (cells-path nil)
+
+ ;; Step 3
+ ;; ------
+ ;; Decide if you want to load and run the regression test suite.
+ ;; If you want to validate the system or explore the test suite,
+ ;; some of which is heavily annotated, set TESTP to T
+ (testp t)
+ )
+
+;;; Yer done
+;;;
+;;; End configuration section
+;;; ***********************************************************************
+
+
+ ;; Ensure ASDF is loaded
+ #-asdf
+ (progn (assert (not (null asdf-path))
+ (asdf-path)
+ "ASDF is not loaded, and ASDF-PATH was not supplied. Please edit build.lisp")
+ (load asdf-path))
+
+ ;; Build Cells.
+ (load (merge-pathnames "build-sys.lisp" cells-path))
+ (funcall (intern "BUILD-SYS" "CELLS-BUILD-PACKAGE")
+ :force t :source-directory cells-path)
+
+ ;; Load and run the test suite, if requested.
+ (when testp
+ (funcall (intern "BUILD-SYS" "CELLS-BUILD-PACKAGE")
+ :force t
+ :source-directory (merge-pathnames
+ (make-pathname :directory '(:wild "cells-test"))
+ cells-path))
+ (funcall (intern "CV-TEST" "CELLS")))
+
+ ;; Remove build package
+ (delete-package "CELLS-BUILD-PACKAGE"))
Index: cells/calc-n-set.lisp
diff -u cells/calc-n-set.lisp:1.1.1.1 cells/calc-n-set.lisp:1.2
--- cells/calc-n-set.lisp:1.1.1.1 Sat Nov 8 18:43:48 2003
+++ cells/calc-n-set.lisp Tue Dec 16 10:02:58 2003
@@ -1,108 +1,103 @@
-;; -*- mode: Lisp; Syntax: Common-Lisp; Package: cells; -*-
-;;;
-;;; Copyright © 1995,2003 by Kenneth William Tilton.
-;;;
-;;; Permission is hereby granted, free of charge, to any person obtaining a copy
-;;; of this software and associated documentation files (the "Software"), to deal
-;;; in the Software without restriction, including without limitation the rights
-;;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-;;; copies of the Software, and to permit persons to whom the Software is furnished
-;;; to do so, subject to the following conditions:
-;;;
-;;; The above copyright notice and this permission notice shall be included in
-;;; all copies or substantial portions of the Software.
-;;;
-;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-;;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-;;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-;;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-;;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-;;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-;;; IN THE SOFTWARE.
-
-(in-package :cells)
-
-;____________________________ cell calculate and set ___________________
-;
-
-(defun c-calculate-and-set (c)
- (when *stop*
- (princ #\.)
- (return-from c-calculate-and-set))
-
- (assert (not (cmdead c)))
-
- (when (find c *c-calculators*) ;; circularity
- (if (unst-cyclic-p c)
- (progn
- (trc "md-slot-value cyclic defaulting" c (unst-cyclic-value c))
- (return-from c-calculate-and-set (unst-cyclic-value c)))
- (progn
- (setf *stop* t)
- (trc "md-slot-value breaking on circularity" c *c-calculators*)
- (break ;; problem when testing cells on some CLs
- "cell ~a midst askers: ~a" c *c-calculators*))))
-
- (count-it :c-calculate-and-set )
- ;;; (count-it :c-calculate-and-set (type-of (c-model c))) ;; (c-slot-name c))
-
- ;;(with-metrics (nil nil () "calc n set" (c-slot-name c) (c-model c))
- (progn ;; wtrc (0 200 "calc n set" (c-slot-name c) (c-model c))
- (cd-usage-clear-all c)
-
- (let ((mycalc (incf (cr-rethinking c) 1))
- (newvalue (let ((*c-calculators* (cons c *c-calculators*))
- *synapse-factory* ;; clear, then if desired each access to potential other cell must estab. *synapse-factory*
- )
- (assert (c-model c))
- #+not (when (plusp *trcdepth*)
- (format t "ccalcnset> calcing ~a calcers ~a" c *c-calculators*))
- (funcall (cr-rule c) c))))
-
- #+notso (assert (not (typep newvalue 'cell)) ()
- "new value for cell ~s is itself a cell: ~s. probably nested (c? ... (c? ))"
- c newvalue)
- (when (and *c-debug* (typep newvalue 'cell))
- (trc "new value for cell ~s is itself a cell: ~s. probably nested (c? ... (c? ))"
- c newvalue))
- (when (< mycalc (cr-rethinking c))
- ;;
- ;; means we re-entered rule and managed to compute without re-entering under new circumstances
- ;; of later entry. use later calculation result..
- (trc nil "calc-n-set > breaking off, not lg" c)
- ;;
- (assert (c-validp c))
- (return-from c-calculate-and-set (c-value c)))
-
- (c-unlink-unused c)
-
- (md-slot-value-assume (c-model c)
- (c-slot-spec c)
- (c-absorb-value c newvalue)))))
-
-#+test
-(loop for useds on '(1 2 3 4 5)
- for used = (car useds)
- for mapn upfrom 5
- when (oddp used)
- do (print (list useds mapn))(print used))
-
-(defun c-unlink-unused (c &aux (usage (cd-usage c)))
- (loop for useds on (cd-useds c)
- for used = (car useds)
- for mapn upfrom (- *cd-usagect* (length (cd-useds c)))
- when (zerop (sbit usage mapn))
- do
- (assert (not (minusp mapn)))
- (assert (< mapn *cd-usagect*))
- (if (typep used 'synapse)
- (progn
- (setf (syn-relevant used) nil) ;; 030826synfix
- )
- (progn
- (trc nil "dropping unused" used :mapn-usage mapn usage)
- (c-unlink-user used c)
- (rplaca useds nil))))
- (setf (cd-useds c) (delete-if #'null (cd-useds c))))
-
-
+;; -*- mode: Lisp; Syntax: Common-Lisp; Package: cells; -*-
+;;;
+;;; Copyright (c) 1995,2003 by Kenneth William Tilton.
+;;;
+;;; Permission is hereby granted, free of charge, to any person obtaining a copy
+;;; of this software and associated documentation files (the "Software"), to deal
+;;; in the Software without restriction, including without limitation the rights
+;;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+;;; copies of the Software, and to permit persons to whom the Software is furnished
+;;; to do so, subject to the following conditions:
+;;;
+;;; The above copyright notice and this permission notice shall be included in
+;;; all copies or substantial portions of the Software.
+;;;
+;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+;;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+;;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+;;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+;;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+;;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+;;; IN THE SOFTWARE.
+
+(in-package :cells)
+
+;____________________________ cell calculate and set ___________________
+;
+
+(defun c-calculate-and-set (c)
+ (when (c-stopped)
+ (princ #\.)
+ (return-from c-calculate-and-set))
+
+ (c-assert (not (cmdead c)))
+
+ (when (find c *c-calculators*) ;; circularity
+ (c-stop :c-calculate-and-set-circ-ask)
+ (trc "md-slot-value breaking on circularity" c *c-calculators*)
+ (break ;; problem when testing cells on some CLs
+ "cell ~a midst askers: ~a" c *c-calculators*))
+
+ (count-it :c-calculate-and-set )
+ ;;; (count-it :c-calculate-and-set (type-of (c-model c))) ;; (c-slot-name c))
+
+ ;;(with-metrics (nil nil () "calc n set" (c-slot-name c) (c-model c))
+ (progn ;; wtrc (0 200 "calc n set" (c-slot-name c) (c-model c))
+ (cd-usage-clear-all c)
+
+ (let ((mycalc (incf (cr-rethinking c) 1))
+ (newvalue (let ((*c-calculators* (cons c *c-calculators*))
+ *synapse-factory* ;; clear, then if desired each access to potential other cell must estab. *synapse-factory*
+ )
+ (c-assert (c-model c))
+ #+not (when (plusp *trcdepth*)
+ (format t "ccalcnset> calcing ~a calcers ~a" c *c-calculators*))
+ (funcall (cr-rule c) c))))
+
+ #+notso (c-assert (not (typep newvalue 'cell)) ()
+ "new value for cell ~s is itself a cell: ~s. probably nested (c? ... (c? ))"
+ c newvalue)
+ (when (and *c-debug* (typep newvalue 'cell))
+ (trc "new value for cell ~s is itself a cell: ~s. probably nested (c? ... (c? ))"
+ c newvalue))
+ (when (< mycalc (cr-rethinking c))
+ ;;
+ ;; means we re-entered rule and managed to compute without re-entering under new circumstances
+ ;; of later entry. use later calculation result..
+ (trc nil "calc-n-set > breaking off, not lg" c)
+ ;;
+ (c-assert (c-validp c))
+ (return-from c-calculate-and-set (c-value c)))
+
+ (c-unlink-unused c)
+
+ (md-slot-value-assume (c-model c)
+ (c-slot-spec c)
+ (c-absorb-value c newvalue)))))
+
+#+test
+(loop for useds on '(1 2 3 4 5)
+ for used = (car useds)
+ for mapn upfrom 5
+ when (oddp used)
+ do (print (list useds mapn))(print used))
+
+(defun c-unlink-unused (c &aux (usage (cd-usage c)))
+ (loop for useds on (cd-useds c)
+ for used = (car useds)
+ for mapn upfrom (- *cd-usagect* (length (cd-useds c)))
+ when (zerop (sbit usage mapn))
+ do
+ (c-assert (not (minusp mapn)))
+ (c-assert (< mapn *cd-usagect*))
+ (if (typep used 'synapse)
+ (progn
+ (setf (syn-relevant used) nil) ;; 030826synfix
+ )
+ (progn
+ (trc nil "dropping unused" used :mapn-usage mapn usage)
+ (c-unlink-user used c)
+ (rplaca useds nil))))
+ (setf (cd-useds c) (delete-if #'null (cd-useds c))))
+
+
Index: cells/cell-types.lisp
diff -u cells/cell-types.lisp:1.1.1.1 cells/cell-types.lisp:1.2
--- cells/cell-types.lisp:1.1.1.1 Sat Nov 8 18:43:48 2003
+++ cells/cell-types.lisp Tue Dec 16 10:02:58 2003
@@ -1,293 +1,257 @@
-;; -*- mode: Lisp; Syntax: Common-Lisp; Package: cells; -*-
-;;;
-;;; Copyright © 1995,2003 by Kenneth William Tilton.
-;;;
-;;; Permission is hereby granted, free of charge, to any person obtaining a copy
-;;; of this software and associated documentation files (the "Software"), to deal
-;;; in the Software without restriction, including without limitation the rights
-;;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-;;; copies of the Software, and to permit persons to whom the Software is furnished
-;;; to do so, subject to the following conditions:
-;;;
-;;; The above copyright notice and this permission notice shall be included in
-;;; all copies or substantial portions of the Software.
-;;;
-;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-;;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-;;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-;;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-;;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-;;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-;;; IN THE SOFTWARE.
-
-(in-package :cells)
-
-(defun slot-spec-name (slot-spec)
- slot-spec)
-
-(cc-defstruct (cell (:conc-name c-))
- waking-state
- model
- slot-spec
- value
- )
-
-(defun c-slot-name (c)
- (slot-spec-name (c-slot-spec c)))
-
-(defun c-validate (self c)
- (when (not (and (c-slot-spec c) (c-model c)))
-;;; (setf *stop* t)
- (format t "~&unadopted cell: ~s md:~s, awake:~s" c self (c-waking-state self))
- (error 'c-unadopted :cell c)))
-
-(defmethod c-when (other)
- (declare (ignorable other)) nil) ;; /// needs work
-
-(cc-defstruct (synapse
- (:include cell)
- (:conc-name syn-))
- user
- used
- (relevant t) ;; not if unused during subsequent eval. but keep to preserve likely state
- fire-p
- relay-value)
-
-(defmacro mksynapse ((&rest closeovervars) &key trcp fire-p relay-value)
- (let ((used (copy-symbol 'used)) (user (copy-symbol 'user)))
- `(lambda (,used ,user)
- ,(when trcp
- `(trc "making synapse between user" ',trcp ,user :and :used ,used))
- (let (,@closeovervars)
- (make-synapse
- :used ,used
- ;;; 210207kt why? use (c-model (syn-used <syn>)) :c-model (c-model ,used)
- :user ,user
- :fire-p ,fire-p
- :relay-value ,relay-value)))))
-
-(defmethod print-object ((syn synapse) stream)
- (format stream "{syn ~s ==> ~s" (syn-used syn) (syn-user syn)))
-
-
-(defmethod c-true-stalep ((syn synapse))
- (cd-stale-p (syn-user syn)))
-
-(cc-defstruct (c-user-notifying
- (:include cell)
- (:conc-name un-))
- (users nil :type list))
-
-(cc-defstruct (c-unsteady
- (:include c-user-notifying)
- (:conc-name unst-))
- cyclic-p
- cyclic-value
- delta-p
- setting-p)
-
-(cc-defstruct (c-variable
- (:include c-unsteady)))
-
-(cc-defstruct (c-ruled
- (:include c-unsteady)
- (:conc-name cr-))
- (state :unbound :type symbol)
- (rethinking 0 :type number)
- lazy
- rule)
-
-(defmethod c-lazy-p ((c c-ruled)) (cr-lazy c))
-(defmethod c-lazy-p (c) (declare (ignore c)) nil)
-
-(defun c-optimized-away-p (c)
- (eql :optimized-away (c-state c)))
-
-;----------------------------
-
-
-(defmethod c-true-stalep (c)
- (declare (ignore c)))
-
-(cc-defstruct (c-independent
- ;;
- ;; these do not optimize away, because also these can be set after initial evaluation of the rule,
- ;; so users better stay tuned.
- ;; the whole idea here is that the old idea of having cv bodies evaluated immediately finally
- ;; broke down when we wanted to say :kids (cv (list (fm-other vertex)))
- ;;
- (:include c-ruled)))
-
-(defmethod trcp-slot (self slot-name)
- (declare (ignore self slot-name)))
-
-(defconstant *cd-usagect* 64)
-
-(cc-defstruct (c-dependent
- (:include c-ruled)
- (:conc-name cd-))
- (useds nil :type list)
- (code nil :type list) ;; /// feature this out on production build
- (usage (make-array *cd-usagect* :element-type 'bit
- :initial-element 0) :type vector)
- stale-p
- )
-
-;;;(defmethod trcp ((c c-dependent))
-;;; (or (trcp-slot (c-model c) (c-slot-name c))
-;;; ;;(c-lazy-p c)
-;;; nil))
-
-(defmethod c-true-stalep ((c c-dependent))
- (cd-stale-p c))
-
-(cc-defstruct (c-stream
- (:include c-ruled)
- (:conc-name cs-))
- values)
-
-;;; (defmacro cell~ (&body body)
-;;; `(make-c-stream
-;;; :rule (lambda ,@*c-lambda*
-;;; ,@body)))
-
-(cc-defstruct (c-drifter
- (:include c-dependent)))
-
-(cc-defstruct (c-drifter-absolute
- (:include c-drifter)))
-
-;_____________________ accessors __________________________________
-
-
-(defun (setf c-state) (new-value c)
- (if (typep c 'c-ruled)
- (setf (cr-state c) new-value)
- new-value))
-
-(defun c-state (c)
- (if (typep c 'c-ruled)
- (cr-state c)
- :valid))
-
-(defun c-unboundp (c)
- (eql :unbound (c-state c)))
-
-(defun c-validp (c)
- (find (c-state c) '(:valid :optimized-away)))
-
-;_____________________ print __________________________________
-
-(defmethod print-object :before ((c c-variable) stream)
- (declare (ignorable c))
- (format stream "[var:"))
-
-(defmethod print-object :before ((c c-dependent) stream)
- (declare (ignorable c))
- (format stream "[dep~a:" (cond
- ((null (c-model c)) #\0)
- ((eq :eternal-rest (md-state (c-model c))) #\_)
- ((cd-stale-p c) #\#)
- ((sw-pending c) #\?)
- (t #\space))))
-
-(defmethod print-object :before ((c c-independent) stream)
- (declare (ignorable c))
- (format stream "[ind:"))
-
-(defmethod print-object ((c cell) stream)
- (c-print-value c stream)
- (format stream "=~a/~a]"
- (symbol-name (or (c-slot-name c) :anoncell))
- (or (c-model c) :anonmd))
-;;; #+dfdbg (unless *stop*
-;;; (assert (find c (cells (c-model c)) :key #'cdr)))
- )
-
-;__________________
-
-(defmethod c-print-value ((c c-ruled) stream)
- (format stream "~a" (cond ((unst-setting-p c) "<^^^>")
- ((c-validp c) "<vld>")
- ((c-unboundp c) "<unb>")
- ((cd-stale-p c) "<obs>")
- (t "<err>"))))
-
-(defmethod c-print-value (c stream)
- (declare (ignore c stream)))
-
-;____________________ constructors _______________________________
-
-(defmacro c-lambda (&body body)
- (let ((c (gensym)))
- `(lambda (,c &aux (self (c-model ,c))
- (.cache (c-value ,c)))
- (declare (ignorable .cache self))
- (assert (not (cmdead ,c))() "cell dead entering rule ~a" ,c)
- ,@body)))
-
-(defmacro c? (&body body)
- `(make-c-dependent
- :code ',body
- :rule (c-lambda ,@body)))
-
-(defmacro c?_ (&body body)
- `(make-c-dependent
- :code ',body
- :lazy t
- :rule (c-lambda ,@body)))
-
-(defmacro c?? ((&key (tagp nil) (in nil) (trigger nil) (out t))&body body)
- (let ((result (copy-symbol 'result))
- (thetag (gensym)))
- `(make-c-dependent
- :code ',body
- :rule (c-lambda
- (let ((,thetag (gensym "tag"))
- (*trcdepth* (1+ *trcdepth*))
- )
- (declare (ignorable self ,thetag))
- ,(when in
- `(trc "c??> entry" (c-slot-name c) (c-model c) (when ,tagp ,thetag)))
- ,(when trigger `(trc "c??> trigger" *cause* c))
- (count-it :c?? (c-slot-name c) (md-name (c-model c)))
- (let ((,result (progn ,@body)))
- ,(when out `(trc "c?? result:" ,result (c-slot-name c) (when ,tagp ,thetag)))
- ,result))))))
-
-(defmacro cv (defn)
- `(make-c-variable
- :value ,defn)) ;; use c-independent if need deferred execution
-
-(defmacro cv8 (defn)
- `(make-c-variable
- :cyclic-p t
- :value ,defn)) ;; use c-independent if need deferred execution
-
-(defmacro c... ((value) &body body)
- `(make-c-drifter
- :code ',body
- :value ,value
- :rule (c-lambda ,@body)))
-
-(defmacro c-abs (value &body body)
- `(make-c-drifter-absolute
- :code ',body
- :value ,value
- :rule (lambda (c &aux (self (c-model c)))
- (declare (ignorable self c))
- ,@body)))
-
-
-(defmacro c-envalue (&body body)
- `(make-c-envaluer
- :envaluerule (lambda (self)
- (declare (ignorable self))
- ,@body)))
-
-(defmacro c8 ((&optional cyclic-value) &body body)
- `(make-c-dependent
- :code ',body
- :cyclic-p t
- :cyclic-value ,cyclic-value
- :rule (c-lambda ,@body)))
+;; -*- mode: Lisp; Syntax: Common-Lisp; Package: cells; -*-
+;;;
+;;; Copyright (c) 1995,2003 by Kenneth William Tilton.
+;;;
+;;; Permission is hereby granted, free of charge, to any person obtaining a copy
+;;; of this software and associated documentation files (the "Software"), to deal
+;;; in the Software without restriction, including without limitation the rights
+;;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+;;; copies of the Software, and to permit persons to whom the Software is furnished
+;;; to do so, subject to the following conditions:
+;;;
+;;; The above copyright notice and this permission notice shall be included in
+;;; all copies or substantial portions of the Software.
+;;;
+;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+;;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+;;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+;;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+;;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+;;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+;;; IN THE SOFTWARE.
+
+(in-package :cells)
+
+(defun slot-spec-name (slot-spec)
+ slot-spec)
+
+
+(defstruct (cell (:conc-name c-))
+ waking-state
+ model
+ slot-spec
+ value
+ (users nil :type list))
+
+(defun test ()
+ (let (x)
+ (makunbound x)
+ x))
+
+(defun c-slot-name (c)
+ (slot-spec-name (c-slot-spec c)))
+
+(defun c-validate (self c)
+ (when (not (and (c-slot-spec c) (c-model c)))
+ (format t "~&unadopted cell: ~s md:~s, awake:~s" c self (c-waking-state self))
+ (c-break "unadopted cell ~a ~a" self c)
+ (error 'c-unadopted :cell c)))
+
+(defmethod c-when (other)
+ (declare (ignorable other)) nil) ;; /// needs work
+
+(defstruct (synapse
+ (:conc-name syn-))
+ user
+ used
+ (relevant t) ;; not if unused during subsequent eval. but keep to preserve any state
+ fire-p
+ relay-value)
+
+(defmacro mksynapse ((&rest closeovervars) &key trcp fire-p relay-value)
+ (let ((used (copy-symbol 'used)) (user (copy-symbol 'user)))
+ `(lambda (,used ,user)
+ ,(when trcp
+ `(trc "making synapse between user" ',trcp ,user :and :used ,used))
+ (let (,@closeovervars)
+ (make-synapse
+ :used ,used
+ :user ,user
+ :fire-p ,fire-p
+ :relay-value ,relay-value)))))
+
+(defmethod print-object ((syn synapse) stream)
+ (format stream "{syn ~s ==> ~s" (syn-used syn) (syn-user syn)))
+
+(defmethod c-true-stalep ((syn synapse))
+ (cd-stale-p (syn-user syn)))
+
+(defstruct (c-variable
+ (:include cell)
+ (:conc-name cv-))
+ cyclic-p
+ setting-p)
+
+(defstruct (c-ruled
+ (:include cell)
+ (:conc-name cr-))
+ (state :unbound :type symbol)
+ (rethinking 0 :type number)
+ lazy
+ rule)
+
+(defmethod c-lazy-p ((c c-ruled)) (cr-lazy c))
+(defmethod c-lazy-p (c) (declare (ignore c)) nil)
+
+(defun c-optimized-away-p (c)
+ (eql :optimized-away (c-state c)))
+
+;----------------------------
+
+(defmethod c-true-stalep (c)
+ (declare (ignore c)))
+
+(defmethod trcp-slot (self slot-name)
+ (declare (ignore self slot-name)))
+
+(defconstant *cd-usagect* 64)
+
+(defstruct (c-dependent
+ (:include c-ruled)
+ (:conc-name cd-))
+ (useds nil :type list)
+ (code nil :type list) ;; /// feature this out on production build
+ (usage (make-array *cd-usagect* :element-type 'bit
+ :initial-element 0) :type vector)
+ stale-p
+ )
+
+;;;(defmethod trcp ((c c-dependent))
+;;; (or (trcp-slot (c-model c) (c-slot-name c))
+;;; ;;(c-lazy-p c)
+;;; nil))
+
+(defmethod c-true-stalep ((c c-dependent))
+ (cd-stale-p c))
+
+(defstruct (c-stream
+ (:include c-ruled)
+ (:conc-name cs-))
+ values)
+
+;;; (defmacro cell~ (&body body)
+;;; `(make-c-stream
+;;; :rule (lambda ,@*c-lambda*
+;;; ,@body)))
+
+(defstruct (c-drifter
+ (:include c-dependent)))
+
+(defstruct (c-drifter-absolute
+ (:include c-drifter)))
+
+;_____________________ accessors __________________________________
+
+
+(defun (setf c-state) (new-value c)
+ (if (typep c 'c-ruled)
+ (setf (cr-state c) new-value)
+ new-value))
+
+(defun c-state (c)
+ (if (typep c 'c-ruled)
+ (cr-state c)
+ :valid))
+
+(defun c-unboundp (c)
+ (eql :unbound (c-state c)))
+
+(defun c-validp (c)
+ (find (c-state c) '(:valid :optimized-away)))
+
+;_____________________ print __________________________________
+
+(defmethod print-object :before ((c c-variable) stream)
+ (declare (ignorable c))
+ (format stream "[var:"))
+
+(defmethod print-object :before ((c c-dependent) stream)
+ (declare (ignorable c))
+ (format stream "[dep~a:" (cond
+ ((null (c-model c)) #\0)
+ ((eq :eternal-rest (md-state (c-model c))) #\_)
+ ((cd-stale-p c) #\#)
+ ((sw-pending c) #\?)
+ (t #\space))))
+
+(defmethod print-object ((c cell) stream)
+ (c-print-value c stream)
+ (format stream "=~a/~a]"
+ (symbol-name (or (c-slot-name c) :anoncell))
+ (or (c-model c) :anonmd)))
+
+;__________________
+
+(defmethod c-print-value ((c c-ruled) stream)
+ (format stream "~a" (cond ((c-validp c) "<vld>")
+ ((c-unboundp c) "<unb>")
+ ((cd-stale-p c) "<obs>")
+ (t "<err>"))))
+
+(defmethod c-print-value (c stream)
+ (declare (ignore c stream)))
+
+;____________________ constructors _______________________________
+
+(defmacro c-lambda (&body body)
+ (let ((c (gensym)))
+ `(lambda (,c &aux (self (c-model ,c))
+ (.cache (c-value ,c)))
+ (declare (ignorable .cache self))
+ (c-assert (not (cmdead ,c)) "cell dead entering rule ~a" ,c)
+ ,@body)))
+
+(defmacro c? (&body body)
+ `(make-c-dependent
+ :code ',body
+ :rule (c-lambda ,@body)))
+
+(defmacro c?_ (&body body)
+ `(make-c-dependent
+ :code ',body
+ :lazy t
+ :rule (c-lambda ,@body)))
+
+(defmacro c?? ((&key (tagp nil) (in nil) (trigger nil) (out t))&body body)
+ (let ((result (copy-symbol 'result))
+ (thetag (gensym)))
+ `(make-c-dependent
+ :code ',body
+ :rule (c-lambda
+ (let ((,thetag (gensym "tag"))
+ (*trcdepth* (1+ *trcdepth*))
+ )
+ (declare (ignorable self ,thetag))
+ ,(when in
+ `(trc "c??> entry" (c-slot-name c) (c-model c) (when ,tagp ,thetag)))
+ ,(when trigger `(trc "c??> trigger" *cause* c))
+ (count-it :c?? (c-slot-name c) (md-name (c-model c)))
+ (let ((,result (progn ,@body)))
+ ,(when out `(trc "c?? result:" ,result (c-slot-name c) (when ,tagp ,thetag)))
+ ,result))))))
+
+(defmacro cv (defn)
+ `(make-c-variable
+ :value ,defn))
+
+(defmacro cv8 (defn)
+ `(make-c-variable
+ :cyclic-p t
+ :value ,defn))
+
+(defmacro c... ((value) &body body)
+ `(make-c-drifter
+ :code ',body
+ :value ,value
+ :rule (c-lambda ,@body)))
+
+(defmacro c-abs (value &body body)
+ `(make-c-drifter-absolute
+ :code ',body
+ :value ,value
+ :rule (c-lambda ,@body)))
+
+
+(defmacro c-envalue (&body body)
+ `(make-c-envaluer
+ :envaluerule (c-lambda ,@body)))
Index: cells/cells.asd
diff -u cells/cells.asd:1.1.1.1 cells/cells.asd:1.2
--- cells/cells.asd:1.1.1.1 Sat Nov 8 18:43:48 2003
+++ cells/cells.asd Tue Dec 16 10:02:58 2003
@@ -1,36 +1,36 @@
-;;;; -*- Mode: Lisp; Syntax: ANSI-Common-Lisp; Base: 10 -*-
-
-(declaim (optimize (debug 3) (speed 3) (safety 1) (compilation-speed 0)))
-
-#+(or allegro lispworks cmu mcl cormanlisp sbcl scl)
-
-(asdf:defsystem :cells
- :name "cells"
- :author "Kenny Tilton <ktilton(a)nyc.rr.com>"
- :version "05-Nov-2003"
- :maintainer "Kenny Tilton <ktilton(a)nyc.rr.com>"
- :licence "MIT Style"
- :description "Cells"
- :long-description "The Cells dataflow extension to CLOS."
- :components
- ((:file "cells")
- (:file "flow-control" :depends-on ("cells"))
- (:file "strings" :depends-on ("flow-control"))
- (:file "detritus" :depends-on ("flow-control"))
- (:file "cell-types" :depends-on ("cells"))
- (:file "debug" :depends-on ("cells"))
- (:file "initialize" :depends-on ("debug"))
- (:file "dataflow-management" :depends-on ("debug"))
- (:file "md-slot-value" :depends-on ("debug"))
- (:file "calc-n-set" :depends-on ("debug"))
- (:file "slot-utilities" :depends-on ("debug"))
- (:file "optimization" :depends-on ("debug"))
- (:file "link" :depends-on ("debug"))
- (:file "propagate" :depends-on ("debug"))
- (:file "synapse" :depends-on ("debug" "cell-types"))
- (:file "model-object" :depends-on ("debug"))
- (:file "defmodel" :depends-on ("model-object"))
- (:file "md-utilities" :depends-on ("defmodel"))
- (:file "family" :depends-on ("propagate" "model-object" "defmodel"))
- (:file "fm-utilities" :depends-on ("family"))
- (:file "family-values" :depends-on ("fm-utilities"))))
+;;;; -*- Mode: Lisp; Syntax: ANSI-Common-Lisp; Base: 10 -*-
+
+(declaim (optimize (debug 3) (speed 3) (safety 1) (compilation-speed 0)))
+
+#+(or allegro lispworks cmu mcl clisp cormanlisp sbcl scl)
+
+(asdf:defsystem :cells
+ :name "cells"
+ :author "Kenny Tilton <ktilton(a)nyc.rr.com>"
+ :version "05-Nov-2003"
+ :maintainer "Kenny Tilton <ktilton(a)nyc.rr.com>"
+ :licence "MIT Style"
+ :description "Cells"
+ :long-description "The Cells dataflow extension to CLOS."
+ :components
+ ((:file "cells")
+ (:file "flow-control" :depends-on ("cells"))
+ (:file "strings" :depends-on ("flow-control"))
+ (:file "detritus" :depends-on ("flow-control"))
+ (:file "cell-types" :depends-on ("cells"))
+ (:file "debug" :depends-on ("cells"))
+ (:file "initialize" :depends-on ("debug"))
+ (:file "dataflow-management" :depends-on ("debug"))
+ (:file "md-slot-value" :depends-on ("debug"))
+ (:file "calc-n-set" :depends-on ("debug"))
+ (:file "slot-utilities" :depends-on ("debug"))
+ (:file "optimization" :depends-on ("debug"))
+ (:file "link" :depends-on ("debug"))
+ (:file "propagate" :depends-on ("debug"))
+ (:file "synapse" :depends-on ("debug" "cell-types"))
+ (:file "model-object" :depends-on ("debug"))
+ (:file "defmodel" :depends-on ("model-object"))
+ (:file "md-utilities" :depends-on ("defmodel"))
+ (:file "family" :depends-on ("propagate" "model-object" "defmodel"))
+ (:file "fm-utilities" :depends-on ("family"))
+ (:file "family-values" :depends-on ("fm-utilities"))))
Index: cells/cells.lisp
diff -u cells/cells.lisp:1.2 cells/cells.lisp:1.3
--- cells/cells.lisp:1.2 Thu Nov 13 00:54:53 2003
+++ cells/cells.lisp Tue Dec 16 10:02:58 2003
@@ -1,111 +1,128 @@
-;; -*- mode: Lisp; Syntax: Common-Lisp; Package: cells; -*-
-;;;
-;;; Copyright © 1995,2003 by Kenneth William Tilton.
-;;;
-;;; Permission is hereby granted, free of charge, to any person obtaining a copy
-;;; of this software and associated documentation files (the "Software"), to deal
-;;; in the Software without restriction, including without limitation the rights
-;;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-;;; copies of the Software, and to permit persons to whom the Software is furnished
-;;; to do so, subject to the following conditions:
-;;;
-;;; The above copyright notice and this permission notice shall be included in
-;;; all copies or substantial portions of the Software.
-;;;
-;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-;;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-;;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-;;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-;;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-;;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-;;; IN THE SOFTWARE.
-
-(eval-when (compile load)
- (proclaim '(optimize (speed 2) (safety 1) (space 1) (debug 3))))
-
-(defpackage :cells
- (:use "COMMON-LISP"
- #+allegro "EXCL"
- #-(or cormanlisp cmu sbcl) "CLOS"
- #+sbcl "SB-MOP"
- #+mcl "CCL"
- )
- #+clisp (:import-from #:clos "CLASS-SLOTS" "CLASS-PRECEDENCE-LIST")
- #+cmu (:import-from "PCL" "CLASS-PRECEDENCE-LIST" "CLASS-SLOTS"
- "SLOT-DEFINITION-NAME")
- (:export "CELL" "CV" "C?" "C?_" "C??" "WITHOUT-C-DEPENDENCY" "SELF" "*SYNAPSE-FACTORY*"
- ".CACHE" "C-LAMBDA" ".CAUSE"
- "DEFMODEL" "CELLBRK" "C-AWAKEN" "DEF-C-ECHO" "DEF-C-UNCHANGED-TEST"
- "NEW-VALUE" "OLD-VALUE" "C..."
- "MKPART" "THEKIDS" "NSIB" "MDVALUE" "^MDVALUE" ".MDVALUE" "KIDS" "^KIDS" ".KIDS"
- "CELL-RESET" "UPPER" "FM-MAX" "NEAREST" "^FM-MIN-KID" "^FM-MAX-KID" "MK-KID-SLOT"
- "DEF-KID-SLOTS" "FIND-PRIOR" "FM-POS" "KIDNO" "FM-INCLUDES" "FM-ASCENDANT-COMMON"
- "FM-KID-CONTAINING" "FM-FIND-IF" "FM-ASCENDANT-IF" "C-ABS" "FM-COLLECT-IF" "CV8" "PSIB"
- "TO-BE" "NOT-TO-BE" "SSIBNO" "MD-AWAKEN"
- #:delta-diff
- )
- #+allegro (:shadowing-import-from #:excl #:fasl-write #:fasl-read #:gc)
- )
-
-(in-package :cells)
-
-(defconstant *c-optimizep* t)
-(defvar *c-prop-depth* 0)
-(defvar *cause* nil)
-(defvar *rethink-deferred* nil)
-(defvar *synapse-factory* nil)
-(defvar *sw-looping* nil)
-(defparameter *to-be-awakened* nil)
-(defvar *trcdepth* 0)
-
-(defparameter *c-debug*
- #+runtime-system nil
- #-runtime-system t)
-
-(defvar *stop* nil)
-
-(defun stop ()
- (setf *stop* t))
-
-(defvar *c-calculators* nil)
-
-(defmacro ssibno () `(position self (^kids .parent)))
-
-(defmacro gpar ()
- `(fm-grandparent self))
-
-(defmacro nearest (selfform type)
- (let ((self (gensym)))
- `(bwhen (,self ,selfform)
- (if (typep ,self ',type) ,self (upper ,self ,type)))))
-
-(defmacro def-c-trace (model-type &optional slot cell-type)
- `(defmethod trcp ((self ,(case cell-type
- (:c? 'c-dependent)
- (otherwise 'cell))))
- (and (typep (c-model self) ',model-type)
- ,(if slot
- `(eq (c-slot-name self) ',slot)
- `t))))
-
-(defmacro with-dataflow-management ((c-originating) &body body)
- (let ((fn (gensym)))
- `(let ((,fn (lambda () ,@body)))
- (declare (dynamic-extent ,fn))
- (call-with-dataflow-management ,c-originating ,fn))))
-
-(defmacro without-c-dependency (&body body)
- `(let (*c-calculators*) ,@body))
-
-(defmacro without-propagating ((slotname objxpr) &body body)
- (let ((c (gensym))
- (c-delta (gensym)))
- `(let ((,c (slot-value ,objxpr ',slotname)))
- (push (cons ,c nil) *c-noprop*)
- (progn ,@body)
- (let ((,c-delta (assoc ,c *c-noprop*)))
- (assert ,c-delta)
- (setf *c-noprop* (delete ,c-delta *c-noprop*))
- (when (cdr ,c-delta) ;; if changed, will be set to /list/ containing priorvalue
- (,c (cadr ,c-delta) (caddr ,c-delta)))))))
-
+;; -*- mode: Lisp; Syntax: Common-Lisp; Package: cells; -*-
+;;;
+;;; Copyright (c) 1995,2003 by Kenneth William Tilton.
+;;;
+;;; Permission is hereby granted, free of charge, to any person obtaining a copy
+;;; of this software and associated documentation files (the "Software"), to deal
+;;; in the Software without restriction, including without limitation the rights
+;;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+;;; copies of the Software, and to permit persons to whom the Software is furnished
+;;; to do so, subject to the following conditions:
+;;;
+;;; The above copyright notice and this permission notice shall be included in
+;;; all copies or substantial portions of the Software.
+;;;
+;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+;;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+;;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+;;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+;;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+;;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+;;; IN THE SOFTWARE.
+
+(eval-when (compile load)
+ (proclaim '(optimize (speed 2) (safety 3) (space 1) (debug 3))))
+
+(defpackage :cells
+ (:use "COMMON-LISP"
+ #+allegro "EXCL"
+ #-(or cormanlisp cmu sbcl) "CLOS"
+ #+sbcl "SB-MOP"
+ #+mcl "CCL"
+ )
+ #+clisp (:import-from #:clos "CLASS-SLOTS" "CLASS-PRECEDENCE-LIST")
+ #+cmu (:import-from "PCL" "CLASS-PRECEDENCE-LIST" "CLASS-SLOTS"
+ "SLOT-DEFINITION-NAME" "TRUE")
+ (:export "CELL" "CV" "C?" "C?_" "C??" "WITHOUT-C-DEPENDENCY" "SELF" "*SYNAPSE-FACTORY*"
+ ".CACHE" "C-LAMBDA" ".CAUSE"
+ "DEFMODEL" "CELLBRK" "C-AWAKEN" "DEF-C-ECHO" "DEF-C-UNCHANGED-TEST"
+ "NEW-VALUE" "OLD-VALUE" "C..."
+ "MKPART" "THEKIDS" "NSIB" "MD-VALUE" "^MD-VALUE" ".MD-VALUE" "KIDS" "^KIDS" ".KIDS"
+ "CELL-RESET" "UPPER" "FM-MAX" "NEAREST" "^FM-MIN-KID" "^FM-MAX-KID" "MK-KID-SLOT"
+ "DEF-KID-SLOTS" "FIND-PRIOR" "FM-POS" "KID-NO" "FM-INCLUDES" "FM-ASCENDANT-COMMON"
+ "FM-KID-CONTAINING" "FM-FIND-IF" "FM-ASCENDANT-IF" "C-ABS" "FM-COLLECT-IF" "CV8" "PSIB"
+ "TO-BE" "NOT-TO-BE" "SSIBNO" "MD-AWAKEN"
+ "C-BREAK" "C-ASSERT" "C-STOP" "C-STOPPED" "C-ASSERT"
+ #:delta-diff
+ )
+ #+allegro (:shadowing-import-from #:excl #:fasl-write #:fasl-read #:gc)
+ )
+
+(in-package :cells)
+
+(defconstant *c-optimizep* t)
+(defvar *c-prop-depth* 0)
+(defvar *cause* nil)
+(defvar *rethink-deferred* nil)
+(defvar *synapse-factory* nil)
+(defvar *sw-looping* nil)
+(defparameter *to-be-awakened* nil)
+(defvar *trcdepth* 0)
+
+(defparameter *c-debug*
+ #+runtime-system nil
+ #-runtime-system t)
+
+(defvar *stop* nil)
+
+(defun c-stop (why)
+ (format t "~&C-STOP> stopping because ~a" why)
+ (setf *stop* t))
+
+(defun c-stopped ()
+ *stop*)
+
+(defmacro c-assert (assertion &optional places fmt$ &rest fmtargs)
+ (declare (ignore places))
+
+ `(unless *stop*
+ (unless ,assertion
+ (setf *stop* t)
+ ,(if fmt$
+ `(c-break ,fmt$ ,@fmtargs)
+ `(c-break "failed assertion:" ',assertion)))))
+
+(defvar *c-calculators* nil)
+
+(defmacro ssibno () `(position self (^kids .parent)))
+
+(defmacro gpar ()
+ `(fm-grandparent self))
+
+(defmacro nearest (selfform type)
+ (let ((self (gensym)))
+ `(bwhen (,self ,selfform)
+ (if (typep ,self ',type) ,self (upper ,self ,type)))))
+
+(defmacro def-c-trace (model-type &optional slot cell-type)
+ `(defmethod trcp ((self ,(case cell-type
+ (:c? 'c-dependent)
+ (otherwise 'cell))))
+ (and (typep (c-model self) ',model-type)
+ ,(if slot
+ `(eq (c-slot-name self) ',slot)
+ `t))))
+
+(defmacro with-dataflow-management ((c-originating) &body body)
+ (let ((fn (gensym)))
+ `(let ((,fn (lambda () ,@body)))
+ (declare (dynamic-extent ,fn))
+ (call-with-dataflow-management ,c-originating ,fn))))
+
+(defmacro without-c-dependency (&body body)
+ `(let (*c-calculators*) ,@body))
+
+(defmacro without-propagating ((slotname objxpr) &body body)
+ (let ((c (gensym))
+ (c-delta (gensym)))
+ `(let ((,c (slot-value ,objxpr ',slotname)))
+ (push (cons ,c nil) *c-noprop*)
+ (progn ,@body)
+ (let ((,c-delta (assoc ,c *c-noprop*)))
+ (c-assert ,c-delta)
+ (setf *c-noprop* (delete ,c-delta *c-noprop*))
+ (when (cdr ,c-delta) ;; if changed, will be set to /list/ containing priorvalue
+ (,c (cadr ,c-delta) (caddr ,c-delta)))))))
+
+(define-symbol-macro .cause
+ *cause*)
Index: cells/dataflow-management.lisp
diff -u cells/dataflow-management.lisp:1.1.1.1 cells/dataflow-management.lisp:1.2
--- cells/dataflow-management.lisp:1.1.1.1 Sat Nov 8 18:44:00 2003
+++ cells/dataflow-management.lisp Tue Dec 16 10:02:58 2003
@@ -1,223 +1,229 @@
-;; -*- mode: Lisp; Syntax: Common-Lisp; Package: cells; -*-
-;;;
-;;; Copyright © 1995,2003 by Kenneth William Tilton.
-;;;
-;;; Permission is hereby granted, free of charge, to any person obtaining a copy
-;;; of this software and associated documentation files (the "Software"), to deal
-;;; in the Software without restriction, including without limitation the rights
-;;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-;;; copies of the Software, and to permit persons to whom the Software is furnished
-;;; to do so, subject to the following conditions:
-;;;
-;;; The above copyright notice and this permission notice shall be included in
-;;; all copies or substantial portions of the Software.
-;;;
-;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-;;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-;;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-;;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-;;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-;;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-;;; IN THE SOFTWARE.
-
-(in-package :cells)
-
-(defparameter *df-interference-detection* t)
-
-(eval-when (compile eval load)
- (export '(*df-interference-detection*)))
-
-(defmethod sw-detect-interference (user trigger)
- (declare (ignorable trigger))
- (when #+runtime-system t #-runtime-system *df-interference-detection*
- (trc nil "detect entry" user (cd-useds user))
- (dolist (used (cd-useds user))
- (do ((deep-stale (cd-deep-stale used)(cd-deep-stale used)))
- ((null deep-stale))
- ;;(trc nil "sw-detect-interference trying deep stale" deep-stale)
- (c-rethink deep-stale)
- (cond
- ((c-true-stalep deep-stale)
- (trc "!! true deep stalep: user>" user)
- (trc "!! true deep stalep: used>" used)
- (trc "!! true deep stalep: deepstale>" deep-stale)
- (return-from sw-detect-interference deep-stale #+debugging (list user used deep-stale)))
-
- ((not (c-true-stalep user))
- (return-from sw-detect-interference nil)))))))
-
-(defmethod sw-detect-interference ((user c-variable) trigger)
- (declare (ignore trigger)))
-
-(defmethod sw-detect-interference ((user synapse) trigger)
- (sw-detect-interference (syn-used user) trigger))
-
-(defmethod cd-deep-stale ((c c-dependent))
- (trc nil "cd-deep-stale entry" c)
- (if (cd-stale-p c)
- c ;; (eko ("deep stalep bingo !!!!!!") c)
- (some #'cd-deep-stale (cd-useds c))))
-
-(defmethod cd-deep-stale ((syn synapse))
- (cd-deep-stale (syn-used syn)))
-
-(defmethod cd-deep-stale (c)
- (declare (ignore c)))
-
-(defparameter *sw-pending* nil)
-(defparameter *dataflowing* nil)
-
-(defun dump-pending ()
- (dotimes (x (length *sw-pending*))
- (let ((p (nth x *sw-pending*)))
- (destructuring-bind (heldup . holdup) p
- (declare (ignorable holdup))
- (trc heldup " pending!!!!!!!!!!" p)
- )))
- )
-
-;; mo better diags: holdup (c-true-stalep holdup) heldup (c-true-stalep heldup))))))
-
-(defun call-with-dataflow-management (c-originating bodyfn)
- (declare (ignorable c-originating))
- (if *dataflowing*
- (funcall bodyfn)
- (let ((*dataflowing* t)
- *sw-pending*)
- #+dfdbg (trc nil ">>>>> with-dataflow-management: 001" c-originating)
- (setf (unst-setting-p c-originating) t)
- (prog1
- (funcall bodyfn)
-
- (while (and *sw-pending*
- (not *sw-looping*))
-
- #+dfdbg
- (progn
- (trc nil "we have pending!!!!!!!!!!" (length *sw-pending*))
- (dump-pending))
-
- (let ((pct (length *sw-pending*))
- (oldpending (copy-list *sw-pending*)))
- ;;(trace c-rethink)
- (labels ((do-last (pending)
- (when pending
- (do-last (cdr pending))
- ;;(trace c-rethink cd-deep-stale sw-detect-interference)
- (destructuring-bind (heldup . holdup) (car pending)
- (trc heldup "pending sweep sees held up" heldup :holdup holdup)
- (assert (find heldup (cells (c-model heldup)) :key #'cdr))
- (assert (find holdup (cells (c-model holdup)) :key #'cdr))
- ;; (unless (c-true-stalep holdup)
- ;; (trc nil "dataflow sees freed blocker" holdup))
- (if (c-true-stalep holdup)
- (if (eq :eternal-rest (md-state (c-model holdup)))
- (progn (trc "holdup is no more!!!!!!!" holdup (c-true-stalep heldup) heldup))
- (progn
- (trc holdup "dataflow retrying blocker" holdup)
- (c-rethink holdup)))
- (progn
- (trc heldup "holdup not stale!!!" holdup :heldup> heldup)
- (c-pending-set heldup nil :holdup-unstale) ))
- ;;(unless (c-true-stalep heldup)
- ;; (trc nil "dataflow sees freed blocked" heldup))
- (when (c-true-stalep heldup)
- (trc heldup "dataflow retrying blocked" heldup)
- (c-rethink heldup))))))
- ;; (trace c-rethink cd-deep-stale sw-detect-interference)
- (do-last *sw-pending*)
- ;; (trc "post sweep pending leftovers:" (length *sw-pending*))
- ;; (untrace c-rethink cd-deep-stale sw-detect-interference)
- )
- ;;(untrace c-rethink)
- (when (and (equal oldpending *sw-pending*)
- (eql pct (length *sw-pending*))
- (not *sw-looping*))
- (setf *sw-looping* t)
- #+nah (dolist (p *sw-pending*)
- (destructuring-bind (heldup . holdup) p
- (dump-dependency-path holdup heldup)))
- #+nah (dolist (p *sw-pending*)
- (destructuring-bind (heldup . holdup) p
- (declare (ignorable heldup))
- (when t ;; (trcp holdup)
- (dump-stale-path holdup))))
- (break "trigger ~a stuck; cant lose pendings ~a"
- c-originating
- *sw-pending*))
-
- ;; (trc "after sweep sw-pending" *sw-pending*)
- ;; (cellbrk)
- (when c-originating
- (setf (unst-setting-p c-originating) nil))))
- (trc nil "<<<< with-dataflow-management:" c-originating)))))
-
-(defun dump-stale-path (used)
- (assert used)
- (when (typep used 'c-dependent)
- (loop with any
- for used-used in (cd-useds used)
- when (dump-stale-path used-used)
- do (progn
- (setf any t)
- (trc "stale-path" used :uses... used-used))
- finally
- (when (or any (cd-stale-p used))
- (trc "stale" used)
- (return any)))))
-
-(defun dump-dependency-path (used user)
- (assert (and used user))
- (if (eql used user)
- (progn
- (trc "bingo---------------")
- (trc "user" user :uses...)
- t)
- (let (any)
- (dolist (used-user (cd-users used) any)
- (when (dump-dependency-path used-user user)
- (setf any t)
- (trc "user" used-user :uses... used))))))
-
-(defun c-pending-set (c newvalue debug-tag)
- (declare (ignorable debug-tag))
- (assert (find c (cells (c-model c)) :key #'cdr))
- (when newvalue (trc nil "still pending!!!!!!!!!!!!!!!!!!" c newvalue debug-tag))
- (if newvalue
- (bif (known (assoc c *sw-pending*))
- (cond
- ((eq newvalue (cdr known))
- (break "hunh? re-pending ~a on same holdup ~a?" c (cdr known)))
- ((c-true-stalep (cdr known))
- (break "hunh? pending ~a on second holdup ~a as well as ~a?" c newvalue (cdr known)))
- (t
- (trc nil "re-pending ~a on new holdup ~a, last ok: ~a" c newvalue (assoc c *sw-pending*))
- (rplacd known newvalue))) ;; risky business, might need whole new assoc entry
- (let ((newpending (cons c newvalue)))
- (progn
- (assert (typep c 'c-dependent))
- (assert (not (eq :eternal-rest (md-state (c-model c)))))
- ;;(trc nil "pending on, genealogy holdup: held, holder:" debug-tag c newvalue)
- ;;(dump-pending)
- )
- ;;; hunh?> (pushnew newpending *sw-pending* :test #'equal)
- (push newpending *sw-pending*)))
- (bwhen (p (assoc c *sw-pending*))
- (trc nil "clear from sw-pending" debug-tag c (remove-if (lambda (p)
- (not (eql c (car p))))
- *sw-pending*))
- (setf *sw-pending* (delete (assoc c *sw-pending*) *sw-pending*))
- (progn
- (trc nil "pending off, genealogy holdup: held, holder:" debug-tag p
- (count c *sw-pending* :key #'car))
- (dump-pending))
- ))
- newvalue)
-
-(defmethod sw-pending ((c cell))
- (assoc c *sw-pending*))
-
-(defmethod sw-pending ((s synapse))
- (sw-pending (syn-used s)))
-
-
+;; -*- mode: Lisp; Syntax: Common-Lisp; Package: cells; -*-
+;;;
+;;; Copyright (c) 1995,2003 by Kenneth William Tilton.
+;;;
+;;; Permission is hereby granted, free of charge, to any person obtaining a copy
+;;; of this software and associated documentation files (the "Software"), to deal
+;;; in the Software without restriction, including without limitation the rights
+;;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+;;; copies of the Software, and to permit persons to whom the Software is furnished
+;;; to do so, subject to the following conditions:
+;;;
+;;; The above copyright notice and this permission notice shall be included in
+;;; all copies or substantial portions of the Software.
+;;;
+;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+;;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+;;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+;;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+;;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+;;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+;;; IN THE SOFTWARE.
+
+(in-package :cells)
+
+(defparameter *df-interference-detection* t)
+
+(eval-when (compile eval load)
+ (export '(*df-interference-detection*)))
+
+(defmethod sw-detect-interference (user trigger)
+ (declare (ignorable trigger))
+ (when #+runtime-system t #-runtime-system *df-interference-detection*
+ (trc nil "detect entry" user (cd-useds user))
+ (dolist (used (cd-useds user))
+ (do ((deep-stale (cd-deep-stale used)(cd-deep-stale used)))
+ ((null deep-stale))
+ ;;(trc nil "sw-detect-interference trying deep stale" deep-stale)
+ (c-rethink deep-stale)
+ (cond
+ ((c-true-stalep deep-stale)
+ (trc "!! true deep stalep: user>" user)
+ (trc "!! true deep stalep: used>" used)
+ (trc "!! true deep stalep: deepstale>" deep-stale)
+ (return-from sw-detect-interference deep-stale #+debugging (list user used deep-stale)))
+
+ ((not (c-true-stalep user))
+ (return-from sw-detect-interference nil)))))))
+
+(defmethod sw-detect-interference ((user c-variable) trigger)
+ (declare (ignore trigger)))
+
+(defmethod sw-detect-interference ((user synapse) trigger)
+ (sw-detect-interference (syn-used user) trigger))
+
+(defmethod cd-deep-stale ((c c-dependent))
+ (trc nil "cd-deep-stale entry" c)
+ (if (cd-stale-p c)
+ c ;; (eko ("deep stalep bingo !!!!!!") c)
+ (some #'cd-deep-stale (cd-useds c))))
+
+(defmethod cd-deep-stale ((syn synapse))
+ (cd-deep-stale (syn-used syn)))
+
+(defmethod cd-deep-stale (c)
+ (declare (ignore c)))
+
+(defparameter *sw-pending* nil)
+(defparameter *dataflowing* nil)
+
+(defun dump-pending ()
+ (dotimes (x (length *sw-pending*))
+ (let ((p (nth x *sw-pending*)))
+ (destructuring-bind (heldup . holdup) p
+ (declare (ignorable holdup))
+ (trc heldup " pending!!!!!!!!!!" p)
+ )))
+ )
+
+;; mo better diags: holdup (c-true-stalep holdup) heldup (c-true-stalep heldup))))))
+
+(defun call-with-dataflow-management (c-originating bodyfn)
+ (declare (ignorable c-originating))
+ (if *dataflowing*
+ (progn
+ (setf (cv-setting-p c-originating) t)
+ (prog1
+ (funcall bodyfn)
+ (setf (cv-setting-p c-originating) nil)))
+
+ (let ((*dataflowing* t)
+ *sw-pending*)
+ #+dfdbg (trc nil ">>>>> with-dataflow-management: 001" c-originating)
+ (setf (cv-setting-p c-originating) t)
+ (prog1
+ (funcall bodyfn)
+
+ (while (and *sw-pending*
+ (not *sw-looping*))
+
+ #+dfdbg
+ (progn
+ (trc nil "we have pending!!!!!!!!!!" (length *sw-pending*))
+ (dump-pending))
+
+ (let ((pct (length *sw-pending*))
+ (oldpending (copy-list *sw-pending*)))
+ ;;(trace c-rethink)
+ (labels ((do-last (pending)
+ (when pending
+ (do-last (cdr pending))
+ ;;(trace c-rethink cd-deep-stale sw-detect-interference)
+ (destructuring-bind (heldup . holdup) (car pending)
+ (trc heldup "pending sweep sees held up" heldup :holdup holdup)
+ (c-assert (find heldup (cells (c-model heldup)) :key #'cdr))
+ (c-assert (find holdup (cells (c-model holdup)) :key #'cdr))
+ ;; (unless (c-true-stalep holdup)
+ ;; (trc nil "dataflow sees freed blocker" holdup))
+ (if (c-true-stalep holdup)
+ (if (eq :eternal-rest (md-state (c-model holdup)))
+ (progn (trc "holdup is no more!!!!!!!" holdup (c-true-stalep heldup) heldup))
+ (progn
+ (trc holdup "dataflow retrying blocker" holdup)
+ (c-rethink holdup)))
+ (progn
+ (trc heldup "holdup not stale!!!" holdup :heldup> heldup)
+ (c-pending-set heldup nil :holdup-unstale) ))
+ ;;(unless (c-true-stalep heldup)
+ ;; (trc nil "dataflow sees freed blocked" heldup))
+ (when (c-true-stalep heldup)
+ (trc heldup "dataflow retrying blocked" heldup)
+ (c-rethink heldup))))))
+ ;; (trace c-rethink cd-deep-stale sw-detect-interference)
+ (do-last *sw-pending*)
+ ;; (trc "post sweep pending leftovers:" (length *sw-pending*))
+ ;; (untrace c-rethink cd-deep-stale sw-detect-interference)
+ )
+ ;;(untrace c-rethink)
+ (when (and (equal oldpending *sw-pending*)
+ (eql pct (length *sw-pending*))
+ (not *sw-looping*))
+ (setf *sw-looping* t)
+ #+nah (dolist (p *sw-pending*)
+ (destructuring-bind (heldup . holdup) p
+ (dump-dependency-path holdup heldup)))
+ #+nah (dolist (p *sw-pending*)
+ (destructuring-bind (heldup . holdup) p
+ (declare (ignorable heldup))
+ (when t ;; (trcp holdup)
+ (dump-stale-path holdup))))
+ (break "trigger ~a stuck; cant lose pendings ~a"
+ c-originating
+ *sw-pending*))
+
+ ;; (trc "after sweep sw-pending" *sw-pending*)
+ ;; (cellbrk)
+ ))
+ (when c-originating
+ (setf (cv-setting-p c-originating) nil))
+ (trc nil "<<<< with-dataflow-management:" c-originating)))))
+
+(defun dump-stale-path (used)
+ (c-assert used)
+ (when (typep used 'c-dependent)
+ (loop with any
+ for used-used in (cd-useds used)
+ when (dump-stale-path used-used)
+ do (progn
+ (setf any t)
+ (trc "stale-path" used :uses... used-used))
+ finally
+ (when (or any (cd-stale-p used))
+ (trc "stale" used)
+ (return any)))))
+
+(defun dump-dependency-path (used user)
+ (c-assert (and used user))
+ (if (eql used user)
+ (progn
+ (trc "bingo---------------")
+ (trc "user" user :uses...)
+ t)
+ (let (any)
+ (dolist (used-user (cd-users used) any)
+ (when (dump-dependency-path used-user user)
+ (setf any t)
+ (trc "user" used-user :uses... used))))))
+
+(defun c-pending-set (c newvalue debug-tag)
+ (declare (ignorable debug-tag))
+ (c-assert (find c (cells (c-model c)) :key #'cdr))
+ (when newvalue (trc nil "still pending!!!!!!!!!!!!!!!!!!" c newvalue debug-tag))
+ (if newvalue
+ (bif (known (assoc c *sw-pending*))
+ (cond
+ ((eq newvalue (cdr known))
+ (break "hunh? re-pending ~a on same holdup ~a?" c (cdr known)))
+ ((c-true-stalep (cdr known))
+ (break "hunh? pending ~a on second holdup ~a as well as ~a?" c newvalue (cdr known)))
+ (t
+ (trc nil "re-pending ~a on new holdup ~a, last ok: ~a" c newvalue (assoc c *sw-pending*))
+ (rplacd known newvalue))) ;; risky business, might need whole new assoc entry
+ (let ((newpending (cons c newvalue)))
+ (progn
+ (c-assert (typep c 'c-dependent))
+ (c-assert (not (eq :eternal-rest (md-state (c-model c)))))
+ ;;(trc nil "pending on, genealogy holdup: held, holder:" debug-tag c newvalue)
+ ;;(dump-pending)
+ )
+ ;;; hunh?> (pushnew newpending *sw-pending* :test #'equal)
+ (push newpending *sw-pending*)))
+ (bwhen (p (assoc c *sw-pending*))
+ (trc nil "clear from sw-pending" debug-tag c (remove-if (lambda (p)
+ (not (eql c (car p))))
+ *sw-pending*))
+ (setf *sw-pending* (delete (assoc c *sw-pending*) *sw-pending*))
+ (progn
+ (trc nil "pending off, genealogy holdup: held, holder:" debug-tag p
+ (count c *sw-pending* :key #'car))
+ (dump-pending))
+ ))
+ newvalue)
+
+(defmethod sw-pending ((c cell))
+ (assoc c *sw-pending*))
+
+(defmethod sw-pending ((s synapse))
+ (sw-pending (syn-used s)))
+
+
Index: cells/debug.lisp
diff -u cells/debug.lisp:1.1.1.1 cells/debug.lisp:1.2
--- cells/debug.lisp:1.1.1.1 Sat Nov 8 18:44:00 2003
+++ cells/debug.lisp Tue Dec 16 10:02:58 2003
@@ -1,268 +1,263 @@
-;; -*- mode: Lisp; Syntax: Common-Lisp; Package: cells; -*-
-;;;
-;;; Copyright © 1995,2003 by Kenneth William Tilton.
-;;;
-;;; Permission is hereby granted, free of charge, to any person obtaining a copy
-;;; of this software and associated documentation files (the "Software"), to deal
-;;; in the Software without restriction, including without limitation the rights
-;;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-;;; copies of the Software, and to permit persons to whom the Software is furnished
-;;; to do so, subject to the following conditions:
-;;;
-;;; The above copyright notice and this permission notice shall be included in
-;;; all copies or substantial portions of the Software.
-;;;
-;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-;;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-;;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-;;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-;;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-;;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-;;; IN THE SOFTWARE.
-
-(in-package :cells)
-
-(defun cellstop ()
- ;; (break "in-cell-stop")
- (setf *stop* t))
-
-(defun cellbrk (&optional (tag :anon))
- (unless (or *stop*)
- ;; daring move, hoping having handler at outside stops the game (cellstop)
- (print `(cell break , tag))
- (break)))
-
-;----------- trc -------------------------------------------
-
-(defun trcdepth-reset ()
- (setf *trcdepth* 0))
-
-(defmacro trc (tgtform &rest os)
- (if (eql tgtform 'nil)
- '(progn)
- (if (stringp tgtform)
- `(without-c-dependency
- (call-trc t ,tgtform ,@os))
- (let ((tgt (gensym)))
- `(without-c-dependency
- (bif (,tgt ,tgtform)
- (if (trcp ,tgt)
- (progn
- (assert (stringp ,(car os)))
- (call-trc t ,@os)) ;;,(car os) ,tgt ,@(cdr os)))
- (progn
- (break)
- (count-it :trcfailed)))
- (count-it :tgtnileval)))))))
-
-(defun call-trc (stream s &rest os)
- (if #+cormanlisp nil #-cormanlisp (and (boundp '*trcdepth*)
- *trcdepth*)
- (format stream "~&~v,,,'.<~d~>> " (mod *trcdepth* 100) *trcdepth*)
- (format stream "~&"))
-
- (format stream "~a" s)
- (let (pkwp)
- (dolist (o os)
- (format stream (if pkwp " ~s" " | ~s") o)
- (setf pkwp (keywordp o))))
- (values))
-
-(defun call-trc-to-string (fmt$ &rest fmtargs)
- (let ((o$ (make-array '(0) :element-type 'base-char
- :fill-pointer 0 :adjustable t)))
- (with-output-to-string (ostream o$)
- (apply 'call-trc ostream fmt$ fmtargs))
- o$))
-
-#+findtrcevalnils
-(defmethod trcp :around (other)
- (unless (call-next-method other)(break)))
-
-(defmethod trcp (other)
- (eq other t))
-
-(defmethod trcp (($ string))
- t)
-
-(defun trcdepth-incf ()
- (incf *trcdepth*))
-
-(defun trcdepth-decf ()
- (format t "decrementing trc depth" *trcdepth*)
- (decf *trcdepth*))
-
-(defmacro wtrc ((&optional (min 1) (max 50) &rest banner) &body body )
- `(let ((*trcdepth* (if *trcdepth*
- (1+ *trcdepth*)
- 0)))
- ,(when banner `(when (>= *trcdepth* ,min)
- (if (< *trcdepth* ,max)
- (trc ,@banner)
- (progn
- (break "excess trace notttt!!! ~d" *trcdepth*) ;; ,@banner)
- nil))))
- (when (< *trcdepth* ,max)
- ,@body)))
-
-(defmacro wnotrc ((&optional (min 1) (max 50) &rest banner) &body body )
- (declare (ignore min max banner))
- `(progn ,@body))
-
-;------ eko --------------------------------------
-
-
-(defmacro eko ((&rest trcargs) &rest body)
- (let ((result (gensym)))
- `(let ((,result ,@body))
- (trc ,(car trcargs) :=> ,result ,@(cdr trcargs))
- ,result)))
-
-(defmacro ek (label &rest body)
- (let ((result (gensym)))
- `(let ((,result (,@body)))
- (when ,label
- (trc ,label ,result))
- ,result)))
-
-;------------- counting ---------------------------
-(defvar *count* nil)
-(defvar *counting* nil)
-
-(defmacro with-counts ((onp &rest msg) &body body)
- `(if ,onp
- (prog2
- (progn
- (count-clear ,@msg)
- (push t *counting*))
- (progn ,@body)
- (pop *counting*)
- (show-count t ,@msg))
- (progn ,@body)))
-
-(defun count-clear (&rest msg)
- (declare (ignorable msg))
- (format t "~&count-clear > ~a" msg)
- (setf *count* nil))
-
-(defmacro count-it (&rest keys)
- `(when *counting*
- (call-count-it ,@keys)))
-
-(defun call-count-it (&rest keys)
- (declare (ignorable keys))
- ;;; (when (eql :TGTNILEVAL (car keys))(break))
- (let ((entry (assoc keys *count* :test #'equal)))
- (if entry
- (setf (cdr entry) (1+ (cdr entry)))
- (push (cons keys 1) *count*))))
-
-(defun show-count (clearp &rest msg)
- (format t "~&Counts after: clearp ~a, length ~d: ~s" clearp (length *count*) msg)
- (let ((res (sort (copy-list *count*) (lambda (v1 v2)
- (let ((v1$ (symbol-name (caar v1)))
- (v2$ (symbol-name (caar v2))))
- (if (string= v1$ v2$)
- (< (cdr v1) (cdr v2))
- (string< v1$ v2$))))))
- )
- (loop for entry in res
- for occs = (cdr entry)
- when (plusp occs)
- sum occs into running
- and do (format t "~&~4d ... ~2d ... ~s" running occs (car entry))))
- (when clearp (count-clear "show-count")))
-
-#+test
-(loop for entry in '((a . 10)(b . 5)(c . 0)(e . -20)(d . 2))
- for occs = (cdr entry)
- when (plusp occs)
- sum occs into running
- and do (print (list entry occs running)))
-
-
-;-------------------- timex ---------------------------------
-
-;;;(defmacro timex ((onp &rest trcArgs) &body body)
-;;; `(if ,onp
-;;; (prog1
-;;; (time
-;;; (progn ,@body))
-;;; (trc "timing was of" ,@trcARgs))
-;;; (progn ,@body)))
-
-
-;---------------- Metrics -------------------
-
-(defmacro with-metrics ((countp timep &rest trcargs) &body body)
- `(with-counts (,countp ,@trcargs)
- (timex (,timep ,@trcargs)
- ,@body)))
-
-
-; -------- cell conditions (not much used) ---------------------------------------------
-
-(define-condition xcell () ;; new 2k0227
- ((cell :initarg :cell :reader cell :initform nil)
- (appfunc :initarg :appfunc :reader appfunc :initform 'badcell)
- (errortext :initarg :errortext :reader errortext :initform "<???>")
- (otherdata :initarg :otherdata :reader otherdata :initform "<nootherdata>"))
- (:report (lambda (c s)
- (format s "~& trouble with cell ~a in function ~s,~s: ~s"
- (cell c) (appfunc c) (errortext c) (otherdata c)))))
-
-(define-condition c-enabling ()
- ((name :initarg :name :reader name)
- (model :initarg :model :reader model)
- (cell :initarg :cell :reader cell))
- (:report (lambda (condition stream)
- (format stream "~&unhandled <c-enabling>: ~s" condition)
- (break "~&i say, unhandled <c-enabling>: ~s" condition))))
-
-(define-condition c-fatal (xcell)
- ((name :initarg :name :reader name)
- (model :initarg :model :reader model)
- (cell :initarg :cell :reader cell))
- (:report (lambda (condition stream)
- (format stream "~&fatal cell programming error: ~s" condition)
- (format stream "~& : ~s" (name condition))
- (format stream "~& : ~s" (model condition))
- (format stream "~& : ~s" (cell condition)))))
-
-(define-condition c-unadopted (c-fatal)
- ()
- (:report
- (lambda (condition stream)
- (format stream "~&unadopted cell >: ~s" (cell condition))
- (format stream "~& >: often you mis-edit (c? (c? ...)) nesting is error"))))
-
-
-;----------------------------- link debugging -----------------------
-
-
-(defun dump-users (c &optional (depth 0))
- (format t "~&~v,4t~s" depth c)
- (dolist (user (un-users c))
- (dump-users user (+ 1 depth))))
-
-(defun dump-useds (c &optional (depth 0))
- ;(c.trc "dump-useds> entry " c (+ 1 depth))
- (when (zerop depth)
- (format t "x~&"))
- (format t "~&|usd> ~v,8t~s" depth c)
- (when (typep c 'c-ruled)
- ;(c.trc "its ruled" c)
- (dolist (used (cd-useds c))
- (dump-useds used (+ 1 depth)))))
-
-
-(defun cell-reset ()
- (setf *count* nil
- *stop* nil
- *dbg* nil
- *mybreak* nil
- *c-prop-depth* 0
- *sw-looping* nil
- *to-be-awakened* nil
- *trcdepth* 0))
-
+;; -*- mode: Lisp; Syntax: Common-Lisp; Package: cells; -*-
+;;;
+;;; Copyright (c) 1995,2003 by Kenneth William Tilton.
+;;;
+;;; Permission is hereby granted, free of charge, to any person obtaining a copy
+;;; of this software and associated documentation files (the "Software"), to deal
+;;; in the Software without restriction, including without limitation the rights
+;;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+;;; copies of the Software, and to permit persons to whom the Software is furnished
+;;; to do so, subject to the following conditions:
+;;;
+;;; The above copyright notice and this permission notice shall be included in
+;;; all copies or substantial portions of the Software.
+;;;
+;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+;;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+;;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+;;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+;;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+;;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+;;; IN THE SOFTWARE.
+
+(in-package :cells)
+
+(defun cellbrk (&optional (tag :anon))
+ (unless (or (c-stopped))
+ ;; daring move, hoping having handler at outside stops the game (cellstop)
+ (print `(cell break , tag))
+ (break)))
+
+;----------- trc -------------------------------------------
+
+(defun trcdepth-reset ()
+ (setf *trcdepth* 0))
+
+(defmacro trc (tgtform &rest os)
+ (if (eql tgtform 'nil)
+ '(progn)
+ (if (stringp tgtform)
+ `(without-c-dependency
+ (call-trc t ,tgtform ,@os))
+ (let ((tgt (gensym)))
+ `(without-c-dependency
+ (bif (,tgt ,tgtform)
+ (if (trcp ,tgt)
+ (progn
+ (c-assert (stringp ,(car os)))
+ (call-trc t ,@os)) ;;,(car os) ,tgt ,@(cdr os)))
+ (progn
+ ;;; (break)
+ (count-it :trcfailed)))
+ (count-it :tgtnileval)))))))
+
+(defun call-trc (stream s &rest os)
+ (if #+cormanlisp nil #-cormanlisp (and (boundp '*trcdepth*)
+ *trcdepth*)
+ (format stream "~&~v,,,'.<~d~>> " (mod *trcdepth* 100) *trcdepth*)
+ (format stream "~&"))
+
+ (format stream "~a" s)
+ (let (pkwp)
+ (dolist (o os)
+ (format stream (if pkwp " ~s" " | ~s") o)
+ (setf pkwp (keywordp o))))
+ (values))
+
+(defun call-trc-to-string (fmt$ &rest fmtargs)
+ (let ((o$ (make-array '(0) :element-type 'base-char
+ :fill-pointer 0 :adjustable t)))
+ (with-output-to-string (ostream o$)
+ (apply 'call-trc ostream fmt$ fmtargs))
+ o$))
+
+#+findtrcevalnils
+(defmethod trcp :around (other)
+ (unless (call-next-method other)(break)))
+
+(defmethod trcp (other)
+ (eq other t))
+
+(defmethod trcp (($ string))
+ t)
+
+(defun trcdepth-incf ()
+ (incf *trcdepth*))
+
+(defun trcdepth-decf ()
+ (format t "decrementing trc depth" *trcdepth*)
+ (decf *trcdepth*))
+
+(defmacro wtrc ((&optional (min 1) (max 50) &rest banner) &body body )
+ `(let ((*trcdepth* (if *trcdepth*
+ (1+ *trcdepth*)
+ 0)))
+ ,(when banner `(when (>= *trcdepth* ,min)
+ (if (< *trcdepth* ,max)
+ (trc ,@banner)
+ (progn
+ (break "excess trace notttt!!! ~d" *trcdepth*) ;; ,@banner)
+ nil))))
+ (when (< *trcdepth* ,max)
+ ,@body)))
+
+(defmacro wnotrc ((&optional (min 1) (max 50) &rest banner) &body body )
+ (declare (ignore min max banner))
+ `(progn ,@body))
+
+;------ eko --------------------------------------
+
+
+(defmacro eko ((&rest trcargs) &rest body)
+ (let ((result (gensym)))
+ `(let ((,result ,@body))
+ (trc ,(car trcargs) :=> ,result ,@(cdr trcargs))
+ ,result)))
+
+(defmacro ek (label &rest body)
+ (let ((result (gensym)))
+ `(let ((,result (,@body)))
+ (when ,label
+ (trc ,label ,result))
+ ,result)))
+
+;------------- counting ---------------------------
+(defvar *count* nil)
+(defvar *counting* nil)
+
+(defmacro with-counts ((onp &rest msg) &body body)
+ `(if ,onp
+ (prog2
+ (progn
+ (count-clear ,@msg)
+ (push t *counting*))
+ (progn ,@body)
+ (pop *counting*)
+ (show-count t ,@msg))
+ (progn ,@body)))
+
+(defun count-clear (&rest msg)
+ (declare (ignorable msg))
+ (format t "~&count-clear > ~a" msg)
+ (setf *count* nil))
+
+(defmacro count-it (&rest keys)
+ `(when *counting*
+ (call-count-it ,@keys)))
+
+(defun call-count-it (&rest keys)
+ (declare (ignorable keys))
+ ;;; (when (eql :TGTNILEVAL (car keys))(break))
+ (let ((entry (assoc keys *count* :test #'equal)))
+ (if entry
+ (setf (cdr entry) (1+ (cdr entry)))
+ (push (cons keys 1) *count*))))
+
+(defun show-count (clearp &rest msg)
+ (format t "~&Counts after: clearp ~a, length ~d: ~s" clearp (length *count*) msg)
+ (let ((res (sort (copy-list *count*) (lambda (v1 v2)
+ (let ((v1$ (symbol-name (caar v1)))
+ (v2$ (symbol-name (caar v2))))
+ (if (string= v1$ v2$)
+ (< (cdr v1) (cdr v2))
+ (string< v1$ v2$))))))
+ )
+ (loop for entry in res
+ for occs = (cdr entry)
+ when (plusp occs)
+ sum occs into running
+ and do (format t "~&~4d ... ~2d ... ~s" running occs (car entry))))
+ (when clearp (count-clear "show-count")))
+
+#+test
+(loop for entry in '((a . 10)(b . 5)(c . 0)(e . -20)(d . 2))
+ for occs = (cdr entry)
+ when (plusp occs)
+ sum occs into running
+ and do (print (list entry occs running)))
+
+
+;-------------------- timex ---------------------------------
+
+(defmacro timex ((onp &rest trcArgs) &body body)
+ `(if ,onp
+ (prog1
+ (time
+ (progn ,@body))
+ (trc "timing was of" ,@trcARgs))
+ (progn ,@body)))
+
+
+;---------------- Metrics -------------------
+
+(defmacro with-metrics ((countp timep &rest trcargs) &body body)
+ `(with-counts (,countp ,@trcargs)
+ (timex (,timep ,@trcargs)
+ ,@body)))
+
+
+; -------- cell conditions (not much used) ---------------------------------------------
+
+(define-condition xcell () ;; new 2k0227
+ ((cell :initarg :cell :reader cell :initform nil)
+ (appfunc :initarg :appfunc :reader appfunc :initform 'badcell)
+ (errortext :initarg :errortext :reader errortext :initform "<???>")
+ (otherdata :initarg :otherdata :reader otherdata :initform "<nootherdata>"))
+ (:report (lambda (c s)
+ (format s "~& trouble with cell ~a in function ~s,~s: ~s"
+ (cell c) (appfunc c) (errortext c) (otherdata c)))))
+
+(define-condition c-enabling ()
+ ((name :initarg :name :reader name)
+ (model :initarg :model :reader model)
+ (cell :initarg :cell :reader cell))
+ (:report (lambda (condition stream)
+ (format stream "~&unhandled <c-enabling>: ~s" condition)
+ (break "~&i say, unhandled <c-enabling>: ~s" condition))))
+
+(define-condition c-fatal (xcell)
+ ((name :initarg :name :reader name)
+ (model :initarg :model :reader model)
+ (cell :initarg :cell :reader cell))
+ (:report (lambda (condition stream)
+ (format stream "~&fatal cell programming error: ~s" condition)
+ (format stream "~& : ~s" (name condition))
+ (format stream "~& : ~s" (model condition))
+ (format stream "~& : ~s" (cell condition)))))
+
+(define-condition c-unadopted (c-fatal)
+ ()
+ (:report
+ (lambda (condition stream)
+ (format stream "~&unadopted cell >: ~s" (cell condition))
+ (format stream "~& >: often you mis-edit (c? (c? ...)) nesting is error"))))
+
+
+;----------------------------- link debugging -----------------------
+
+
+(defun dump-users (c &optional (depth 0))
+ (format t "~&~v,4t~s" depth c)
+ (dolist (user (c-users c))
+ (dump-users user (+ 1 depth))))
+
+(defun dump-useds (c &optional (depth 0))
+ ;(c.trc "dump-useds> entry " c (+ 1 depth))
+ (when (zerop depth)
+ (format t "x~&"))
+ (format t "~&|usd> ~v,8t~s" depth c)
+ (when (typep c 'c-ruled)
+ ;(c.trc "its ruled" c)
+ (dolist (used (cd-useds c))
+ (dump-useds used (+ 1 depth)))))
+
+
+(defun cell-reset ()
+ (setf *count* nil
+ *stop* nil
+ *dbg* nil
+ *c-break* nil
+ *c-prop-depth* 0
+ *sw-looping* nil
+ *to-be-awakened* nil
+ *trcdepth* 0))
\ No newline at end of file
Index: cells/defmodel.lisp
diff -u cells/defmodel.lisp:1.1.1.1 cells/defmodel.lisp:1.2
--- cells/defmodel.lisp:1.1.1.1 Sat Nov 8 18:44:00 2003
+++ cells/defmodel.lisp Tue Dec 16 10:02:58 2003
@@ -1,121 +1,121 @@
-;; -*- mode: Lisp; Syntax: Common-Lisp; Package: cells; -*-
-;;;
-;;; Copyright © 1995,2003 by Kenneth William Tilton.
-;;;
-;;; Permission is hereby granted, free of charge, to any person obtaining a copy
-;;; of this software and associated documentation files (the "Software"), to deal
-;;; in the Software without restriction, including without limitation the rights
-;;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-;;; copies of the Software, and to permit persons to whom the Software is furnished
-;;; to do so, subject to the following conditions:
-;;;
-;;; The above copyright notice and this permission notice shall be included in
-;;; all copies or substantial portions of the Software.
-;;;
-;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-;;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-;;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-;;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-;;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-;;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-;;; IN THE SOFTWARE.
-
-(in-package :cells)
-
-(defmacro defmodel (class directsupers slotspecs &rest options)
- ;;(print `(defmodel sees directsupers ,directsupers using ,(or directsupers :model-object)))
- `(progn
- (eval-when (:compile-toplevel :execute :load-toplevel)
- (setf (get ',class :cell-defs) nil))
- ;
- ; define slot macros before class so they can appear in initforms and default-initargs
- ;
- ,@(mapcar (lambda (slotspec)
- (destructuring-bind
- (slotname &rest slotargs
- &key (cell t) accessor reader
- &allow-other-keys)
- slotspec
- (declare (ignorable slotargs))
- (when cell
- (let* ((readerfn (or reader accessor))
- (deriverfn (intern$ "^" (symbol-name readerfn)))
- )
- ;
- ; may as well do this here...
- ;
- ;;(trc nil "slot, deriverfn would be" slotname deriverfn)
- `(eval-when (:compile-toplevel :execute :load-toplevel)
- (setf (md-slot-cell-type ',class ',slotname) ,cell)
- (unless (macro-function ',deriverfn)
- (defmacro ,deriverfn (&optional (model 'self) synfactory)
- `(let ((*synapse-factory* ,synfactory))
- (,',readerfn ,model))))
- )
- ))
- ))
- slotspecs)
-
- ;
- ; ------- defclass --------------- (^slot-value ,model ',',slotname)
- ;
-
- (progn
- (defclass ,class ,(or directsupers '(model-object));; now we can def the class
- ,(mapcar (lambda (s)
- (list* (car s)
- (let ((ias (cdr s)))
- (remf ias :cell)
- (remf ias :cwhen)
- (remf ias :unchanged-if)
- ias))) (mapcar #'copy-list slotspecs))
- (:documentation
- ,@(or (cdr (find :documentation options :key #'car))
- '("chya")))
- (:default-initargs ;; nil ok and needed: acl oddity in re not clearing d-i's sans this
- ,@(cdr (find :default-initargs options :key #'car)))
- (:metaclass ,(or (find :metaclass options :key #'car)
- 'standard-class)))
-
- (defmethod shared-initialize :after ((self ,class) slot-names &rest iargs)
- (declare (ignore slot-names iargs))
- ,(when (and directsupers (not (member 'model-object directsupers)))
- `(unless (typep self 'model-object)
- (error "If no superclass of ~a inherits directly
-or indirectly from model-object, model-object must be included as a direct super-class in
-the defmodel form for ~a" ',class ',class))))
- ;
- ; slot accessors once class is defined...
- ;
- ,@(mapcar (lambda (slotspec)
- (destructuring-bind
- (slotname &rest slotargs
- &key (cell t) unchanged-if accessor reader writer type
- &allow-other-keys)
- slotspec
- (declare (ignorable slotargs))
- (when cell
- (let* ((readerfn (or reader accessor))
- (writerfn (or writer accessor))
- )
- (setf (md-slot-cell-type class slotname) cell)
-
- `(progn
- ,(when readerfn
- `(defmethod ,readerfn ((self ,class))
- (md-slot-value self ',slotname)))
-
- ,(when writerfn
- `(defmethod (setf ,writerfn) (new-value (self ,class))
- (setf (md-slot-value self ',slotname)
- ,(if type
- `(coerce new-value ',type)
- 'new-value))))
-
- ,(when unchanged-if
- `(def-c-unchanged-test (,class ,slotname)))
- )
- ))
- ))
- slotspecs)
+;; -*- mode: Lisp; Syntax: Common-Lisp; Package: cells; -*-
+;;;
+;;; Copyright (c) 1995,2003 by Kenneth William Tilton.
+;;;
+;;; Permission is hereby granted, free of charge, to any person obtaining a copy
+;;; of this software and associated documentation files (the "Software"), to deal
+;;; in the Software without restriction, including without limitation the rights
+;;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+;;; copies of the Software, and to permit persons to whom the Software is furnished
+;;; to do so, subject to the following conditions:
+;;;
+;;; The above copyright notice and this permission notice shall be included in
+;;; all copies or substantial portions of the Software.
+;;;
+;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+;;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+;;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+;;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+;;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+;;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+;;; IN THE SOFTWARE.
+
+(in-package :cells)
+
+(defmacro defmodel (class directsupers slotspecs &rest options)
+ ;;(print `(defmodel sees directsupers ,directsupers using ,(or directsupers :model-object)))
+ `(progn
+ (eval-when (:compile-toplevel :execute :load-toplevel)
+ (setf (get ',class :cell-types) nil))
+ ;
+ ; define slot macros before class so they can appear in initforms and default-initargs
+ ;
+ ,@(mapcar (lambda (slotspec)
+ (destructuring-bind
+ (slotname &rest slotargs
+ &key (cell t) accessor reader
+ &allow-other-keys)
+ slotspec
+ (declare (ignorable slotargs))
+ (when cell
+ (let* ((readerfn (or reader accessor))
+ (deriverfn (intern$ "^" (symbol-name readerfn)))
+ )
+ ;
+ ; may as well do this here...
+ ;
+ ;;(trc nil "slot, deriverfn would be" slotname deriverfn)
+ `(eval-when (:compile-toplevel :execute :load-toplevel)
+ (setf (md-slot-cell-type ',class ',slotname) ,cell)
+ (unless (macro-function ',deriverfn)
+ (defmacro ,deriverfn (&optional (model 'self) synfactory)
+ `(let ((*synapse-factory* ,synfactory))
+ (,',readerfn ,model))))
+ )
+ ))
+ ))
+ slotspecs)
+
+ ;
+ ; ------- defclass --------------- (^slot-value ,model ',',slotname)
+ ;
+
+ (progn
+ (defclass ,class ,(or directsupers '(model-object));; now we can def the class
+ ,(mapcar (lambda (s)
+ (list* (car s)
+ (let ((ias (cdr s)))
+ (remf ias :cell)
+ (remf ias :cwhen)
+ (remf ias :unchanged-if)
+ ias))) (mapcar #'copy-list slotspecs))
+ (:documentation
+ ,@(or (cdr (find :documentation options :key #'car))
+ '("chya")))
+ (:default-initargs ;; nil ok and needed: acl oddity in re not clearing d-i's sans this
+ ,@(cdr (find :default-initargs options :key #'car)))
+ (:metaclass ,(or (find :metaclass options :key #'car)
+ 'standard-class)))
+
+ (defmethod shared-initialize :after ((self ,class) slot-names &rest iargs)
+ (declare (ignore slot-names iargs))
+ ,(when (and directsupers (not (member 'model-object directsupers)))
+ `(unless (typep self 'model-object)
+ (error "If no superclass of ~a inherits directly
+or indirectly from model-object, model-object must be included as a direct super-class in
+the defmodel form for ~a" ',class ',class))))
+ ;
+ ; slot accessors once class is defined...
+ ;
+ ,@(mapcar (lambda (slotspec)
+ (destructuring-bind
+ (slotname &rest slotargs
+ &key (cell t) unchanged-if accessor reader writer type
+ &allow-other-keys)
+ slotspec
+ (declare (ignorable slotargs))
+ (when cell
+ (let* ((readerfn (or reader accessor))
+ (writerfn (or writer accessor))
+ )
+ (setf (md-slot-cell-type class slotname) cell)
+
+ `(progn
+ ,(when readerfn
+ `(defmethod ,readerfn ((self ,class))
+ (md-slot-value self ',slotname)))
+
+ ,(when writerfn
+ `(defmethod (setf ,writerfn) (new-value (self ,class))
+ (setf (md-slot-value self ',slotname)
+ ,(if type
+ `(coerce new-value ',type)
+ 'new-value))))
+
+ ,(when unchanged-if
+ `(def-c-unchanged-test (,class ,slotname) ,unchanged-if))
+ )
+ ))
+ ))
+ slotspecs)
(find-class ',class))))
Index: cells/detritus.lisp
diff -u cells/detritus.lisp:1.1.1.1 cells/detritus.lisp:1.2
--- cells/detritus.lisp:1.1.1.1 Sat Nov 8 18:44:05 2003
+++ cells/detritus.lisp Tue Dec 16 10:02:58 2003
@@ -1,49 +1,49 @@
-;; -*- mode: Lisp; Syntax: Common-Lisp; Package: cells; -*-
-;;;
-;;; Copyright © 1995,2003 by Kenneth William Tilton.
-;;;
-;;; Permission is hereby granted, free of charge, to any person obtaining a copy
-;;; of this software and associated documentation files (the "Software"), to deal
-;;; in the Software without restriction, including without limitation the rights
-;;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-;;; copies of the Software, and to permit persons to whom the Software is furnished
-;;; to do so, subject to the following conditions:
-;;;
-;;; The above copyright notice and this permission notice shall be included in
-;;; all copies or substantial portions of the Software.
-;;;
-;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-;;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-;;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-;;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-;;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-;;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-;;; IN THE SOFTWARE.
-
-(in-package :cells)
-
-(defvar *dbg*)
-
-(defmacro wdbg (&body body)
- `(let ((*dbg* t))
- ,@body))
-
-#+clisp
-(defun slot-definition-name (slot)
- (clos::slotdef-name slot))
-
-(defmethod class-slot-named ((classname symbol) slotname)
- (class-slot-named (find-class classname) slotname))
-
-(defmethod class-slot-named (class slotname)
- (find slotname (class-slots class) :key #'slot-definition-name))
-
-#+mcl
-(defun class-slots (c)
- (nconc (copy-list (class-class-slots c))
- (copy-list (class-instance-slots c))))
-
-(defun true (it) (declare (ignore it)) t)
-(defun false (it) (declare (ignore it)))
-(defun xor (c1 c2)
- (if c1 (not c2) c2))
+;; -*- mode: Lisp; Syntax: Common-Lisp; Package: cells; -*-
+;;;
+;;; Copyright (c) 1995,2003 by Kenneth William Tilton.
+;;;
+;;; Permission is hereby granted, free of charge, to any person obtaining a copy
+;;; of this software and associated documentation files (the "Software"), to deal
+;;; in the Software without restriction, including without limitation the rights
+;;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+;;; copies of the Software, and to permit persons to whom the Software is furnished
+;;; to do so, subject to the following conditions:
+;;;
+;;; The above copyright notice and this permission notice shall be included in
+;;; all copies or substantial portions of the Software.
+;;;
+;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+;;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+;;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+;;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+;;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+;;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+;;; IN THE SOFTWARE.
+
+(in-package :cells)
+
+(defvar *dbg*)
+
+(defmacro wdbg (&body body)
+ `(let ((*dbg* t))
+ ,@body))
+
+#+clisp
+(defun slot-definition-name (slot)
+ (clos::slotdef-name slot))
+
+(defmethod class-slot-named ((classname symbol) slotname)
+ (class-slot-named (find-class classname) slotname))
+
+(defmethod class-slot-named (class slotname)
+ (find slotname (class-slots class) :key #'slot-definition-name))
+
+#+mcl
+(defun class-slots (c)
+ (nconc (copy-list (class-class-slots c))
+ (copy-list (class-instance-slots c))))
+
+(defun true (it) (declare (ignore it)) t)
+(defun false (it) (declare (ignore it)))
+(defun xor (c1 c2)
+ (if c1 (not c2) c2))
Index: cells/family-values.lisp
diff -u cells/family-values.lisp:1.1.1.1 cells/family-values.lisp:1.2
--- cells/family-values.lisp:1.1.1.1 Sat Nov 8 18:44:05 2003
+++ cells/family-values.lisp Tue Dec 16 10:02:58 2003
@@ -1,105 +1,105 @@
-;; -*- mode: Lisp; Syntax: Common-Lisp; Package: cells; -*-
-;;;
-;;; Copyright © 1995,2003 by Kenneth William Tilton.
-;;;
-;;; Permission is hereby granted, free of charge, to any person obtaining a copy
-;;; of this software and associated documentation files (the "Software"), to deal
-;;; in the Software without restriction, including without limitation the rights
-;;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-;;; copies of the Software, and to permit persons to whom the Software is furnished
-;;; to do so, subject to the following conditions:
-;;;
-;;; The above copyright notice and this permission notice shall be included in
-;;; all copies or substantial portions of the Software.
-;;;
-;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-;;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-;;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-;;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-;;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-;;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-;;; IN THE SOFTWARE.
-
-(in-package :cells)
-
-(eval-when (:compile-toplevel :load-toplevel :execute)
- (export '(family-values family-values-sorted
- sortindex sortdirection sortpredicate sortkey
- ^sortindex ^sortdirection ^sortpredicate ^sortkey)))
-
-(defmodel family-values (family)
- (
- (kvcollector :initarg :kvcollector
- :initform #'identity
- :reader kvcollector)
-
- (kidvalues :cell t
- :initform (c? (when (kvcollector self)
- (funcall (kvcollector self) (^mdvalue))))
- :accessor kidvalues
- :initarg :kidvalues)
-
- (kvkey :initform #'identity
- :initarg :kvkey
- :reader kvkey)
-
- (kvkeytest :initform #'equal
- :initarg :kvkeytest
- :reader kvkeytest)
-
- (kidfactory :cell t
- :initform #'identity
- :initarg :kidfactory
- :reader kidfactory)
-
- (.kids :cell t
- :initform (c? (assert (listp (kidvalues self)))
- (let ((newkids (mapcan (lambda (kidvalue)
- (list (or (find kidvalue .cache
- :key (kvkey self)
- :test (kvkeytest self))
- (trc nil "family-values forced to make new kid"
- self .cache kidvalue)
- (funcall (kidfactory self) self kidvalue))))
- (^kidvalues))))
- (nconc (mapcan (lambda (oldkid)
- (unless (find oldkid newkids)
- (when (fv-kid-keep self oldkid)
- (list oldkid))))
- .cache)
- newkids)))
- :accessor kids
- :initarg :kids)))
-
-(defmethod fv-kid-keep (family oldkid)
- (declare (ignorable family oldkid))
- nil)
-
-(defmodel family-values-sorted (family-values)
- ((sortedkids :initarg :sortedkids :accessor sortedkids
- :initform nil)
- (sortmap :initform (cv nil) :initarg :sortmap :accessor sortmap)
- (.kid-slots :cell t
- :initform (c? (assert (listp (kidvalues self)))
- (mapsort (^sortmap)
- (thekids
- (mapcar (lambda (kidvalue)
- (trc "making kid" kidvalue)
- (or (find kidvalue .cache :key (kvkey self) :test (kvkeytest self))
- (trc nil "family-values forced to make new kid" self .cache kidvalue)
- (funcall (kidfactory self) self kidvalue)))
- (^kidvalues)))))
- :accessor kid-slots
- :initarg :kid-slots)))
-
-(defun mapsort (map data)
- ;;(trc "mapsort map" map)
- (if map
- (stable-sort data #'< :key (lambda (datum) (or (position datum map)
- ;(trc "mapsort datum not in map" datum)
- (1+ (length data)))))
- data))
-
-(def-c-echo sortedkids ()
- (setf (sortmap self) new-value)) ;; cellular trick to avoid cyclicity
-
+;; -*- mode: Lisp; Syntax: Common-Lisp; Package: cells; -*-
+;;;
+;;; Copyright (c) 1995,2003 by Kenneth William Tilton.
+;;;
+;;; Permission is hereby granted, free of charge, to any person obtaining a copy
+;;; of this software and associated documentation files (the "Software"), to deal
+;;; in the Software without restriction, including without limitation the rights
+;;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+;;; copies of the Software, and to permit persons to whom the Software is furnished
+;;; to do so, subject to the following conditions:
+;;;
+;;; The above copyright notice and this permission notice shall be included in
+;;; all copies or substantial portions of the Software.
+;;;
+;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+;;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+;;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+;;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+;;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+;;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+;;; IN THE SOFTWARE.
+
+(in-package :cells)
+
+(eval-when (:compile-toplevel :load-toplevel :execute)
+ (export '(family-values family-values-sorted
+ sortindex sortdirection sortpredicate sortkey
+ ^sortindex ^sortdirection ^sortpredicate ^sortkey)))
+
+(defmodel family-values (family)
+ (
+ (kvcollector :initarg :kvcollector
+ :initform #'identity
+ :reader kvcollector)
+
+ (kidvalues :cell t
+ :initform (c? (when (kvcollector self)
+ (funcall (kvcollector self) (^md-value))))
+ :accessor kidvalues
+ :initarg :kidvalues)
+
+ (kvkey :initform #'identity
+ :initarg :kvkey
+ :reader kvkey)
+
+ (kvkeytest :initform #'equal
+ :initarg :kvkeytest
+ :reader kvkeytest)
+
+ (kidfactory :cell t
+ :initform #'identity
+ :initarg :kidfactory
+ :reader kidfactory)
+
+ (.kids :cell t
+ :initform (c? (c-assert (listp (kidvalues self)))
+ (let ((newkids (mapcan (lambda (kidvalue)
+ (list (or (find kidvalue .cache
+ :key (kvkey self)
+ :test (kvkeytest self))
+ (trc nil "family-values forced to make new kid"
+ self .cache kidvalue)
+ (funcall (kidfactory self) self kidvalue))))
+ (^kidvalues))))
+ (nconc (mapcan (lambda (oldkid)
+ (unless (find oldkid newkids)
+ (when (fv-kid-keep self oldkid)
+ (list oldkid))))
+ .cache)
+ newkids)))
+ :accessor kids
+ :initarg :kids)))
+
+(defmethod fv-kid-keep (family oldkid)
+ (declare (ignorable family oldkid))
+ nil)
+
+(defmodel family-values-sorted (family-values)
+ ((sortedkids :initarg :sortedkids :accessor sortedkids
+ :initform nil)
+ (sortmap :initform (cv nil) :initarg :sortmap :accessor sortmap)
+ (.kids :cell t
+ :initform (c? (c-assert (listp (kidvalues self)))
+ (mapsort (^sortmap)
+ (thekids
+ (mapcar (lambda (kidvalue)
+ (trc "making kid" kidvalue)
+ (or (find kidvalue .cache :key (kvkey self) :test (kvkeytest self))
+ (trc nil "family-values forced to make new kid" self .cache kidvalue)
+ (funcall (kidfactory self) self kidvalue)))
+ (^kidvalues)))))
+ :accessor kids
+ :initarg :kids)))
+
+(defun mapsort (map data)
+ ;;(trc "mapsort map" map)
+ (if map
+ (stable-sort data #'< :key (lambda (datum) (or (position datum map)
+ ;(trc "mapsort datum not in map" datum)
+ (1+ (length data)))))
+ data))
+
+(def-c-echo sortedkids ()
+ (setf (sortmap self) new-value)) ;; cellular trick to avoid cyclicity
+
Index: cells/family.lisp
diff -u cells/family.lisp:1.1.1.1 cells/family.lisp:1.2
--- cells/family.lisp:1.1.1.1 Sat Nov 8 18:44:05 2003
+++ cells/family.lisp Tue Dec 16 10:02:58 2003
@@ -1,240 +1,261 @@
-;; -*- mode: Lisp; Syntax: Common-Lisp; Package: cells; -*-
-;;;
-;;; Copyright © 1995,2003 by Kenneth William Tilton.
-;;;
-;;; Permission is hereby granted, free of charge, to any person obtaining a copy
-;;; of this software and associated documentation files (the "Software"), to deal
-;;; in the Software without restriction, including without limitation the rights
-;;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-;;; copies of the Software, and to permit persons to whom the Software is furnished
-;;; to do so, subject to the following conditions:
-;;;
-;;; The above copyright notice and this permission notice shall be included in
-;;; all copies or substantial portions of the Software.
-;;;
-;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-;;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-;;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-;;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-;;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-;;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-;;; IN THE SOFTWARE.
-
-(in-package :cells)
-
-(eval-when (:compile-toplevel :execute :load-toplevel)
- (export '(model mdvalue family kids kid1 perishable)))
-
-(defmodel model ()
- ((.mdvalue :initform nil :accessor mdvalue :initarg :mdvalue)))
-
-(defmodel perishable ()
- ((expiration :initform nil :accessor expiration :initarg :expiration)))
-
-(def-c-echo expiration ()
- (when new-value
- (not-to-be self)))
-
-(defmodel family (model)
- ((.kids :cell t
- :initform (cv nil) ;; most useful
- :accessor kids
- :initarg :kids)
- (.kid-slots :cell t
- :initform nil
- :accessor kid-slots
- :initarg :kid-slots)))
-
-(defmacro thekids (&rest kids)
- `(packed-flat! ,@(mapcar (lambda (kid)
- (typecase kid
- (keyword `(make-instance ',(intern$ (symbol-name kid))))
- (t `,kid)))
- kids)))
-
-(defmacro thekids2 (&rest kids)
- `(packed-flat! ,@(mapcar (lambda (kid)
- (typecase kid
- (keyword `(make-instance ',(intern$ (symbol-name kid))))
- (t `,kid)))
- kids)))
-
-(defun kid1 (self) (car (kids self)))
-
-;; /// redundancy in following
-
-(defmacro psib (&optional (selfform 'self))
- (let ((self (gensym)))
- `(bwhen (,self ,selfform)
- (find-prior ,self (kids (fmparent ,self))))))
-
-(defmacro nsib (&optional (selfform 'self))
- (let ((self (gensym)))
- `(bwhen (,self ,selfform)
- (cadr (member ,self (kids (fmparent ,self)))))))
-
-(defmacro ^priorSib (self)
- (let ((kid (gensym)))
- `(let* ((,kid ,self))
- (find-prior ,kid (^kids (fmParent ,kid))))))
-
-(defmacro ^firstKidP (self)
- (let ((kid (gensym)))
- `(let ((,kid ,self))
- (eql ,kid (car (^kids (fmParent ,kid)))))))
-
-(defmacro ^lastKidP (self)
- (let ((kid (gensym)))
- `(let ((,kid ,self))
- (null (cdr (member ,kid (^kids (fmParent ,kid))))))))
-
-(defun md-adopt (fmparent self)
- (assert self)
- (assert fmparent)
- (assert (typep fmparent 'family))
-
- (trc nil "md-adopt >" :by fmparent)
-
- (let ((currparent (fmparent self))
- (selftype (type-of self)))
- (assert (or (null currparent)
- (eql fmparent currparent)))
- (unless (plusp (adopt-ct self))
- (incf (adopt-ct self))
- (setf (fmparent self) fmparent)
-
- (bwhen (kid-slots-fn (kid-slots (fmparent self)))
- (dolist (ksdef (funcall kid-slots-fn self) self)
- (let ((slot-name (ksname ksdef)))
- (trc nil "got ksdef " slot-name)
- (when (md-slot-cell-type selftype slot-name)
- (trc nil "got cell type " slot-name)
- (when (or (not (ksifmissing ksdef))
- (and (null (c-slot-value self slot-name))
- (null (md-slot-cell self slot-name))))
- (trc nil "ks missing ok " slot-name)
- (multiple-value-bind (c-or-value suppressp)
- (funcall (ksrule ksdef) self)
- (unless suppressp
- (trc nil "c-install " slot-name c-or-value)
- (c-install self slot-name c-or-value))))))))
-
- ; new for 12/02...
- (md-adopt-kids self)))
- self)
-
-(defmethod md-adopt-kids (self) (declare (ignorable self)))
-(defmethod md-adopt-kids ((self family))
- (when (slot-boundp self '.kids)
- (dolist (k (slot-value self '.kids))
- (unless (fmParent k)
- (md-adopt self k)))))
-
-
-
-
-(defmethod c-slot-value ((self model-object) slot)
- (slot-value self slot))
-
-(defun md-kids-change (self new-kids old-kids usage)
- (assert (listp new-kids))
- (assert (listp old-kids))
- (assert (not (member nil old-kids)))
- (assert (not (member nil new-kids)))
-
- (trc nil "md-kids-change > entry" usage new-kids old-kids)
- #+nah (when (and (trcp (car new-kids))
- (eql usage :md-slot-value-assume))
- (break "how here? ~a" self))
-
- (dolist (k old-kids)
- (unless (member k new-kids)
- (trc nil "kids change nailing lost kid" k)
- (not-to-be k)
- (setf (fmparent k) nil) ;; 020302kt unnecessary? anyway, after not-to-be since that might require fmparent
- ))
-
- (dolist (k new-kids)
- (unless (member k old-kids)
- (if (eql :nascent (md-state k))
- (progn
- #+dfdbg (trc k "adopting par,k:" self k)
- (md-adopt self k))
- (unless (eql self (fmParent k))
- ;; 230126 recent changes to kids handling leads to dup kids-change calls
- (trc "feature not yet implemented: adopting previously adopted: parent, kid" self (type-of k))
- (trc "old" old-kids)
- (trc "new" new-kids)
- (break "bad state extant nkid ~a ~a ~a" usage k (md-state k))
- )))))
-
-(def-c-echo .kids ((self family))
- (dolist (k new-value)
- (to-be k)))
-
-(defun md-reinitialize (self)
- (unless (eql (md-state self) :nascent)
- (setf (md-state self) :nascent)
- (md-reinitialize-primary self)))
-
-(defmethod md-reinitialize-primary :after ((self family))
- (dolist (kid (slot-value self '.kids)) ;; caused re-entrance to c? (kids self))
- (md-reinitialize kid)))
-
-(defmethod md-reinitialize-primary (self)
- (cellbrk)
- (md-map-cells self nil (lambda (c)
- (setf (c-waking-state c) nil)
- (when (typep c 'c-ruled)
- (setf (c-state c) :unbound)))))
-
-(defmethod kids ((other model-object)) nil)
-
-(defmethod not-to-be :before ((fm family))
- (unless (md-untouchable fm)
- (trc nil "(not-to-be :before family) not closed stream, backdooropen; kids c-awake; kids c-state"
- *svuc-backdoor-open*
- (if (md-slot-cell fm '.kids)
- (c-waking-state (md-slot-cell fm '.kids))
- :no-kids-cell)
- (when (md-slot-cell fm '.kids)
- (c-state (md-slot-cell fm 'kids))))
- ;; use backdoor so if kids not yet ruled into
- ;; existence they won't be now just to not-to-be them
- (let ((svkids (slot-value fm '.kids)))
- (when (listp svkids)
- (dolist ( kid svkids)
- (not-to-be kid)))))
-
- (trc nil "(not-to-be :before family) exit, kids state" (when (md-slot-cell fm 'kids)
- (c-state (md-slot-cell fm 'kids)))))
-
-
-;------------------ kid slotting ----------------------------
-;
-(cc-defstruct (kid-slotdef
- (:conc-name nil))
- ksname
- ksrule
- (ksifmissing t))
-
-(defmacro mk-kid-slot ((ksname &key ifmissing) ksrule)
- `(make-kid-slotdef
- :ksname ',ksname
- :ksrule (lambda (self)
- (declare (ignorable self))
- ,ksrule)
- :ksifmissing ,ifmissing))
-
-(defmacro def-kid-slots (&rest slot-defs)
- `(lambda (self)
- (declare (ignorable self))
- (list ,@slot-defs)))
-
-(defmethod md-name (symbol)
- symbol)
-
-(defmethod md-name ((nada null))
- (unless *stop*
- (setq *stop* t)
- (break "md-name called on nil")))
\ No newline at end of file
+;; -*- mode: Lisp; Syntax: Common-Lisp; Package: cells; -*-
+;;;
+;;; Copyright (c) 1995,2003 by Kenneth William Tilton.
+;;;
+;;; Permission is hereby granted, free of charge, to any person obtaining a copy
+;;; of this software and associated documentation files (the "Software"), to deal
+;;; in the Software without restriction, including without limitation the rights
+;;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+;;; copies of the Software, and to permit persons to whom the Software is furnished
+;;; to do so, subject to the following conditions:
+;;;
+;;; The above copyright notice and this permission notice shall be included in
+;;; all copies or substantial portions of the Software.
+;;;
+;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+;;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+;;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+;;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+;;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+;;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+;;; IN THE SOFTWARE.
+
+(in-package :cells)
+
+(eval-when (:compile-toplevel :execute :load-toplevel)
+ (export '(model md-value family kids kid1 perishable)))
+
+(defmodel model ()
+ ((.md-name :cell nil :initform nil :initarg :md-name :accessor md-name)
+ (.fm-parent :cell nil :initform nil :initarg :fm-parent :accessor fm-parent)
+ (.md-value :initform nil :accessor md-value :initarg :md-value)))
+
+(defmethod print-object ((self model) s)
+ (format s "~a" (or (md-name self) (type-of self))))
+
+(define-symbol-macro .parent (fm-parent self))
+
+(defmethod md-initialize :around ((self model))
+ (when (slot-boundp self '.md-name)
+ (unless (md-name self)
+ (setf (md-name self) (c-class-name (class-of self)))))
+
+ (when (fm-parent self)
+ (md-adopt (fm-parent self) self))
+
+ (call-next-method))
+
+(defmodel perishable ()
+ ((expiration :initform nil :accessor expiration :initarg :expiration)))
+
+(def-c-echo expiration ()
+ (when new-value
+ (not-to-be self)))
+
+(defmodel family (model)
+ ((.kid-slots :cell nil
+ :initform nil
+ :accessor kid-slots
+ :initarg :kid-slots)
+ (.kids :initform (cv nil) ;; most useful
+ :accessor kids
+ :initarg :kids)
+ ))
+
+(defmacro thekids (&rest kids)
+ `(packed-flat! ,@(mapcar (lambda (kid)
+ (typecase kid
+ (keyword `(make-instance ',(intern$ (symbol-name kid))))
+ (t `,kid)))
+ kids)))
+
+(defmacro thekids2 (&rest kids)
+ `(packed-flat! ,@(mapcar (lambda (kid)
+ (typecase kid
+ (keyword `(make-instance ',(intern$ (symbol-name kid))))
+ (t `,kid)))
+ kids)))
+
+(defun kid1 (self) (car (kids self)))
+(defun lastkid (self) (last1 (kids self)))
+
+;; /// redundancy in following
+
+(defmacro psib (&optional (selfform 'self))
+ (let ((self (gensym)))
+ `(bwhen (,self ,selfform)
+ (find-prior ,self (kids (fm-parent ,self))))))
+
+(defmacro nsib (&optional (selfform 'self))
+ (let ((self (gensym)))
+ `(bwhen (,self ,selfform)
+ (cadr (member ,self (kids (fm-parent ,self)))))))
+
+(defmacro ^priorSib (self)
+ (let ((kid (gensym)))
+ `(let* ((,kid ,self))
+ (find-prior ,kid (^kids (fm-parent ,kid))))))
+
+(defmacro ^firstKidP (self)
+ (let ((kid (gensym)))
+ `(let ((,kid ,self))
+ (eql ,kid (car (^kids (fm-parent ,kid)))))))
+
+(defmacro ^lastKidP (self)
+ (let ((kid (gensym)))
+ `(let ((,kid ,self))
+ (null (cdr (member ,kid (^kids (fm-parent ,kid))))))))
+
+(defun md-adopt (fm-parent self)
+ (c-assert self)
+ (c-assert fm-parent)
+ (c-assert (typep fm-parent 'family))
+
+
+ (trc nil "md-adopt >" :kid self (adopt-ct self) :by fm-parent)
+
+ (let ((currparent (fm-parent self))
+ (selftype (type-of self)))
+ (c-assert (or (null currparent)
+ (eql fm-parent currparent)))
+ ;; (when (plusp (adopt-ct self))(c-break "2nd adopt ~a, by ~a" self fm-parent))
+ (unless (plusp (adopt-ct self))
+ (incf (adopt-ct self))
+ (setf (fm-parent self) fm-parent)
+
+ (bwhen (kid-slots-fn (kid-slots (fm-parent self)))
+ (dolist (ksdef (funcall kid-slots-fn self) self)
+ (let ((slot-name (ksname ksdef)))
+ (trc nil "got ksdef " slot-name)
+ (when (md-slot-cell-type selftype slot-name)
+ (trc fm-parent "got cell type " slot-name)
+ (when (or (not (ksifmissing ksdef))
+ (and (null (c-slot-value self slot-name))
+ (null (md-slot-cell self slot-name))))
+ (trc fm-parent "ks missing ok " slot-name)
+ (multiple-value-bind (c-or-value suppressp)
+ (funcall (ksrule ksdef) self)
+ (unless suppressp
+ (trc fm-parent "c-install " slot-name c-or-value)
+ (c-install self slot-name c-or-value))))))))
+
+ ; new for 12/02...
+ (md-adopt-kids self)))
+ self)
+
+(defmethod md-adopt-kids (self) (declare (ignorable self)))
+(defmethod md-adopt-kids ((self family))
+ (when (slot-boundp self '.kids)
+ (dolist (k (slot-value self '.kids))
+ (unless (fm-parent k)
+ (md-adopt self k)))))
+
+
+
+
+(defmethod c-slot-value ((self model-object) slot)
+ (slot-value self slot))
+
+(defun md-kids-change (self new-kids old-kids usage)
+ (c-assert (listp new-kids))
+ (c-assert (listp old-kids))
+ (c-assert (not (member nil old-kids)))
+ (c-assert (not (member nil new-kids)))
+
+ (trc nil "md-kids-change > entry" usage new-kids old-kids)
+ #+nah (when (and (trcp (car new-kids))
+ (eql usage :md-slot-value-assume))
+ (break "how here? ~a" self))
+
+ (dolist (k old-kids)
+ (unless (member k new-kids)
+ (trc nil "kids change nailing lost kid" k)
+ (not-to-be k)
+ (setf (fm-parent k) nil) ;; 020302kt unnecessary? anyway, after not-to-be since that might require fm-parent
+ ))
+
+ (dolist (k new-kids)
+ (unless (member k old-kids)
+ (if (eql :nascent (md-state k))
+ (progn
+ #+dfdbg (trc k "adopting par,k:" self k)
+ (md-adopt self k))
+ (unless (eql self (fm-parent k))
+ ;; 230126 recent changes to kids handling leads to dup kids-change calls
+ (trc "feature not yet implemented: adopting previously adopted: parent, kid" self (type-of k))
+ (trc "old" old-kids)
+ (trc "new" new-kids)
+ (break "bad state extant nkid ~a ~a ~a" usage k (md-state k))
+ )))))
+
+(def-c-echo .kids ((self family))
+ (dolist (k new-value)
+ (to-be k)))
+
+(defun md-reinitialize (self)
+ (unless (eql (md-state self) :nascent)
+ (setf (md-state self) :nascent)
+ (md-reinitialize-primary self)))
+
+(defmethod md-reinitialize-primary :after ((self family))
+ (dolist (kid (slot-value self '.kids)) ;; caused re-entrance to c? (kids self))
+ (md-reinitialize kid)))
+
+(defmethod md-reinitialize-primary (self)
+ (cellbrk)
+ (md-map-cells self nil (lambda (c)
+ (setf (c-waking-state c) nil)
+ (when (typep c 'c-ruled)
+ (setf (c-state c) :unbound)))))
+
+(defmethod kids ((other model-object)) nil)
+
+(defmethod not-to-be :before ((fm family))
+ (unless (md-untouchable fm)
+ (trc nil "(not-to-be :before family) not closed stream, backdooropen; kids c-awake; kids c-state"
+ *svuc-backdoor-open*
+ (if (md-slot-cell fm '.kids)
+ (c-waking-state (md-slot-cell fm '.kids))
+ :no-kids-cell)
+ (when (md-slot-cell fm '.kids)
+ (c-state (md-slot-cell fm 'kids))))
+ ;; use backdoor so if kids not yet ruled into
+ ;; existence they won't be now just to not-to-be them
+ (let ((svkids (slot-value fm '.kids)))
+ (when (listp svkids)
+ (dolist ( kid svkids)
+ (not-to-be kid)))))
+
+ (trc nil "(not-to-be :before family) exit, kids state" (when (md-slot-cell fm 'kids)
+ (c-state (md-slot-cell fm 'kids)))))
+
+
+;------------------ kid slotting ----------------------------
+;
+(defstruct (kid-slotdef
+ (:conc-name nil))
+ ksname
+ ksrule
+ (ksifmissing t))
+
+(defmacro mk-kid-slot ((ksname &key ifmissing) ksrule)
+ `(make-kid-slotdef
+ :ksname ',ksname
+ :ksrule (lambda (self)
+ (declare (ignorable self))
+ ,ksrule)
+ :ksifmissing ,ifmissing))
+
+(defmacro def-kid-slots (&rest slot-defs)
+ `(lambda (self)
+ (declare (ignorable self))
+ (list ,@slot-defs)))
+
+(defmethod md-name (symbol)
+ symbol)
+
+(defmethod md-name ((nada null))
+ (unless (c-stopped)
+ (c-stop :md-name-on-null)
+ (break "md-name called on nil")))
+
Index: cells/flow-control.lisp
diff -u cells/flow-control.lisp:1.1.1.1 cells/flow-control.lisp:1.2
--- cells/flow-control.lisp:1.1.1.1 Sat Nov 8 18:44:17 2003
+++ cells/flow-control.lisp Tue Dec 16 10:02:58 2003
@@ -1,169 +1,155 @@
-;; -*- mode: Lisp; Syntax: Common-Lisp; Package: cells; -*-
-;;;
-;;;
-;;; Copyright © 1995,2003 by Kenneth William Tilton.
-;;;
-;;; Permission is hereby granted, free of charge, to any person obtaining a copy
-;;; of this software and associated documentation files (the "Software"), to deal
-;;; in the Software without restriction, including without limitation the rights
-;;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-;;; copies of the Software, and to permit persons to whom the Software is furnished
-;;; to do so, subject to the following conditions:
-;;;
-;;; The above copyright notice and this permission notice shall be included in
-;;; all copies or substantial portions of the Software.
-;;;
-;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-;;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-;;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-;;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-;;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-;;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-;;; IN THE SOFTWARE.
-
-(in-package :cells)
-
-(defmacro maxf (place &rest othervalues)
- `(setf ,place (max ,place ,@othervalues)))
-
-(defun last1 (thing)
- (car (last thing)))
-
-(defun max-if (&rest values)
- (loop for x in values when x maximize x))
-
-(defun min-max-of (v1 v2)
- (values (min-if v1 v2) (max-if v1 v2)))
-
-(defun min-if (v1 v2)
- (if v1 (if v2 (min v1 v2) v1) v2))
-
-(defun list-flatten! (&rest list)
- (if (consp list)
- (let (head work visited)
- (labels ((link (cell)
- ;;(format t "~&Link > cons: ~s . ~s" (car cell) (cdr cell))
- (when (and (consp cell)
- (member cell visited))
- (break "list-flatten! detects infinite list: cell ~a, visited ~a" cell visited))
- (push cell visited)
-
- (when cell
- (if (consp (car cell))
- (link (car cell))
- (progn
- (setf head (or head cell))
- (when work
- (rplacd work cell))
- (setf work cell)))
- (link (rest cell)))))
- (link list))
- head)
- list))
-
-(defun packed-flat! (&rest uNameit)
- (delete-if #'null (list-flatten! uNameIt)))
-
-(defmacro with-dynamic-fn ((fnName (&rest fnArgs) &body fnBody) &body body)
- `(let ((,fnName (lambda ,fnArgs ,@fnBody)))
- (declare (dynamic-extent ,fnname))
- ,@body))
-
-(eval-when (compile load eval)
- (export 'myAssert))
-
-(defmacro myAssert (assertion &optional places fmt$ &rest fmtargs)
- (declare (ignore places))
-
- `(unless *stop*
- (unless ,assertion
- (setf *stop* t)
- ,(if fmt$
- `(mybreak ,fmt$ ,@fmtargs)
- `(mybreak "failed assertion:" ',assertion)))))
-
-(defvar *mybreak*)
-
-(defun mybreak (&rest args)
- (unless (or *mybreak* *stop*)
- (setf *mybreak* t)
- (setf *stop* t)
- (format t "mybreak > stopping > ~a" args)
- (apply #'break args)))
-
-(defun assocv (sym assoc)
- (cdr (assoc sym assoc)))
-
-(defmacro assocv-setf (assoc-place sym-form v)
- (let ((sym (gensym))(entry (gensym)))
- `(let ((,sym ,sym-form))
- (bIf (,entry (assoc ,sym ,assoc-place))
- (rplacd ,entry ,v)
- (push (cons ,sym ,v) ,assoc-place)))))
-
-(defun intern$ (&rest strings)
- (intern (apply #'concatenate 'string (mapcar #'string-upcase strings))))
-
-#-allegro
-(defmacro until (test &body body)
- `(LOOP (WHEN ,test (RETURN)) ,@body))
-
-#-allegro
-(defmacro while (test &body body)
- `(LOOP (unless ,test (RETURN)) ,@body))
-
-(defmacro bwhen ((bindvar boundform) &body body)
- `(let ((,bindvar ,boundform))
- (when ,bindvar
- ,@body)))
-
-(defmacro bif ((bindvar boundform) yup &optional nope)
- `(let ((,bindvar ,boundform))
- (if ,bindvar
- ,yup
- ,nope)))
-
-(defmacro maptimes ((nvar count) &body body)
- `(loop for ,nvar below ,count
- collecting (progn ,@body)))
-
-; --- cloucell support for struct access of slots ------------------------
-
-(eval-when (:compile-toplevel :execute :load-toplevel)
- (export '(cc-defstruct instance-slots)))
-
-(defmacro cc-defstruct (header &rest slots)
- (let (name concname (cache (gensym)))
- (if (consp header)
- (destructuring-bind (hname &rest options)
- header
- (setf name hname)
- (setf concname (bIf (concoption (find :conc-name options :key #'car))
- (unless (eql (second concoption) 'nil)
- (second concoption))
- (intern (concatenate 'string
- (symbol-name hname)
- "-")))))
- (progn
- (setf name header)
- (setf concname (intern (concatenate 'string
- (symbol-name header) "-")))))
-
- (let ((cc-info (mapcar (lambda (s)
- (let ((sn (if (consp s)
- (car s) s)))
- (cons sn
- (intern (concatenate 'string
- (when concname (symbol-name concname))
- (symbol-name sn))))))
- slots)))
- `(progn
- (defstruct ,header ,@slots)
- (let (,cache)
- (defmethod instance-slots ((self ,name))
- (or ,cache (setf ,cache (append (call-next-method) ',cc-info)))))
- ))))
-
-(defmethod instance-slots (root)
- (declare (ignorable root)))
-
+;; -*- mode: Lisp; Syntax: Common-Lisp; Package: cells; -*-
+;;;
+;;;
+;;; Copyright (c) 1995,2003 by Kenneth William Tilton.
+;;;
+;;; Permission is hereby granted, free of charge, to any person obtaining a copy
+;;; of this software and associated documentation files (the "Software"), to deal
+;;; in the Software without restriction, including without limitation the rights
+;;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+;;; copies of the Software, and to permit persons to whom the Software is furnished
+;;; to do so, subject to the following conditions:
+;;;
+;;; The above copyright notice and this permission notice shall be included in
+;;; all copies or substantial portions of the Software.
+;;;
+;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+;;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+;;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+;;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+;;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+;;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+;;; IN THE SOFTWARE.
+
+(in-package :cells)
+
+(defmacro maxf (place &rest othervalues)
+ `(setf ,place (max ,place ,@othervalues)))
+
+(defun last1 (thing)
+ (car (last thing)))
+
+(defun max-if (&rest values)
+ (loop for x in values when x maximize x))
+
+(defun min-max-of (v1 v2)
+ (values (min-if v1 v2) (max-if v1 v2)))
+
+(defun min-if (v1 v2)
+ (if v1 (if v2 (min v1 v2) v1) v2))
+
+(defun list-flatten! (&rest list)
+ (if (consp list)
+ (let (head work visited)
+ (labels ((link (cell)
+ ;;(format t "~&Link > cons: ~s . ~s" (car cell) (cdr cell))
+ (when (and (consp cell)
+ (member cell visited))
+ (break "list-flatten! detects infinite list: cell ~a, visited ~a" cell visited))
+ (push cell visited)
+
+ (when cell
+ (if (consp (car cell))
+ (link (car cell))
+ (progn
+ (setf head (or head cell))
+ (when work
+ (rplacd work cell))
+ (setf work cell)))
+ (link (rest cell)))))
+ (link list))
+ head)
+ list))
+
+(defun packed-flat! (&rest uNameit)
+ (delete-if #'null (list-flatten! uNameIt)))
+
+(defmacro with-dynamic-fn ((fnName (&rest fnArgs) &body fnBody) &body body)
+ `(let ((,fnName (lambda ,fnArgs ,@fnBody)))
+ (declare (dynamic-extent ,fnname))
+ ,@body))
+
+(defvar *c-break*)
+
+(defun c-break (&rest args)
+ (unless (or *c-break* *stop*)
+ (setf *c-break* t)
+ (c-stop args)
+ (format t "c-break > stopping > ~a" args)
+ (apply #'break args)))
+
+(defmacro assocv-setf (assoc-place sym-form v-form)
+ (let ((sym (gensym))(entry (gensym))(v (gensym)))
+ `(let* ((,sym ,sym-form)
+ (,v ,v-form))
+ (bIf (,entry (assoc ,sym ,assoc-place))
+ (rplacd ,entry ,v)
+ (push (cons ,sym ,v) ,assoc-place))
+ ,v)))
+
+(defun intern$ (&rest strings)
+ (intern (apply #'concatenate 'string (mapcar #'string-upcase strings))))
+
+#-allegro
+(defmacro until (test &body body)
+ `(LOOP (WHEN ,test (RETURN)) ,@body))
+
+#-allegro
+(defmacro while (test &body body)
+ `(LOOP (unless ,test (RETURN)) ,@body))
+
+(defmacro bwhen ((bindvar boundform) &body body)
+ `(let ((,bindvar ,boundform))
+ (when ,bindvar
+ ,@body)))
+
+(defmacro bif ((bindvar boundform) yup &optional nope)
+ `(let ((,bindvar ,boundform))
+ (if ,bindvar
+ ,yup
+ ,nope)))
+
+(defmacro maptimes ((nvar count) &body body)
+ `(loop for ,nvar below ,count
+ collecting (progn ,@body)))
+
+; --- cloucell support for struct access of slots ------------------------
+
+(eval-when (:compile-toplevel :execute :load-toplevel)
+ (export '(cc-defstruct instance-slots)))
+
+(defmacro cc-defstruct (header &rest slots)
+ (let (name concname (cache (gensym)))
+ (if (consp header)
+ (destructuring-bind (hname &rest options)
+ header
+ (setf name hname)
+ (setf concname (bIf (concoption (find :conc-name options :key #'car))
+ (unless (eql (second concoption) 'nil)
+ (second concoption))
+ (intern (concatenate 'string
+ (symbol-name hname)
+ "-")))))
+ (progn
+ (setf name header)
+ (setf concname (intern (concatenate 'string
+ (symbol-name header) "-")))))
+
+ (let ((cc-info (mapcar (lambda (s)
+ (let ((sn (if (consp s)
+ (car s) s)))
+ (cons sn
+ (intern (concatenate 'string
+ (when concname (symbol-name concname))
+ (symbol-name sn))))))
+ slots)))
+ `(progn
+ (defstruct ,header ,@slots)
+ (let (,cache)
+ (defmethod instance-slots ((self ,name))
+ (or ,cache (setf ,cache (append (call-next-method) ',cc-info)))))
+ ))))
+
+(defmethod instance-slots (root)
+ (declare (ignorable root)))
+
Index: cells/fm-utilities.lisp
diff -u cells/fm-utilities.lisp:1.1.1.1 cells/fm-utilities.lisp:1.2
--- cells/fm-utilities.lisp:1.1.1.1 Sat Nov 8 18:44:17 2003
+++ cells/fm-utilities.lisp Tue Dec 16 10:02:58 2003
@@ -1,557 +1,557 @@
-;; -*- mode: Lisp; Syntax: Common-Lisp; Package: cells; -*-
-;;;
-;;; Copyright © 1995,2003 by Kenneth William Tilton.
-;;;
-;;; Permission is hereby granted, free of charge, to any person obtaining a copy
-;;; of this software and associated documentation files (the "Software"), to deal
-;;; in the Software without restriction, including without limitation the rights
-;;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-;;; copies of the Software, and to permit persons to whom the Software is furnished
-;;; to do so, subject to the following conditions:
-;;;
-;;; The above copyright notice and this permission notice shall be included in
-;;; all copies or substantial portions of the Software.
-;;;
-;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-;;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-;;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-;;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-;;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-;;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-;;; IN THE SOFTWARE.
-
-(in-package :cells)
-
-(defparameter *fmdbg* nil)
-
-(eval-when (compile eval load)
- (export '(make-part mkpart fm-other fm-traverse fm-descendant-typed do-like-fm-parts
- container-typed *fmdbg*)))
-
-(defun make-part (partname partclass &rest initargs)
- ;;(trc "make-part > name class" partname partclass)
- (when partclass ;;a little programmer friendliness
- (apply #'make-instance partclass :md-name partname initargs)))
-
-(defmacro mkpart (md-name (mdclass) &rest initargs)
- `(make-part ',md-name ',mdclass ,@initargs))
-
-(defmethod make-partspec ((partclass symbol))
- (make-part partclass partclass))
-
-(defmethod make-partspec ((part model))
- part)
-
-(defmacro upper (self &optional (type t))
- `(container-typed ,self ',type))
-
-(defmethod container (self) (fmparent self))
-
-(defmethod container-typed ((self model-object) type)
- (assert self)
- (let ((parent (container self))) ;; fm- or ps-parent
- (cond
- ((null parent) nil)
- ((typep parent type) parent)
- (t (container-typed parent type)))))
-
-(defun fm-descendant-typed (self type)
- (when self
- (or (find-if (lambda (k) (typep k type)) (kids self))
- (some (lambda (k)
- (fm-descendant-typed k type)) (kids self)))))
-
-(defun fm-descendant-named (parent name &key (must-find t))
- (fm-find-one parent name :must-find must-find :global-search nil))
-
-(defun fm-ascendant-named (parent name)
- (when parent
- (or (when (eql (md-name parent) name)
- parent)
- (fm-ascendant-named (fmparent parent) name))))
-
-(defun fm-ascendant-typed (parent name)
- (when parent
- (or (when (typep parent name)
- parent)
- (fm-ascendant-typed (fmparent parent) name))))
-
-(defun fm-ascendant-some (parent somefunction)
- (when (and parent somefunction)
- (or (funcall somefunction parent)
- (fm-ascendant-some (fmparent parent) somefunction))))
-
-(defun fm-ascendant-if (self iffunction)
- (when (and self iffunction)
- (or (when (funcall iffunction self)
- self)
- (fm-ascendant-if .parent iffunction))))
-
-(defun fm-ascendant-common (d1 d2)
- (fm-ascendant-some d1 (lambda (node)
- (when (fm-includes node d2)
- node))))
-
-(defun fm-collect-if (tree test)
- (let (collection)
- (fm-traverse tree (lambda (node)
- (when (funcall test node)
- (push node collection))))
- (nreverse collection)))
-
-(defun fm-max (tree key)
- (let (max)
- (fm-traverse tree (lambda (node)
- (if max
- (setf max (max max (funcall key node)))
- (setf max (funcall key node))))
- :global-search nil)
- max))
-
-
-(defun fm-traverse (family applied-fn &key skipnode skiptree (global-search t) (opaque nil))
- (progn ;; wtrc (0 1600 "fm-traverse2" family)
- (labels ((tv-family (fm skippee)
- (when *fmdbg* (trc "tv-family" fm))
-
- (when (and (typep fm 'model-object)
- (not (eql fm skippee)))
- (let ((outcome (unless (eql skipnode fm)
- (funcall applied-fn fm))))
- (unless (and outcome opaque)
- (dolist (kid (sub-nodes fm))
- (tv-family kid nil)))))
- (when (and (typep fm 'model-object)
- (not (eql fm skippee)))
- (let ((outcome (and (not (eql skipnode fm))
- (funcall applied-fn fm))))
- (unless (and outcome opaque)
- (dolist (kid (sub-nodes fm))
- (tv-family kid nil)))))))
-
- (loop for fm = family then (when global-search (fmparent fm))
- and skip = skiptree then fm
- unless fm return nil
- do (when *fmdbg* (print `(fm-traverse using :fm , fm :skip ,skip)))
- (tv-family fm skip)))))
-
-(defmethod sub-nodes (other)
- (declare (ignore other)))
-
-(defmethod sub-nodes ((self family))
- (kids self))
-
-(defmethod fm-ps-parent ((self model-object))
- (fmparent self))
-
-(defmacro with-like-fm-parts ((partsvar (self likeclass)) &body body)
- `(let (,partsvar)
- (fm-traverse ,self (lambda (node)
- ;;(trc "with like sees node" node (type-of node) ',likeclass)
- (when (typep node ',likeclass)
- (push node ,partsvar)))
- :skipnode ,self
- :global-search nil
- :opaque t)
- (setf ,partsvar (nreverse ,partsvar))
- (progn ,@body)))
-
-(defmacro do-like-fm-parts ((partvar (self likeclass) &optional returnvar) &body body)
- `(progn
- (fm-traverse ,self (lambda (,partvar)
- (when (typep ,partvar ',likeclass)
- ,@body))
- :skipnode ,self
- :global-search nil
- :opaque t)
- ,returnvar)
- )
-
-;;
-;; family member finding
-;;
-
-#|
- (defun fm-member-named (kidname kids)
- (member kidname kids :key #'md-name))
- |#
-
-(defun true-that (that) (declare (ignore that)) t)
-;;
-;; eventually fm-find-all needs a better name (as does fm-collect) and they
-;; should be modified to go through 'gather', which should be the real fm-find-all
-;;
-(defun fm-gather (family &key (test #'true-that))
- (packed-flat!
- (cons (when (funcall test family) family)
- (mapcar (lambda (fm)
- (fm-gather fm :test test))
- (kids family)))))
-
-(defun fm-find-all (family md-name &key (must-find t) (global-search t))
- (let ((matches (catch 'fm-find-all
- (with-dynamic-fn
- (traveller (family)
- (with-dynamic-fn
- (filter (kid) (eql md-name (md-name kid)))
- (let ((matches (remove-if-not filter (kids family))))
- (when matches
- (throw 'fm-find-all matches)))))
- (fm-traverse family traveller :global-search global-search)))))
- (when (and must-find (null matches))
- (setf *stop* t)
- (break "fm-find-all > *stop*ping...did not find ~a ~a ~a" family md-name global-search)
- ;; (error 'fm-not-found (list md-name family global-search))
- )
- matches))
-
-(defun fm-find-next (fm test-fn)
- (fm-find-next-within fm test-fn))
-
-(defun fm-find-next-within (fm test-fn &optional upperbound &aux (fmparent (unless (eql upperbound fm)
- (fmparent fm))))
- (let ((sibs (and fmparent (rest (member fm (kids fmparent))))))
- (or (dolist (s sibs)
- (let ((winner (fm-find-if s test-fn)))
- (when winner (return winner))))
- (if fmparent
- (fm-find-next-within fmparent test-fn upperbound)
- (fm-find-if fm test-fn)))))
-
-(defun fm-find-prior (fm test-fn)
- (fm-find-prior-within fm test-fn))
-
-(defun fm-find-prior-within (fm test-fn &optional upperbound &aux (fmparent (unless (eql upperbound fm)
- (fmparent fm))))
- (let ((sibs (and fmparent (kids fmparent))))
- (or (loop with next-ok
- for s on sibs
- for last-ok = nil then (or next-ok last-ok)
- when (eql fm (first s)) do (loop-finish)
- finally (return last-ok)
- do (setf next-ok (fm-find-last-if (car s) test-fn)))
- (if fmparent
- (fm-find-prior-within fmparent test-fn upperbound)
- (fm-find-last-if fm test-fn)))))
-
- (defun fm-find-last-if (family test-fn)
- (let ((last))
- (or (and (kids family)
- (dolist (k (kids family) last)
- (setf last (or (fm-find-last-if k test-fn) last))))
- (when (funcall test-fn family)
- family))))
-
-(defun fm-prior-sib (self &optional (test-fn #'true-that)
- &aux (kids (kids (fmparent self))))
- "Find nearest preceding sibling passing TEST-FN"
- (find-if test-fn kids :end (position self kids) :from-end t))
-
-(defun fm-next-sib-if (self test-fn)
- (some test-fn (cdr (member self (kids (fmparent self))))))
-
-(defun fm-next-sib (self)
- (car (cdr (member self (kids (fmparent self))))))
-
-(defmacro ^fm-next-sib (&optional (self 'self))
- (let ((s (gensym)))
- `(let ((,s ,self))
- (car (cdr (member ,s (^kids (fmparent ,s))))))))
-
-(defun find-prior (self sibs &key (test #'true-that))
- (assert (member self sibs)) ;; got this by accidentally having toolbar kids dependent..on second calc,
- ;; all newkids got over, and when old kids tried to recalculate...not in sibs!!
- (unless (eql self (car sibs))
- (labels
- ((fpsib (rsibs &aux (psib (car rsibs)))
- (assert rsibs () "~&find-prior > fpsib > self ~s not found to prior off" self)
- (if (eql self (cadr rsibs))
- (when (funcall test psib) psib)
- (or (fpsib (cdr rsibs))
- (when (funcall test psib) psib)))))
- (fpsib sibs))))
-
-(defun fm-find-if (family test-fn &key skiptopp) ;; 99-03 kt why is thsi depth-first?
- (assert test-fn)
- (when family
- (or (dolist (b (sub-nodes family))
- (let ((match (fm-find-if b test-fn)))
- (when match (return match))))
- (when (and (not skiptopp)
- (funcall test-fn family))
- family))))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;;;
-;;;; family ordering
-;;;;
-(defun fm-kid-add (fmparent kid &optional before)
- (assert (or (null (fmparent kid)) (eql fmparent (fmparent kid))))
- (assert (typep fmparent 'family))
- (setf (fmparent kid) fmparent)
- (fm-kid-insert kid before))
-
-(defun fm-kid-insert-last (goal &aux (fmparent (fmparent goal)))
- (setf (kids fmparent) (nconc (kids fmparent) (list goal))))
-
-(defun fm-kid-insert-first (goal &aux (fmparent (fmparent goal)))
- (setf (kids fmparent) (cons goal (kids fmparent))))
-
-(defun fm-kid-insert (kid &optional before &aux (dakids (kids (fmparent kid))))
- (assert (or (null before) (eql (fmparent kid) (fmparent before))))
- (setf (kids (fmparent kid))
- (if before
- (if (eql before (car dakids))
- (cons kid dakids)
- (let ((cell (member before dakids)))
- (rplaca cell kid)
- (rplacd cell (cons before (cdr cell)))
- (cons (car dakids) (rest dakids))))
- (if dakids
- (progn
- (rplacd (last dakids) (cons kid nil))
- (cons (car dakids) (rest dakids)))
- (cons kid dakids)))))
-
-(defun fm-kid-remove (kid &key (quiesce t) &aux (parent (fmparent kid)))
- (when quiesce
- (fm-quiesce-all kid))
- (when parent
- (setf (kids parent) (remove kid (kids parent)))
- ;; (setf (fmparent kid) nil) gratuitous housekeeping caused ensuing focus echo
- ;; image-invalidate to fail since no access to containing window via fmparent chain
- ))
-
-(defun fm-quiesce-all (md)
- (md-quiesce md)
- (dolist (kid (kids md))
- (when (and kid (not (md-untouchable kid)))
- (fm-quiesce-all kid)))
- md)
-
-
-(defun fm-kid-replace (oldkid newkid &aux (fmparent (fmparent oldkid)))
- (assert (member oldkid (kids fmparent)) ()
- "~&oldkid ~s not amongst kids of its fmparent ~s"
- oldkid fmparent)
- (when fmparent ;; silly test given above assert--which is right?
- (assert (typep fmparent 'family))
- (setf (fmparent newkid) fmparent)
- (setf (kids fmparent) (substitute newkid oldkid (kids fmparent)))
- ;;(rplaca (member oldkid (kids fmparent)) newkid)
- newkid))
-
-;----------------------------------------------------------
-;;
-;; h i g h - o r d e r f a m i l y o p s
-;;
-;; currently not in use...someday?
-(defmacro ^fm-min-max-kid (min-max slot-name &key (default 0) test (fmparent 'self))
- (let ((best (copy-symbol 'best))
- (kid (copy-symbol 'kid))
- )
- `(let ((,best ,default))
- (dolist (,kid (^kids ,fmparent) ,best)
- ,(if test
- `(when (funcall ,test ,kid)
- (setf ,best (funcall ,min-max ,best (,slot-name ,kid))))
- `(bif (slotvalue (,slot-name ,kid))
- (setf ,best (funcall ,min-max ,best slotvalue))
- (break "nil slotvalue ~a in kid ~a of parent ~a"
- ',slot-name ,kid ,fmparent)))))))
-
-(defmacro ^fm-min-kid (slot-name &key (default 0) test (fmparent 'self))
- `(^fm-min-max-kid #'min-if ,slot-name
- :default ,default
- :test ,test
- :fmparent ,fmparent))
-
-(defmacro ^fm-max-kid (slot-name &key (default 0) test (fmparent 'self))
- `(^fm-min-max-kid #'max-if ,slot-name
- :default ,default
- :test ,test
- :fmparent ,fmparent))
-
-(defmacro ^fm-max-sib (slot-name &key (default 0) test)
- `(^fm-max-kid ,slot-name :default ,default
- :test ,test
- :fmparent (fmparent self)))
-
-(defmacro ^fm-max-sib-other (slot-name &key (default 0))
- `(with-dynamic-fn (tester (sib) (not (eql self sib)))
- (^fm-max-kid ,slot-name :default ,default
- :test tester
- :fmparent (fmparent self))))
-
-(defmacro ^sib-named (name)
- `(find ,name (^kids (fmparent self)) :key #'md-name))
-
-
-(defmacro fm-other (md-name &key (starting 'self) skiptree (test '#'true-that))
- `(fm-find-one ,starting ,(if (consp md-name)
- `(list ',(car md-name) ,(cadr md-name))
- `',md-name)
- :must-find t
- :skiptree ,skiptree
- :global-search t
- :test ,test))
-
-(defmacro fm-otherx (md-name &key (starting 'self) skiptree)
- (if (eql starting 'self)
- `(or (fm-find-one ,starting ,(if (consp md-name)
- `(list ',(car md-name) ,(cadr md-name))
- `',md-name)
- :must-find t
- :skiptree ,skiptree
- :global-search t))
- `(fm-find-one ,starting ,(if (consp md-name)
- `(list ',(car md-name) ,(cadr md-name))
- `',md-name)
- :must-find t
- :skiptree ,skiptree
- :global-search t)))
-
-(defun fm-other-v (md-name starting &optional (global-search t))
- (break)
- (fm-find-one starting md-name
- :must-find nil
- :global-search global-search))
-
-(defmacro fm-otherv? (md-name &optional (starting 'self) (global-search t))
- `(fm-other-v ,md-name ,starting ,global-search))
-
-(defmacro fm-other? (md-name &optional (starting 'self) (global-search t))
- `(fm-find-one ,starting ,(if (consp md-name)
- `(list ',(car md-name) ,(cadr md-name))
- `',md-name)
- :must-find nil
- :global-search ,global-search))
-
-(defun fm! (starting md-name &optional (global-search t))
- (fm-find-one starting md-name
- :must-find t
- :global-search global-search))
-
-(defmacro fm? (md-name &optional (starting 'self) (global-search t))
- `(fm-find-one ,starting ,(if (consp md-name)
- `(list ',(car md-name) ,(cadr md-name))
- `',md-name)
- :must-find nil
- :global-search ,global-search))
-
-(defmacro fm-other! (md-name &optional (starting 'self))
- `(fm-find-one ,starting ,(if (consp md-name)
- `(list ',(car md-name) ,(cadr md-name))
- `',md-name)
- :must-find t
- :global-search nil))
-
-(defmacro fm-other?! (md-name &optional (starting 'self))
- `(fm-find-one ,starting ,(if (consp md-name)
- `(list ',(car md-name) ,(cadr md-name))
- `',md-name)
- :must-find nil
- :global-search nil))
-
-(defmacro fm-collect (md-name &key (must-find t))
- `(fm-find-all self ',md-name :must-find ,must-find)) ;deliberate capture
-
-(defmacro fm-map (fn md-name)
- `(mapcar ,fn (fm-find-all self ',md-name))) ;deliberate capture
-
-(defmacro fm-mapc (fn md-name)
- `(mapc ,fn (fm-find-all self ',md-name))) ;deliberate capture
-
-(defun fm-pos (goal &aux (fmparent (fmparent goal)))
- (when fmparent
- (or (position goal (kids fmparent))
- (length (kids fmparent))))) ;; ?!!
-
-(defmacro fm-count-named (family md-name &key (global-search t))
- `(length (fm-find-all ,family ,md-name
- :must-find nil
- :global-search ,global-search)))
-;---------------------------------------------------------------
-
-(defun fm-top (fm &optional (test #'true-that) &aux (fmparent (fmparent fm)))
- (cond ((null fmparent) fm)
- ((not (funcall test fmparent)) fm)
- (t (fm-top fmparent test))))
-
-(defun fm-first-above (fm &key (test #'true-that) &aux (fmparent (fmparent fm)))
- (cond ((null fmparent) nil)
- ((funcall test fmparent) fmparent)
- (t (fm-first-above fmparent :test test))))
-
-(defun fm-nearest-if (test fm)
- (when fm
- (if (funcall test fm)
- fm
- (fm-nearest-if test (fmparent fm)))))
-
-(defun fm-includes (fm sought)
- (fm-ancestorp fm sought))
-
-(defun fm-ancestorp (fm sought)
- (assert fm)
- (when sought
- (or (eql fm sought)
- (fm-includes fm (fmparent sought)))))
-
-(defun fm-kid-containing (fmparent descendant)
- (with-dynamic-fn (finder (node) (not (eql fmparent node)))
- (fm-top descendant finder)))
-
-(defun make-name (root &optional subscript)
- (if subscript (list root subscript) root))
-
-(defun name-root (md-name)
- (if (atom md-name) md-name (car md-name)))
-
-(defun name-subscript (md-name)
- (when (consp md-name) (cadr md-name)))
-
-(defun fm-find-one (family md-name &key (must-find t)
- (global-search t) skiptree (test #'true-that))
- (flet ((matcher (fm)
- (trc nil "fm-find-one matcher sees" md-name fm (md-name fm))
- (when (and (eql (name-root md-name)
- (or (md-name fm) (c-class-name (class-of fm))))
- (or (null (name-subscript md-name))
- (eql (name-subscript md-name) (fm-pos fm)))
- (funcall test fm))
- (throw 'fm-find-one fm))))
- #-lispworks (declare (dynamic-extent matcher))
- (trc nil "fm-find-one> entry " md-name family)
- (let ((match (catch 'fm-find-one
- (fm-traverse family #'matcher
- :skiptree skiptree
- :global-search global-search))))
- (when (and must-find (null match))
- (trc nil "fm-find-one > erroring fm-not-found" family md-name must-find global-search)
- ;;(inspect family)
- (let ((*fmdbg* family))
- (fm-find-one family md-name :must-find nil :global-search global-search)
- (setf *stop* t)
- ;;(trc "fm-find-one > *stop*ping...did not find" family md-name global-search)
- (break "fm-find-one > *stop*ping...did not find ~a ~a ~a" family md-name global-search)
-
- ))
- match)))
-
-(defun fm-find-kid (self name)
- (find name (kids self) :key #'md-name))
-
-(defun fm-kid-typed (self type)
- (assert self)
- (find type (kids self) :key #'type-of))
-
-(defun kidno (self)
- (unless (typep self 'model-object)
- (break "not a model object ~a" self))
- (when (and self (fmparent self))
- (assert (member self (kids (fmparent self))))
- (position self (kids (fmparent self)))))
-
-
+;; -*- mode: Lisp; Syntax: Common-Lisp; Package: cells; -*-
+;;;
+;;; Copyright (c) 1995,2003 by Kenneth William Tilton.
+;;;
+;;; Permission is hereby granted, free of charge, to any person obtaining a copy
+;;; of this software and associated documentation files (the "Software"), to deal
+;;; in the Software without restriction, including without limitation the rights
+;;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+;;; copies of the Software, and to permit persons to whom the Software is furnished
+;;; to do so, subject to the following conditions:
+;;;
+;;; The above copyright notice and this permission notice shall be included in
+;;; all copies or substantial portions of the Software.
+;;;
+;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+;;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+;;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+;;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+;;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+;;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+;;; IN THE SOFTWARE.
+
+(in-package :cells)
+
+(defparameter *fmdbg* nil)
+
+(eval-when (compile eval load)
+ (export '(make-part mkpart fm-other fm-traverse fm-descendant-typed do-like-fm-parts
+ container-typed *fmdbg*)))
+
+(defun make-part (partname partclass &rest initargs)
+ ;;(trc "make-part > name class" partname partclass)
+ (when partclass ;;a little programmer friendliness
+ (apply #'make-instance partclass :md-name partname initargs)))
+
+(defmacro mkpart (md-name (mdclass) &rest initargs)
+ `(make-part ',md-name ',mdclass ,@initargs))
+
+(defmethod make-partspec ((partclass symbol))
+ (make-part partclass partclass))
+
+(defmethod make-partspec ((part model))
+ part)
+
+(defmacro upper (self &optional (type t))
+ `(container-typed ,self ',type))
+
+(defmethod container (self) (fm-parent self))
+
+(defmethod container-typed ((self model-object) type)
+ (c-assert self)
+ (let ((parent (container self))) ;; fm- or ps-parent
+ (cond
+ ((null parent) nil)
+ ((typep parent type) parent)
+ (t (container-typed parent type)))))
+
+(defun fm-descendant-typed (self type)
+ (when self
+ (or (find-if (lambda (k) (typep k type)) (kids self))
+ (some (lambda (k)
+ (fm-descendant-typed k type)) (kids self)))))
+
+(defun fm-descendant-named (parent name &key (must-find t))
+ (fm-find-one parent name :must-find must-find :global-search nil))
+
+(defun fm-ascendant-named (parent name)
+ (when parent
+ (or (when (eql (md-name parent) name)
+ parent)
+ (fm-ascendant-named (fm-parent parent) name))))
+
+(defun fm-ascendant-typed (parent name)
+ (when parent
+ (or (when (typep parent name)
+ parent)
+ (fm-ascendant-typed (fm-parent parent) name))))
+
+(defun fm-ascendant-some (parent somefunction)
+ (when (and parent somefunction)
+ (or (funcall somefunction parent)
+ (fm-ascendant-some (fm-parent parent) somefunction))))
+
+(defun fm-ascendant-if (self iffunction)
+ (when (and self iffunction)
+ (or (when (funcall iffunction self)
+ self)
+ (fm-ascendant-if .parent iffunction))))
+
+(defun fm-ascendant-common (d1 d2)
+ (fm-ascendant-some d1 (lambda (node)
+ (when (fm-includes node d2)
+ node))))
+
+(defun fm-collect-if (tree test)
+ (let (collection)
+ (fm-traverse tree (lambda (node)
+ (when (funcall test node)
+ (push node collection))))
+ (nreverse collection)))
+
+(defun fm-max (tree key)
+ (let (max)
+ (fm-traverse tree (lambda (node)
+ (if max
+ (setf max (max max (funcall key node)))
+ (setf max (funcall key node))))
+ :global-search nil)
+ max))
+
+
+(defun fm-traverse (family applied-fn &key skipnode skiptree (global-search t) (opaque nil))
+ (progn ;; wtrc (0 1600 "fm-traverse2" family)
+ (labels ((tv-family (fm skippee)
+ (when *fmdbg* (trc "tv-family" fm))
+
+ (when (and (typep fm 'model-object)
+ (not (eql fm skippee)))
+ (let ((outcome (unless (eql skipnode fm)
+ (funcall applied-fn fm))))
+ (unless (and outcome opaque)
+ (dolist (kid (sub-nodes fm))
+ (tv-family kid nil)))))
+ (when (and (typep fm 'model-object)
+ (not (eql fm skippee)))
+ (let ((outcome (and (not (eql skipnode fm))
+ (funcall applied-fn fm))))
+ (unless (and outcome opaque)
+ (dolist (kid (sub-nodes fm))
+ (tv-family kid nil)))))))
+
+ (loop for fm = family then (when global-search (fm-parent fm))
+ and skip = skiptree then fm
+ unless fm return nil
+ do (when *fmdbg* (print `(fm-traverse using :fm , fm :skip ,skip)))
+ (tv-family fm skip)))))
+
+(defmethod sub-nodes (other)
+ (declare (ignore other)))
+
+(defmethod sub-nodes ((self family))
+ (kids self))
+
+(defmethod fm-ps-parent ((self model-object))
+ (fm-parent self))
+
+(defmacro with-like-fm-parts ((partsvar (self likeclass)) &body body)
+ `(let (,partsvar)
+ (fm-traverse ,self (lambda (node)
+ ;;(trc "with like sees node" node (type-of node) ',likeclass)
+ (when (typep node ',likeclass)
+ (push node ,partsvar)))
+ :skipnode ,self
+ :global-search nil
+ :opaque t)
+ (setf ,partsvar (nreverse ,partsvar))
+ (progn ,@body)))
+
+(defmacro do-like-fm-parts ((partvar (self likeclass) &optional returnvar) &body body)
+ `(progn
+ (fm-traverse ,self (lambda (,partvar)
+ (when (typep ,partvar ',likeclass)
+ ,@body))
+ :skipnode ,self
+ :global-search nil
+ :opaque t)
+ ,returnvar)
+ )
+
+;;
+;; family member finding
+;;
+
+#|
+ (defun fm-member-named (kidname kids)
+ (member kidname kids :key #'md-name))
+ |#
+
+(defun true-that (that) (declare (ignore that)) t)
+;;
+;; eventually fm-find-all needs a better name (as does fm-collect) and they
+;; should be modified to go through 'gather', which should be the real fm-find-all
+;;
+(defun fm-gather (family &key (test #'true-that))
+ (packed-flat!
+ (cons (when (funcall test family) family)
+ (mapcar (lambda (fm)
+ (fm-gather fm :test test))
+ (kids family)))))
+
+(defun fm-find-all (family md-name &key (must-find t) (global-search t))
+ (let ((matches (catch 'fm-find-all
+ (with-dynamic-fn
+ (traveller (family)
+ (with-dynamic-fn
+ (filter (kid) (eql md-name (md-name kid)))
+ (let ((matches (remove-if-not filter (kids family))))
+ (when matches
+ (throw 'fm-find-all matches)))))
+ (fm-traverse family traveller :global-search global-search)))))
+ (when (and must-find (null matches))
+ (setf *stop* t)
+ (break "fm-find-all > *stop*ping...did not find ~a ~a ~a" family md-name global-search)
+ ;; (error 'fm-not-found (list md-name family global-search))
+ )
+ matches))
+
+(defun fm-find-next (fm test-fn)
+ (fm-find-next-within fm test-fn))
+
+(defun fm-find-next-within (fm test-fn &optional upperbound &aux (fm-parent (unless (eql upperbound fm)
+ (fm-parent fm))))
+ (let ((sibs (and fm-parent (rest (member fm (kids fm-parent))))))
+ (or (dolist (s sibs)
+ (let ((winner (fm-find-if s test-fn)))
+ (when winner (return winner))))
+ (if fm-parent
+ (fm-find-next-within fm-parent test-fn upperbound)
+ (fm-find-if fm test-fn)))))
+
+(defun fm-find-prior (fm test-fn)
+ (fm-find-prior-within fm test-fn))
+
+(defun fm-find-prior-within (fm test-fn &optional upperbound &aux (fm-parent (unless (eql upperbound fm)
+ (fm-parent fm))))
+ (let ((sibs (and fm-parent (kids fm-parent))))
+ (or (loop with next-ok
+ for s on sibs
+ for last-ok = nil then (or next-ok last-ok)
+ when (eql fm (first s)) do (loop-finish)
+ finally (return last-ok)
+ do (setf next-ok (fm-find-last-if (car s) test-fn)))
+ (if fm-parent
+ (fm-find-prior-within fm-parent test-fn upperbound)
+ (fm-find-last-if fm test-fn)))))
+
+ (defun fm-find-last-if (family test-fn)
+ (let ((last))
+ (or (and (kids family)
+ (dolist (k (kids family) last)
+ (setf last (or (fm-find-last-if k test-fn) last))))
+ (when (funcall test-fn family)
+ family))))
+
+(defun fm-prior-sib (self &optional (test-fn #'true-that)
+ &aux (kids (kids (fm-parent self))))
+ "Find nearest preceding sibling passing TEST-FN"
+ (find-if test-fn kids :end (position self kids) :from-end t))
+
+(defun fm-next-sib-if (self test-fn)
+ (some test-fn (cdr (member self (kids (fm-parent self))))))
+
+(defun fm-next-sib (self)
+ (car (cdr (member self (kids (fm-parent self))))))
+
+(defmacro ^fm-next-sib (&optional (self 'self))
+ (let ((s (gensym)))
+ `(let ((,s ,self))
+ (car (cdr (member ,s (^kids (fm-parent ,s))))))))
+
+(defun find-prior (self sibs &key (test #'true-that))
+ (c-assert (member self sibs)) ;; got this by accidentally having toolbar kids dependent..on second calc,
+ ;; all newkids got over, and when old kids tried to recalculate...not in sibs!!
+ (unless (eql self (car sibs))
+ (labels
+ ((fpsib (rsibs &aux (psib (car rsibs)))
+ (c-assert rsibs () "~&find-prior > fpsib > self ~s not found to prior off" self)
+ (if (eql self (cadr rsibs))
+ (when (funcall test psib) psib)
+ (or (fpsib (cdr rsibs))
+ (when (funcall test psib) psib)))))
+ (fpsib sibs))))
+
+(defun fm-find-if (family test-fn &key skiptopp) ;; 99-03 kt why is thsi depth-first?
+ (c-assert test-fn)
+ (when family
+ (or (dolist (b (sub-nodes family))
+ (let ((match (fm-find-if b test-fn)))
+ (when match (return match))))
+ (when (and (not skiptopp)
+ (funcall test-fn family))
+ family))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;
+;;;; family ordering
+;;;;
+(defun fm-kid-add (fm-parent kid &optional before)
+ (c-assert (or (null (fm-parent kid)) (eql fm-parent (fm-parent kid))))
+ (c-assert (typep fm-parent 'family))
+ (setf (fm-parent kid) fm-parent)
+ (fm-kid-insert kid before))
+
+(defun fm-kid-insert-last (goal &aux (fm-parent (fm-parent goal)))
+ (setf (kids fm-parent) (nconc (kids fm-parent) (list goal))))
+
+(defun fm-kid-insert-first (goal &aux (fm-parent (fm-parent goal)))
+ (setf (kids fm-parent) (cons goal (kids fm-parent))))
+
+(defun fm-kid-insert (kid &optional before &aux (dakids (kids (fm-parent kid))))
+ (c-assert (or (null before) (eql (fm-parent kid) (fm-parent before))))
+ (setf (kids (fm-parent kid))
+ (if before
+ (if (eql before (car dakids))
+ (cons kid dakids)
+ (let ((cell (member before dakids)))
+ (rplaca cell kid)
+ (rplacd cell (cons before (cdr cell)))
+ (cons (car dakids) (rest dakids))))
+ (if dakids
+ (progn
+ (rplacd (last dakids) (cons kid nil))
+ (cons (car dakids) (rest dakids)))
+ (cons kid dakids)))))
+
+(defun fm-kid-remove (kid &key (quiesce t) &aux (parent (fm-parent kid)))
+ (when quiesce
+ (fm-quiesce-all kid))
+ (when parent
+ (setf (kids parent) (remove kid (kids parent)))
+ ;; (setf (fm-parent kid) nil) gratuitous housekeeping caused ensuing focus echo
+ ;; image-invalidate to fail since no access to containing window via fm-parent chain
+ ))
+
+(defun fm-quiesce-all (md)
+ (md-quiesce md)
+ (dolist (kid (kids md))
+ (when (and kid (not (md-untouchable kid)))
+ (fm-quiesce-all kid)))
+ md)
+
+
+(defun fm-kid-replace (oldkid newkid &aux (fm-parent (fm-parent oldkid)))
+ (c-assert (member oldkid (kids fm-parent)) ()
+ "~&oldkid ~s not amongst kids of its fm-parent ~s"
+ oldkid fm-parent)
+ (when fm-parent ;; silly test given above assert--which is right?
+ (c-assert (typep fm-parent 'family))
+ (setf (fm-parent newkid) fm-parent)
+ (setf (kids fm-parent) (substitute newkid oldkid (kids fm-parent)))
+ ;;(rplaca (member oldkid (kids fm-parent)) newkid)
+ newkid))
+
+;----------------------------------------------------------
+;;
+;; h i g h - o r d e r f a m i l y o p s
+;;
+;; currently not in use...someday?
+(defmacro ^fm-min-max-kid (min-max slot-name &key (default 0) test (fm-parent 'self))
+ (let ((best (copy-symbol 'best))
+ (kid (copy-symbol 'kid))
+ )
+ `(let ((,best ,default))
+ (dolist (,kid (^kids ,fm-parent) ,best)
+ ,(if test
+ `(when (funcall ,test ,kid)
+ (setf ,best (funcall ,min-max ,best (,slot-name ,kid))))
+ `(bif (slotvalue (,slot-name ,kid))
+ (setf ,best (funcall ,min-max ,best slotvalue))
+ (break "nil slotvalue ~a in kid ~a of parent ~a"
+ ',slot-name ,kid ,fm-parent)))))))
+
+(defmacro ^fm-min-kid (slot-name &key (default 0) test (fm-parent 'self))
+ `(^fm-min-max-kid #'min-if ,slot-name
+ :default ,default
+ :test ,test
+ :fm-parent ,fm-parent))
+
+(defmacro ^fm-max-kid (slot-name &key (default 0) test (fm-parent 'self))
+ `(^fm-min-max-kid #'max-if ,slot-name
+ :default ,default
+ :test ,test
+ :fm-parent ,fm-parent))
+
+(defmacro ^fm-max-sib (slot-name &key (default 0) test)
+ `(^fm-max-kid ,slot-name :default ,default
+ :test ,test
+ :fm-parent (fm-parent self)))
+
+(defmacro ^fm-max-sib-other (slot-name &key (default 0))
+ `(with-dynamic-fn (tester (sib) (not (eql self sib)))
+ (^fm-max-kid ,slot-name :default ,default
+ :test tester
+ :fm-parent (fm-parent self))))
+
+(defmacro ^sib-named (name)
+ `(find ,name (^kids (fm-parent self)) :key #'md-name))
+
+
+(defmacro fm-other (md-name &key (starting 'self) skiptree (test '#'true-that))
+ `(fm-find-one ,starting ,(if (consp md-name)
+ `(list ',(car md-name) ,(cadr md-name))
+ `',md-name)
+ :must-find t
+ :skiptree ,skiptree
+ :global-search t
+ :test ,test))
+
+(defmacro fm-otherx (md-name &key (starting 'self) skiptree)
+ (if (eql starting 'self)
+ `(or (fm-find-one ,starting ,(if (consp md-name)
+ `(list ',(car md-name) ,(cadr md-name))
+ `',md-name)
+ :must-find t
+ :skiptree ,skiptree
+ :global-search t))
+ `(fm-find-one ,starting ,(if (consp md-name)
+ `(list ',(car md-name) ,(cadr md-name))
+ `',md-name)
+ :must-find t
+ :skiptree ,skiptree
+ :global-search t)))
+
+(defun fm-other-v (md-name starting &optional (global-search t))
+ (break)
+ (fm-find-one starting md-name
+ :must-find nil
+ :global-search global-search))
+
+(defmacro fm-otherv? (md-name &optional (starting 'self) (global-search t))
+ `(fm-other-v ,md-name ,starting ,global-search))
+
+(defmacro fm-other? (md-name &optional (starting 'self) (global-search t))
+ `(fm-find-one ,starting ,(if (consp md-name)
+ `(list ',(car md-name) ,(cadr md-name))
+ `',md-name)
+ :must-find nil
+ :global-search ,global-search))
+
+(defun fm! (starting md-name &optional (global-search t))
+ (fm-find-one starting md-name
+ :must-find t
+ :global-search global-search))
+
+(defmacro fm? (md-name &optional (starting 'self) (global-search t))
+ `(fm-find-one ,starting ,(if (consp md-name)
+ `(list ',(car md-name) ,(cadr md-name))
+ `',md-name)
+ :must-find nil
+ :global-search ,global-search))
+
+(defmacro fm-other! (md-name &optional (starting 'self))
+ `(fm-find-one ,starting ,(if (consp md-name)
+ `(list ',(car md-name) ,(cadr md-name))
+ `',md-name)
+ :must-find t
+ :global-search nil))
+
+(defmacro fm-other?! (md-name &optional (starting 'self))
+ `(fm-find-one ,starting ,(if (consp md-name)
+ `(list ',(car md-name) ,(cadr md-name))
+ `',md-name)
+ :must-find nil
+ :global-search nil))
+
+(defmacro fm-collect (md-name &key (must-find t))
+ `(fm-find-all self ',md-name :must-find ,must-find)) ;deliberate capture
+
+(defmacro fm-map (fn md-name)
+ `(mapcar ,fn (fm-find-all self ',md-name))) ;deliberate capture
+
+(defmacro fm-mapc (fn md-name)
+ `(mapc ,fn (fm-find-all self ',md-name))) ;deliberate capture
+
+(defun fm-pos (goal &aux (fm-parent (fm-parent goal)))
+ (when fm-parent
+ (or (position goal (kids fm-parent))
+ (length (kids fm-parent))))) ;; ?!!
+
+(defmacro fm-count-named (family md-name &key (global-search t))
+ `(length (fm-find-all ,family ,md-name
+ :must-find nil
+ :global-search ,global-search)))
+;---------------------------------------------------------------
+
+(defun fm-top (fm &optional (test #'true-that) &aux (fm-parent (fm-parent fm)))
+ (cond ((null fm-parent) fm)
+ ((not (funcall test fm-parent)) fm)
+ (t (fm-top fm-parent test))))
+
+(defun fm-first-above (fm &key (test #'true-that) &aux (fm-parent (fm-parent fm)))
+ (cond ((null fm-parent) nil)
+ ((funcall test fm-parent) fm-parent)
+ (t (fm-first-above fm-parent :test test))))
+
+(defun fm-nearest-if (test fm)
+ (when fm
+ (if (funcall test fm)
+ fm
+ (fm-nearest-if test (fm-parent fm)))))
+
+(defun fm-includes (fm sought)
+ (fm-ancestorp fm sought))
+
+(defun fm-ancestorp (fm sought)
+ (c-assert fm)
+ (when sought
+ (or (eql fm sought)
+ (fm-includes fm (fm-parent sought)))))
+
+(defun fm-kid-containing (fm-parent descendant)
+ (with-dynamic-fn (finder (node) (not (eql fm-parent node)))
+ (fm-top descendant finder)))
+
+(defun make-name (root &optional subscript)
+ (if subscript (list root subscript) root))
+
+(defun name-root (md-name)
+ (if (atom md-name) md-name (car md-name)))
+
+(defun name-subscript (md-name)
+ (when (consp md-name) (cadr md-name)))
+
+(defun fm-find-one (family md-name &key (must-find t)
+ (global-search t) skiptree (test #'true-that))
+ (flet ((matcher (fm)
+ (trc nil "fm-find-one matcher sees" md-name fm (md-name fm))
+ (when (and (eql (name-root md-name)
+ (or (md-name fm) (c-class-name (class-of fm))))
+ (or (null (name-subscript md-name))
+ (eql (name-subscript md-name) (fm-pos fm)))
+ (funcall test fm))
+ (throw 'fm-find-one fm))))
+ #-lispworks (declare (dynamic-extent matcher))
+ (trc nil "fm-find-one> entry " md-name family)
+ (let ((match (catch 'fm-find-one
+ (fm-traverse family #'matcher
+ :skiptree skiptree
+ :global-search global-search))))
+ (when (and must-find (null match))
+ (trc nil "fm-find-one > erroring fm-not-found" family md-name must-find global-search)
+ ;;(inspect family)
+ (let ((*fmdbg* family))
+ (fm-find-one family md-name :must-find nil :global-search global-search)
+ (setf *stop* t)
+ ;;(trc "fm-find-one > *stop*ping...did not find" family md-name global-search)
+ (break "fm-find-one > *stop*ping...did not find ~a ~a ~a" family md-name global-search)
+
+ ))
+ match)))
+
+(defun fm-find-kid (self name)
+ (find name (kids self) :key #'md-name))
+
+(defun fm-kid-typed (self type)
+ (c-assert self)
+ (find type (kids self) :key #'type-of))
+
+(defun kid-no (self)
+ (unless (typep self 'model-object)
+ (break "not a model object ~a" self))
+ (when (and self (fm-parent self))
+ (c-assert (member self (kids (fm-parent self))))
+ (position self (kids (fm-parent self)))))
+
+
Index: cells/initialize.lisp
diff -u cells/initialize.lisp:1.1.1.1 cells/initialize.lisp:1.2
--- cells/initialize.lisp:1.1.1.1 Sat Nov 8 18:44:17 2003
+++ cells/initialize.lisp Tue Dec 16 10:02:58 2003
@@ -1,105 +1,105 @@
-;; -*- mode: Lisp; Syntax: Common-Lisp; Package: cells; -*-
-;;;
-;;; Copyright © 1995,2003 by Kenneth William Tilton.
-;;;
-;;; Permission is hereby granted, free of charge, to any person obtaining a copy
-;;; of this software and associated documentation files (the "Software"), to deal
-;;; in the Software without restriction, including without limitation the rights
-;;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-;;; copies of the Software, and to permit persons to whom the Software is furnished
-;;; to do so, subject to the following conditions:
-;;;
-;;; The above copyright notice and this permission notice shall be included in
-;;; all copies or substantial portions of the Software.
-;;;
-;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-;;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-;;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-;;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-;;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-;;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-;;; IN THE SOFTWARE.
-
-(in-package :cells)
-
-(eval-when (compile eval load)
- (export '(c-envalue)))
-
-(cc-defstruct (c-envaluer (:conc-name nil))
- envaluerule
- )
-
-(defun c-awaken (c)
- (when *stop*
- (princ #\.)
- (return-from c-awaken))
-
- (assert (c-model c) () "c-awaken sees uninstalled cell" c)
-
- ; re-entry happen's normally
- ; nop it...
- ;
- (when (c-waking-state c)
- ;;(count-it :c-awaken :already)
- ;;(trc "c-awaken > already awake" c)
- (return-from c-awaken))
-
- ;;(trc "c-awaken > awakening" c)
- ;;(count-it :c-awaken)
- (setf (c-waking-state c) :awakening)
- (c-awaken-cell c)
- (setf (c-waking-state c) :awake)
- c)
-
-(defun c-ephemeral-p (c)
- (eql :ephemeral (md-slot-cell-type (type-of (c-model c)) (c-slot-name c))))
-
-(defmethod c-awaken-cell (c)
- (declare (ignorable c)))
-
-(defmethod c-awaken-cell ((c c-variable))
- (when (and (c-ephemeral-p c)
- (c-value c))
- (error "Feature not yet supported: initializing ephemeral to other than nil: [~a]"
- (c-value c)))
- ;
- ; nothing to calculate, but every cellular slot should be echoed
- ;
- (let ((v (c-value c)))
- ;;(trc (c-model c) "c-awaken > calling echo" c v (slot-value (c-model c)(c-slot-name c)))
- (when (eql '.kids (c-slot-name c))
- (md-kids-change (c-model c) v nil :c-awaken-variable))
- (c-echo-slot-name (c-slot-name c) (c-model c) v nil nil)
- (c-ephemeral-reset c)))
-
-(defmethod c-awaken-cell ((c c-ruled))
- ;
- ; ^svuc (with askers supplied) calls c-awaken, and now we call ^svuc crucially without askers
- ; this oddity comes from an incident in which an asker-free invocation of ^svuc
- ; successfully calculated when the call passing askers failed, i guess because askers not
- ; actually to be consulted given the algorithm still were detected as self-referential
- ; since the self-ref detector could not anticipate the algorithm's branching.
- ;
- (let (*c-calculators*)
- (c-calculate-and-set c)))
-
-(defmethod c-awaken-cell ((c c-dependent))
- ;
- ; satisfy CormanCL bug
- ;
- (let (*c-calculators*)
- (c-calculate-and-set c)))
-
-(defmethod c-awaken-cell ((c c-drifter))
- ;
- ; drifters *begin* valid, so the derived version's test for unbounditude
- ; would keep (drift) rule ever from being evaluated. correct solution
- ; (for another day) is to separate awakening (ie, linking to independent
- ; cs) from evaluation, tho also evaluating if necessary during
- ; awakening, because awakening's other role is to get an instance up to speed
- ; at once upon instantiation
- ;
- (c-calculate-and-set c)
- (cond ((c-validp c) (c-value c))
- ((c-unboundp c) nil)
- (t "illegal state!!!")))
+;; -*- mode: Lisp; Syntax: Common-Lisp; Package: cells; -*-
+;;;
+;;; Copyright (c) 1995,2003 by Kenneth William Tilton.
+;;;
+;;; Permission is hereby granted, free of charge, to any person obtaining a copy
+;;; of this software and associated documentation files (the "Software"), to deal
+;;; in the Software without restriction, including without limitation the rights
+;;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+;;; copies of the Software, and to permit persons to whom the Software is furnished
+;;; to do so, subject to the following conditions:
+;;;
+;;; The above copyright notice and this permission notice shall be included in
+;;; all copies or substantial portions of the Software.
+;;;
+;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+;;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+;;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+;;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+;;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+;;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+;;; IN THE SOFTWARE.
+
+(in-package :cells)
+
+(eval-when (compile eval load)
+ (export '(c-envalue)))
+
+(defstruct (c-envaluer (:conc-name nil))
+ envaluerule
+ )
+
+(defun c-awaken (c)
+ (when *stop*
+ (princ #\.)
+ (return-from c-awaken))
+
+ (c-assert (c-model c) () "c-awaken sees uninstalled cell" c)
+
+ ; re-entry happen's normally
+ ; nop it...
+ ;
+ (when (c-waking-state c)
+ ;;(count-it :c-awaken :already)
+ ;;(trc "c-awaken > already awake" c)
+ (return-from c-awaken))
+
+ ;;(trc "c-awaken > awakening" c)
+ ;;(count-it :c-awaken)
+ (setf (c-waking-state c) :awakening)
+ (c-awaken-cell c)
+ (setf (c-waking-state c) :awake)
+ c)
+
+(defun c-ephemeral-p (c)
+ (eql :ephemeral (md-slot-cell-type (type-of (c-model c)) (c-slot-name c))))
+
+(defmethod c-awaken-cell (c)
+ (declare (ignorable c)))
+
+(defmethod c-awaken-cell ((c c-variable))
+ (when (and (c-ephemeral-p c)
+ (c-value c))
+ (c-break "Feature not yet supported: initializing ephemeral to other than nil: [~a]"
+ (c-value c)))
+ ;
+ ; nothing to calculate, but every cellular slot should be echoed
+ ;
+ (let ((v (c-value c)))
+ ;;(trc (c-model c) "c-awaken > calling echo" c v (slot-value (c-model c)(c-slot-name c)))
+ (when (eql '.kids (c-slot-name c))
+ (md-kids-change (c-model c) v nil :c-awaken-variable))
+ (c-echo-slot-name (c-slot-name c) (c-model c) v nil nil)
+ (c-ephemeral-reset c)))
+
+(defmethod c-awaken-cell ((c c-ruled))
+ ;
+ ; ^svuc (with askers supplied) calls c-awaken, and now we call ^svuc crucially without askers
+ ; this oddity comes from an incident in which an asker-free invocation of ^svuc
+ ; successfully calculated when the call passing askers failed, i guess because askers not
+ ; actually to be consulted given the algorithm still were detected as self-referential
+ ; since the self-ref detector could not anticipate the algorithm's branching.
+ ;
+ (let (*c-calculators*)
+ (c-calculate-and-set c)))
+
+(defmethod c-awaken-cell ((c c-dependent))
+ ;
+ ; satisfy CormanCL bug
+ ;
+ (let (*c-calculators*)
+ (c-calculate-and-set c)))
+
+(defmethod c-awaken-cell ((c c-drifter))
+ ;
+ ; drifters *begin* valid, so the derived version's test for unbounditude
+ ; would keep (drift) rule ever from being evaluated. correct solution
+ ; (for another day) is to separate awakening (ie, linking to independent
+ ; cs) from evaluation, tho also evaluating if necessary during
+ ; awakening, because awakening's other role is to get an instance up to speed
+ ; at once upon instantiation
+ ;
+ (c-calculate-and-set c)
+ (cond ((c-validp c) (c-value c))
+ ((c-unboundp c) nil)
+ (t "illegal state!!!")))
Index: cells/link.lisp
diff -u cells/link.lisp:1.1.1.1 cells/link.lisp:1.2
--- cells/link.lisp:1.1.1.1 Sat Nov 8 18:44:28 2003
+++ cells/link.lisp Tue Dec 16 10:02:58 2003
@@ -1,226 +1,226 @@
-;; -*- mode: Lisp; Syntax: Common-Lisp; Package: cells; -*-
-;;;
-;;; Copyright © 1995,2003 by Kenneth William Tilton.
-;;;
-;;; Permission is hereby granted, free of charge, to any person obtaining a copy
-;;; of this software and associated documentation files (the "Software"), to deal
-;;; in the Software without restriction, including without limitation the rights
-;;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-;;; copies of the Software, and to permit persons to whom the Software is furnished
-;;; to do so, subject to the following conditions:
-;;;
-;;; The above copyright notice and this permission notice shall be included in
-;;; all copies or substantial portions of the Software.
-;;;
-;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-;;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-;;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-;;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-;;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-;;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-;;; IN THE SOFTWARE.
-
-(in-package :cells)
-
-
-(defun c-link-ex (used &aux (user (car *c-calculators*)))
-
- (cond
- ((cmdead user) (return-from c-link-ex nil))
- ((null used)
- ;
- ; no cell on used value so it is constant, but if a synapse is involved the constant
- ; must still be filtered thru that, albeit only this once
- ;
- (when *synapse-factory*
- (assert (car *c-calculators*)) ;; sanity-check
- (funcall *synapse-factory* nil (car *c-calculators*))))
-
- ((or (not (typep used 'c-user-notifying))
- (and (typep used 'c-dependent)
- (c-optimized-away-p used)))
- (return-from c-link-ex nil))
-
- (t
- ;
- ; --------- debug stuff --------------
- (assert user)
- (assert (not (cmdead user)) () "dead user in link-ex ~a, used being ~a" user used)
- (assert (not (cmdead used)) () "dead used in link-ex ~a, user being ~a" used user)
-
- #+dfdbg (trc user "c-link > user, used" user used)
- (assert (not (eq :eternal-rest (md-state (c-model user)))))
- (assert (not (eq :eternal-rest (md-state (c-model used)))))
- (count-it :c-link-entry)
- (when *c-debug*
- (assert (or (null *synapse-factory*)
- (functionp *synapse-factory*))
- ()
- "~s is not a function, but was supplied as a synapse factory between ~s and ~s. probably parentheses wrong, as in (- (^lr x 96))"
- *synapse-factory* used user))
-
- (let ((used-link
- (or
- ;; check if linked already
- ;; /// looks like a bug: cannot have two synaptic dependencies on same
- ;; /// cell slot...probably need to "name" the synapses just for this purpose
- ;;
- (c-find-used-link user used)
- ;;
- ;; following may have been a goof, but i like it: let synapse factory
- ;; decide not to produce a synapse, in which case dumb direct c-cell link
- ;; gets created.
- ;;
- (bwhen (syn (and *synapse-factory*
- (funcall *synapse-factory* used user)))
- (c-add-user used syn)
- (c-add-used user syn)
- ;;(trc used "c-link> users now:" (mapcar #'celltrueuser (un-users used)))
- (trc nil "setting used to syn" syn used)
- syn)
- ;;
- ;; make dumb link: used just tells user to rethink.
- ;;
- (progn
- (trc nil "c-link > new user,used " user used)
- (c-add-user used user)
- (c-add-used user used)
- used))))
-
- (assert used-link)
- (assert (position used-link (cd-useds user))
- ()
- "used-link ~a does not appear in useds ~a of user ~a"
- used-link (cd-useds user) user)
-
- (let ((mapn (- *cd-usagect*
- (- (length (cd-useds user))
- (or (position used-link (cd-useds user)) 0)))))
- ;; (trc user "c-link> setting usage bit" user mapn used-link)
- (if (minusp mapn)
- (break "whoa. more than ~d used? i see ~d" *cd-usagect* (length (cd-useds user)))
- (cd-usage-set user mapn)))
- used-link))))
-
-(defun cd-usage-set (c mapn)
- (when (typep c 'synapse)
- (setf (syn-relevant c) t))
- (setf (sbit (cd-usage c) mapn) 1))
-
-(defun cd-usage-clear-all (c)
- (bit-and (cd-usage c)
- #*0000000000000000000000000000000000000000000000000000000000000000
- t))
-
-(defun c-find-used-link (user-cell used)
- "find any existing link to user-cell, the cell itself if direct or a synapse leading to it"
- (some (lambda (user)
- (if (typep user 'synapse)
- (when (eql user-cell (syn-user user))
- user) ;; the synapse is the used link
- (when (eql user-cell user)
- used))) ;; the link to used is direct (non-synaptic)
- (un-users used)))
-
-(defun c-add-user (used user)
- (count-it :c-adduser)
-
- (typecase used
- (c-user-notifying
- (trc nil "c-add-user conventional > user, used" user used)
- (pushnew user (un-users used)))
-
- (synapse (setf (syn-user used) user)))
-
- used)
-
-(defun c-user-path-exists-p (from-used to-user)
- (typecase from-used
- (synapse (c-user-path-exists-p (syn-user from-used) to-user))
- (c-user-notifying
- (or (find to-user (un-users from-used))
- (find-if (lambda (from-used-user)
- (c-user-path-exists-p (c-user-true from-used-user) to-user))
- (un-users from-used))))))
-
-; -----------
-
-(defun c-add-used (user used)
- (count-it :c-used)
- #+ucount (unless (member used (cd-useds user))
- (incf *cd-useds*)
- (when (zerop (mod *cd-useds* 100))
- (trc "useds count = " *cd-useds*)))
- (pushnew used (cd-useds user))
- (trc nil "c-add-used> user <= used" user used (length (cd-useds user)))
- (mapcar 'c-users-resort (cd-useds user))
- (cd-useds user))
-
-(defun c-users-resort (used)
- (typecase used
- (synapse (c-users-resort (syn-used used)))
- (c-user-notifying
- (when (second (un-users used))
- (setf (un-users used) (sort (un-users used) 'c-user-path-exists-p))
- (trc nil "c-users-resort resorted users > used" used (mapcar 'c-slot-name (un-users used)))
- (mapcar 'c-users-resort (c-useds used))))))
-
-(defmethod c-useds (other) (declare (ignore other)))
-(defmethod c-useds ((c c-dependent)) (cd-useds c))
-
-
-(defun c-quiesce (c)
- (typecase c
- (cell
- (trc nil "c-quiesce unlinking" c)
- (c-unlink-from-used c)
- (when (typep c 'c-user-notifying)
- (dolist (user (un-users c))
- (c-unlink-user c user)))
- (c-pending-set c nil :c-quiesce)
- ;;; (setf (c-waking-state c) nil)
- ;;; (when (eql :rpthead (c-model c))
- (trc nil "cell quiesce nulled cell awake" c))))
-
-;-------------------------
-
-(defmethod c-unlink-from-used ((user c-dependent))
- (dolist (used (cd-useds user))
- #+dfdbg (trc user "unlinking from used" user used)
- (c-unlink-user used user))
- ;; shouldn't be necessary (setf (cd-useds user) nil)
- )
-
-(defmethod c-unlink-from-used (other)
- (declare (ignore other)))
-
-;----------------------------------------------------------
-
-(defmethod c-unlink-user ((used c-user-notifying) user)
- #+dfdbg (trc user "user unlinking from used" user used)
- (setf (un-users used) (delete user (un-users used)))
- (c-unlink-used user used))
-
-(defmethod c-unlink-user ((syn synapse) user)
- (assert (eq user (syn-user syn)))
- (c-unlink-user (syn-used syn) syn)
- (setf (syn-user syn) nil) ;; gc-paranoia?
- )
-
-;-----------------------------------------------------------
-
-
-(defmethod c-unlink-used ((user c-dependent) used)
- (setf (cd-useds user) (delete used (cd-useds user))))
-
-(defmethod c-unlink-used ((syn synapse) used)
- (assert (eq used (syn-used syn)))
- (setf (syn-used syn) nil)
- (c-unlink-used (syn-user syn) syn))
-
-; --- very low-vel abstraction
-
-(defmethod c-user-true (c) c)
-(defmethod c-user-true ((syn synapse)) (syn-user syn))
-(defmethod c-used-true (c) c)
-(defmethod c-used-true ((syn synapse)) (syn-used syn))
+;; -*- mode: Lisp; Syntax: Common-Lisp; Package: cells; -*-
+;;;
+;;; Copyright (c) 1995,2003 by Kenneth William Tilton.
+;;;
+;;; Permission is hereby granted, free of charge, to any person obtaining a copy
+;;; of this software and associated documentation files (the "Software"), to deal
+;;; in the Software without restriction, including without limitation the rights
+;;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+;;; copies of the Software, and to permit persons to whom the Software is furnished
+;;; to do so, subject to the following conditions:
+;;;
+;;; The above copyright notice and this permission notice shall be included in
+;;; all copies or substantial portions of the Software.
+;;;
+;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+;;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+;;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+;;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+;;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+;;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+;;; IN THE SOFTWARE.
+
+(in-package :cells)
+
+
+(defun c-link-ex (used &aux (user (car *c-calculators*)))
+ (c-assert user)
+ (cond
+ ((cmdead user) (return-from c-link-ex nil))
+ ((null used)
+ ;
+ ; no cell on used value so it is constant, but if a synapse is involved the constant
+ ; must still be filtered thru that, albeit only this once
+ ;
+ (when *synapse-factory*
+ (c-assert (car *c-calculators*)) ;; sanity-check
+ (funcall *synapse-factory* nil (car *c-calculators*))))
+
+ ((or (not (typep used 'cell))
+ (and (typep used 'c-dependent)
+ (c-optimized-away-p used)))
+ (return-from c-link-ex nil))
+
+ (t
+ ;
+ ; --------- debug stuff --------------
+ (c-assert user)
+ (c-assert (not (cmdead user)) () "dead user in link-ex ~a, used being ~a" user used)
+ (c-assert (not (cmdead used)) () "dead used in link-ex ~a, user being ~a" used user)
+
+ #+dfdbg (trc user "c-link > user, used" user used)
+ (c-assert (not (eq :eternal-rest (md-state (c-model user)))))
+ (c-assert (not (eq :eternal-rest (md-state (c-model used)))))
+ (count-it :c-link-entry)
+ (when *c-debug*
+ (c-assert (or (null *synapse-factory*)
+ (functionp *synapse-factory*))
+ ()
+ "~s is not a function, but was supplied as a synapse factory between ~s and ~s. probably parentheses wrong, as in (- (^lr x 96))"
+ *synapse-factory* used user))
+
+ (let ((used-link
+ (or
+ ;; check if linked already
+ ;; /// looks like a bug: cannot have two synaptic dependencies on same
+ ;; /// cell slot...probably need to "name" the synapses just for this purpose
+ ;;
+ (c-find-used-link user used)
+ ;;
+ ;; following may have been a goof, but i like it: let synapse factory
+ ;; decide not to produce a synapse, in which case dumb direct c-cell link
+ ;; gets created.
+ ;;
+ (bwhen (syn (and *synapse-factory*
+ (funcall *synapse-factory* used user)))
+ (c-add-user used syn)
+ (c-add-used user syn)
+ ;;(trc used "c-link> users now:" (mapcar #'celltrueuser (c-users used)))
+ (trc nil "setting used to syn" syn used)
+ syn)
+ ;;
+ ;; make dumb link: used just tells user to rethink.
+ ;;
+ (progn
+ (trc nil "c-link > new user,used " user used)
+ (c-add-user used user)
+ (c-add-used user used)
+ used))))
+
+ (c-assert used-link)
+ (c-assert (position used-link (cd-useds user))
+ ()
+ "used-link ~a does not appear in useds ~a of user ~a"
+ used-link (cd-useds user) user)
+
+ (let ((mapn (- *cd-usagect*
+ (- (length (cd-useds user))
+ (or (position used-link (cd-useds user)) 0)))))
+ ;; (trc user "c-link> setting usage bit" user mapn used-link)
+ (if (minusp mapn)
+ (break "whoa. more than ~d used? i see ~d" *cd-usagect* (length (cd-useds user)))
+ (cd-usage-set user mapn)))
+ used-link))))
+
+(defun cd-usage-set (c mapn)
+ (when (typep c 'synapse)
+ (setf (syn-relevant c) t))
+ (setf (sbit (cd-usage c) mapn) 1))
+
+(defun cd-usage-clear-all (c)
+ (bit-and (cd-usage c)
+ #*0000000000000000000000000000000000000000000000000000000000000000
+ t))
+
+(defun c-find-used-link (user-cell used)
+ "find any existing link to user-cell, the cell itself if direct or a synapse leading to it"
+ (some (lambda (user)
+ (if (typep user 'synapse)
+ (when (eql user-cell (syn-user user))
+ user) ;; the synapse is the used link
+ (when (eql user-cell user)
+ used))) ;; the link to used is direct (non-synaptic)
+ (c-users used)))
+
+(defun c-add-user (used user)
+ (count-it :c-adduser)
+
+ (typecase used
+ (cell
+ (trc nil "c-add-user conventional > user, used" user used)
+ (pushnew user (c-users used)))
+
+ (synapse (setf (syn-user used) user)))
+
+ used)
+
+(defun c-user-path-exists-p (from-used to-user)
+ (typecase from-used
+ (synapse (c-user-path-exists-p (syn-user from-used) to-user))
+ (cell
+ (or (find to-user (c-users from-used))
+ (find-if (lambda (from-used-user)
+ (c-user-path-exists-p (c-user-true from-used-user) to-user))
+ (c-users from-used))))))
+
+; -----------
+
+(defun c-add-used (user used)
+ (count-it :c-used)
+ #+ucount (unless (member used (cd-useds user))
+ (incf *cd-useds*)
+ (when (zerop (mod *cd-useds* 100))
+ (trc "useds count = " *cd-useds*)))
+ (pushnew used (cd-useds user))
+ (trc nil "c-add-used> user <= used" user used (length (cd-useds user)))
+ (mapcar 'c-users-resort (cd-useds user))
+ (cd-useds user))
+
+(defun c-users-resort (used)
+ (typecase used
+ (synapse (c-users-resort (syn-used used)))
+ (cell
+ (when (second (c-users used))
+ (setf (c-users used) (sort (c-users used) 'c-user-path-exists-p))
+ (trc nil "c-users-resort resorted users > used" used (mapcar 'c-slot-name (c-users used)))
+ (mapcar 'c-users-resort (c-useds used))))))
+
+(defmethod c-useds (other) (declare (ignore other)))
+(defmethod c-useds ((c c-dependent)) (cd-useds c))
+
+
+(defun c-quiesce (c)
+ (typecase c
+ (cell
+ (trc nil "c-quiesce unlinking" c)
+ (c-unlink-from-used c)
+ (when (typep c 'cell)
+ (dolist (user (c-users c))
+ (c-unlink-user c user)))
+ (c-pending-set c nil :c-quiesce)
+ ;;; (setf (c-waking-state c) nil)
+ ;;; (when (eql :rpthead (c-model c))
+ (trc nil "cell quiesce nulled cell awake" c))))
+
+;-------------------------
+
+(defmethod c-unlink-from-used ((user c-dependent))
+ (dolist (used (cd-useds user))
+ #+dfdbg (trc user "unlinking from used" user used)
+ (c-unlink-user used user))
+ ;; shouldn't be necessary (setf (cd-useds user) nil)
+ )
+
+(defmethod c-unlink-from-used (other)
+ (declare (ignore other)))
+
+;----------------------------------------------------------
+
+(defmethod c-unlink-user ((used cell) user)
+ #+dfdbg (trc user "user unlinking from used" user used)
+ (setf (c-users used) (delete user (c-users used)))
+ (c-unlink-used user used))
+
+(defmethod c-unlink-user ((syn synapse) user)
+ (c-assert (eq user (syn-user syn)))
+ (c-unlink-user (syn-used syn) syn)
+ (setf (syn-user syn) nil) ;; gc-paranoia?
+ )
+
+;-----------------------------------------------------------
+
+
+(defmethod c-unlink-used ((user c-dependent) used)
+ (setf (cd-useds user) (delete used (cd-useds user))))
+
+(defmethod c-unlink-used ((syn synapse) used)
+ (c-assert (eq used (syn-used syn)))
+ (setf (syn-used syn) nil)
+ (c-unlink-used (syn-user syn) syn))
+
+; --- very low-vel abstraction
+
+(defmethod c-user-true (c) c)
+(defmethod c-user-true ((syn synapse)) (syn-user syn))
+(defmethod c-used-true (c) c)
+(defmethod c-used-true ((syn synapse)) (syn-used syn))
Index: cells/md-slot-value.lisp
diff -u cells/md-slot-value.lisp:1.1.1.1 cells/md-slot-value.lisp:1.2
--- cells/md-slot-value.lisp:1.1.1.1 Sat Nov 8 18:44:28 2003
+++ cells/md-slot-value.lisp Tue Dec 16 10:02:58 2003
@@ -1,153 +1,150 @@
-;; -*- mode: Lisp; Syntax: Common-Lisp; Package: cells; -*-
-;;;
-;;; Copyright © 1995,2003 by Kenneth William Tilton.
-;;;
-;;; Permission is hereby granted, free of charge, to any person obtaining a copy
-;;; of this software and associated documentation files (the "Software"), to deal
-;;; in the Software without restriction, including without limitation the rights
-;;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-;;; copies of the Software, and to permit persons to whom the Software is furnished
-;;; to do so, subject to the following conditions:
-;;;
-;;; The above copyright notice and this permission notice shall be included in
-;;; all copies or substantial portions of the Software.
-;;;
-;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-;;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-;;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-;;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-;;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-;;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-;;; IN THE SOFTWARE.
-
-(in-package :cells)
-
-(defun md-slot-cell-flushed (self slot-spec)
- (assocv (slot-spec-name slot-spec) (cells-flushed self)))
-
-(defun md-slot-value (self slot-spec &aux (slot-c (md-slot-cell self slot-spec)))
- (when *stop*
- (princ #\.)
- (return-from md-slot-value))
- ;; (count-it :md-slot-value (slot-spec-name slot-spec))
- #+badidea(when (mdead self)
- (trc "md-slot-value> model dead" (type-of self) slot-spec)
- (return-from md-slot-value nil))
- (when (eql :nascent (md-state self))
- (md-awaken self))
-
- ; this next bit is not written (c-relay-value <link> (etypecase slot-c...))
- ; because that would link before accessing possibly an invalid ruled slot
- ; (during md-awaken), and after calculating it would propagate to users and
- ; re-enter this calculation. Switching the order of the parameters would
- ; also work, but we need to document this very specific order of operations
- ; anyway, can't just leave that to the left-right thing.
- ;
- (let ((slot-value (etypecase slot-c
- (null (bd-slot-value self slot-spec))
- (c-variable (c-value slot-c))
- (c-ruled (c-ruled-slot-value slot-c)))))
- (c-relay-value
- (when (car *c-calculators*)
- (c-link-ex slot-c))
- slot-value)))
-
-(defun c-ruled-slot-value (slot-c)
- (trc nil "c-ruled-slot-value entry" slot-c)
- (assert (not (cmdead slot-c)))
-
- (cond
- ((c-validp slot-c)
- (if (c-true-stalep slot-c)
- (c-calculate-and-set slot-c) ;; new for 2003-09-14
- (bif (deep (cd-deep-stale slot-c))
- (progn
- (trc nil "valid ~a :but-deepstale ~a, cause: ~a. calcing"
- slot-c deep *cause*)
- (c-calculate-and-set slot-c))
- #+worked (progn
- (trc "valid ~a :but-deepstale ~a, cause: ~a. calcing"
- slot-c deep *cause*)
- (c-calculate-and-set deep)
- (bIf (deep2 (cd-deep-stale slot-c))
- (break "deep, deep trouble ~a :deep2 ~a :deep1 ~a, cause: ~a."
- slot-c deep2 deep *cause*)
- (progn
- (trc "cleared valid with deep stale" slot-c)
- (c-calculate-and-set slot-c))))
- (c-value slot-c)))) ;; good to go
-
- (t (let ((*cause* :on-demand)) ; normal path first time asked
- (trc (plusp *trcdepth*) "md-slot-value calc" slot-c *c-calculators*)
- (c-calculate-and-set slot-c)))))
-
-;-------------------------------------------------------------
-
-(defun (setf md-slot-value) (newvalue self slot-spec)
- (when (mdead self)
- (return-from md-slot-value))
- (let ((c (md-slot-cell self slot-spec)))
-
- (when *c-debug*
- (c-setting-debug self slot-spec c newvalue))
-
- (unless c
- (cellstop)
- (error "(setf md-slot-value)> cellular slot ~a of ~a cannot be setf unless initialized to c-variable"
- slot-spec self)
- )
-
- (if (unst-setting-p c)
- (if (unst-cyclic-p c)
- newvalue
- (error "setf of ~a propagated back; declare as cyclic (cv8...)" c))
- (let ((absorbedvalue (c-absorb-value c newvalue)))
- ;;(assert (not (mdead self)))
- (with-dataflow-management (c)
- (md-slot-value-assume self slot-spec absorbedvalue)) ;; /// uh-oh. calc-n-set uses this return value
- absorbedvalue))))
-
-;;;(defmethod trcp ((c c-ruled))
-;;; ;;(trc "trcp ruled" (c-slot-name c) (md-name (c-model c)))
-;;; (and (eql 'clo::px (c-slot-name c))
-;;; (eql :mklabel (md-name (c-model c)))))
-
-
-(defun md-slot-value-assume (self slot-spec absorbedvalue
- &aux
- (c (md-slot-cell self slot-spec))
- (priorstate (when c (c-state c)))
- (priorvalue (when c (c-value c)))
- )
- (when (mdead self)
- (return-from md-slot-value-assume nil))
- (md-slot-value-store self (slot-spec-name slot-spec)
- (if c
- (setf (c-value c) absorbedvalue)
- absorbedvalue))
-
- (when (typep c 'c-ruled)
- (trc nil " setting cellstate :valid" c)
- (setf (c-state c) :valid)
- (setf (cd-stale-p c) nil)
- (setf (c-waking-state c) :awake)
- (c-pending-set c nil :sv-assume)
- (c-optimize-away?! c)) ;;; put optimize as early as possible
-
- ;--- propagation -----------
- ;
- (unwind-protect
- (if (and (eql priorstate :valid) ;; ie, priorvalue meaningful (nil is ambiguous)
- (c-no-news c absorbedvalue priorvalue))
- (progn
- (trc nil "(setf md-slot-value) >no-news" priorstate (c-no-news c absorbedvalue priorvalue))
- #+not (count-it :no-news))
- (progn
- (when (eql '.kids (slot-spec-name slot-spec))
- #+dfdbg (dolist (K absorbedvalue) (trc k "md-slot-value-assume -> kids change" k self))
- (md-kids-change self absorbedvalue priorvalue :md-slot-value-assume))
- (md-propagate self slot-spec absorbedvalue priorvalue (not (eql :unbound priorstate)))))
- (when c
- (setf (unst-setting-p c) nil)))
- absorbedvalue)
-
+;; -*- mode: Lisp; Syntax: Common-Lisp; Package: cells; -*-
+;;;
+;;; Copyright (c) 1995,2003 by Kenneth William Tilton.
+;;;
+;;; Permission is hereby granted, free of charge, to any person obtaining a copy
+;;; of this software and associated documentation files (the "Software"), to deal
+;;; in the Software without restriction, including without limitation the rights
+;;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+;;; copies of the Software, and to permit persons to whom the Software is furnished
+;;; to do so, subject to the following conditions:
+;;;
+;;; The above copyright notice and this permission notice shall be included in
+;;; all copies or substantial portions of the Software.
+;;;
+;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+;;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+;;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+;;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+;;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+;;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+;;; IN THE SOFTWARE.
+
+(in-package :cells)
+
+(defun md-slot-cell-flushed (self slot-spec)
+ (cdr (assoc (slot-spec-name slot-spec) (cells-flushed self))))
+
+(defun md-slot-value (self slot-spec &aux (slot-c (md-slot-cell self slot-spec)))
+ (when *stop*
+ (princ #\.)
+ (return-from md-slot-value))
+ ;; (count-it :md-slot-value (slot-spec-name slot-spec))
+ #+badidea(when (mdead self)
+ (trc "md-slot-value> model dead" (type-of self) slot-spec)
+ (return-from md-slot-value nil))
+ (when (eql :nascent (md-state self))
+ (md-awaken self))
+
+ ; this next bit is not written (c-relay-value <link> (etypecase slot-c...))
+ ; because that would link before accessing possibly an invalid ruled slot
+ ; (during md-awaken), and after calculating it would propagate to users and
+ ; re-enter this calculation. Switching the order of the parameters would
+ ; also work, but we need to document this very specific order of operations
+ ; anyway, can't just leave that to the left-right thing.
+ ;
+ (let ((slot-value (etypecase slot-c
+ (null (bd-slot-value self slot-spec))
+ (c-variable (c-value slot-c))
+ (c-ruled (c-ruled-slot-value slot-c)))))
+ (c-relay-value
+ (when (car *c-calculators*)
+ (c-link-ex slot-c))
+ slot-value)))
+
+(defun c-ruled-slot-value (slot-c)
+ (trc nil "c-ruled-slot-value entry" slot-c)
+ (c-assert (not (cmdead slot-c)))
+
+ (cond
+ ((c-validp slot-c)
+ (if (c-true-stalep slot-c)
+ (c-calculate-and-set slot-c) ;; new for 2003-09-14
+ (bif (deep (cd-deep-stale slot-c))
+ (progn
+ (trc nil "valid ~a :but-deepstale ~a, cause: ~a. calcing"
+ slot-c deep *cause*)
+ (c-calculate-and-set slot-c))
+ #+worked (progn
+ (trc "valid ~a :but-deepstale ~a, cause: ~a. calcing"
+ slot-c deep *cause*)
+ (c-calculate-and-set deep)
+ (bIf (deep2 (cd-deep-stale slot-c))
+ (break "deep, deep trouble ~a :deep2 ~a :deep1 ~a, cause: ~a."
+ slot-c deep2 deep *cause*)
+ (progn
+ (trc "cleared valid with deep stale" slot-c)
+ (c-calculate-and-set slot-c))))
+ (c-value slot-c)))) ;; good to go
+
+ (t (let ((*cause* :on-demand)) ; normal path first time asked
+ (trc (plusp *trcdepth*) "md-slot-value calc" slot-c *c-calculators*)
+ (c-calculate-and-set slot-c)))))
+
+;-------------------------------------------------------------
+
+(defun (setf md-slot-value) (newvalue self slot-spec)
+ (when (mdead self)
+ (return-from md-slot-value))
+ (let ((c (md-slot-cell self slot-spec)))
+
+ (when *c-debug*
+ (c-setting-debug self slot-spec c newvalue))
+
+ (unless c
+ (c-stop :setf-md-slot-value)
+ (c-break "(setf md-slot-value)> cellular slot ~a of ~a cannot be setf unless initialized to c-variable"
+ slot-spec self)
+ )
+
+ (if (cv-setting-p c)
+ (if (cv-cyclic-p c)
+ newvalue
+ (c-break "setf of ~a propagated back; declare as cyclic (cv8...)" c))
+ (let ((absorbedvalue (c-absorb-value c newvalue)))
+ ;;(c-assert (not (mdead self)))
+ (with-dataflow-management (c)
+ (md-slot-value-assume self slot-spec absorbedvalue)) ;; /// uh-oh. calc-n-set uses this return value
+ absorbedvalue))))
+
+;;;(defmethod trcp ((c c-ruled))
+;;; ;;(trc "trcp ruled" (c-slot-name c) (md-name (c-model c)))
+;;; (and (eql 'clo::px (c-slot-name c))
+;;; (eql :mklabel (md-name (c-model c)))))
+
+
+(defun md-slot-value-assume (self slot-spec absorbedvalue
+ &aux
+ (c (md-slot-cell self slot-spec))
+ (priorstate (when c (c-state c)))
+ (priorvalue (when c (c-value c)))
+ )
+ (when (mdead self)
+ (return-from md-slot-value-assume nil))
+ (md-slot-value-store self (slot-spec-name slot-spec)
+ (if c
+ (setf (c-value c) absorbedvalue)
+ absorbedvalue))
+
+ (when (typep c 'c-ruled)
+ (trc nil " setting cellstate :valid" c)
+ (setf (c-state c) :valid)
+ (setf (cd-stale-p c) nil)
+ (setf (c-waking-state c) :awake)
+ (c-pending-set c nil :sv-assume)
+ (c-optimize-away?! c)) ;;; put optimize as early as possible
+
+ ;--- propagation -----------
+ ;
+ (if (and (eql priorstate :valid) ;; ie, priorvalue meaningful (nil is ambiguous)
+ (c-no-news c absorbedvalue priorvalue))
+ (progn
+ (trc nil "(setf md-slot-value) >no-news" priorstate (c-no-news c absorbedvalue priorvalue))
+ #+not (count-it :no-news))
+ (progn
+ (when (eql '.kids (slot-spec-name slot-spec))
+ #+dfdbg (dolist (K absorbedvalue) (trc k "md-slot-value-assume -> kids change" k self))
+ (md-kids-change self absorbedvalue priorvalue :md-slot-value-assume))
+ (md-propagate self slot-spec absorbedvalue priorvalue (not (eql :unbound priorstate)))))
+ absorbedvalue)
+
Index: cells/md-utilities.lisp
diff -u cells/md-utilities.lisp:1.1.1.1 cells/md-utilities.lisp:1.2
--- cells/md-utilities.lisp:1.1.1.1 Sat Nov 8 18:44:28 2003
+++ cells/md-utilities.lisp Tue Dec 16 10:02:58 2003
@@ -1,111 +1,111 @@
-;; -*- mode: Lisp; Syntax: Common-Lisp; Package: cells; -*-
-;;;
-;;; Copyright © 1995,2003 by Kenneth William Tilton.
-;;;
-;;; Permission is hereby granted, free of charge, to any person obtaining a copy
-;;; of this software and associated documentation files (the "Software"), to deal
-;;; in the Software without restriction, including without limitation the rights
-;;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-;;; copies of the Software, and to permit persons to whom the Software is furnished
-;;; to do so, subject to the following conditions:
-;;;
-;;; The above copyright notice and this permission notice shall be included in
-;;; all copies or substantial portions of the Software.
-;;;
-;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-;;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-;;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-;;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-;;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-;;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-;;; IN THE SOFTWARE.
-
-(in-package :cells)
-
-;;;(defmethod update-instance-for-redefined-class ((self model-object) added lost plist &key)
-;;; (declare (ignorable added lost plist))
-;;; (when (slot-boundp self '.md-state) (call-next-method)))
-
-(defmethod occurence ((self model-object))
- ;
- ; whether multiply occuring or not, return index of self
- ; within list of likenamed siblings, perhaps mixed amongst others
- ; of diff names
- ;
- (let ((selfindex -1))
- (dolist (kid (kids (fmparent self)))
- (when (eql (md-name kid) (md-name self))
- (incf selfindex)
- (when (eql self kid)
- (return-from occurence selfindex))))))
-
-
-(defun md-awake (self) (eql :awake (md-state self)))
-
-
-(defun fm-grandparent (md)
- (fmparent (fmparent md)))
-
-
-(defmethod md-release (other)
- (declare (ignorable other)))
-
-;___________________ birth / death__________________________________
-
-(defmethod not-to-be :around (self)
- (trc nil "not-to-be clearing 1 fmparent, eternal-rest" self)
- (assert (not (eq (md-state self) :eternal-rest)))
-
- (call-next-method)
-
- (setf (fmparent self) nil
- (md-state self) :eternal-rest)
- (trc nil "not-to-be cleared 2 fmparent, eternal-rest" self))
-
-(defmethod not-to-be ((self model-object))
- (trc nil "not to be!!!" self)
- (unless (md-untouchable self)
- (md-quiesce self)))
-
-(defmethod md-untouchable (self) ;; would be t for closed-stream under acl
- (declare (ignore self))
- nil)
-
-(defun md-quiesce (self)
- (trc nil "md-quiesce doing" self)
- (md-map-cells self nil (lambda (c)
- (trc nil "quiescing" c)
- (assert (not (find c *c-calculators*)))
- (c-quiesce c))))
-
-
-(defmethod not-to-be (other)
- other)
-
-
-
-(defparameter *to-be-dbg* nil)
-
-(defun to-be (self)
- (trc nil "to-be> entry" self (md-state self))
-
- (progn ;;wtrc (0 100 "to-be> entry" self (md-state self) (length *to-be-awakened*))
- (when (eql :nascent (md-state self)) ;; formwithview to-be-primary :after => rv-stitch! => side-effects
- (let ((already *to-be-awakened*))
- (setf *to-be-awakened* (nconc *to-be-awakened* (list self)))
- (trc nil "to-be deferring awaken" self)
- (kids self) ;; sick, just for side effect
- (unless already
- (trc nil "top to-be awakening deferred" self (length *to-be-awakened*))
- (do* ((mds *to-be-awakened* (cdr mds))
- (md (car mds) (car mds)))
- ((null mds))
- (if (eql :nascent (md-state md))
- (md-awaken md)
- (trc nil "not md-awakening non-nascent" md)))
- (setf *to-be-awakened* nil)))))
- self)
-
-(defun md-make (class &rest kwps)
- (to-be (apply #'make-instance class kwps)))
-
+;; -*- mode: Lisp; Syntax: Common-Lisp; Package: cells; -*-
+;;;
+;;; Copyright (c) 1995,2003 by Kenneth William Tilton.
+;;;
+;;; Permission is hereby granted, free of charge, to any person obtaining a copy
+;;; of this software and associated documentation files (the "Software"), to deal
+;;; in the Software without restriction, including without limitation the rights
+;;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+;;; copies of the Software, and to permit persons to whom the Software is furnished
+;;; to do so, subject to the following conditions:
+;;;
+;;; The above copyright notice and this permission notice shall be included in
+;;; all copies or substantial portions of the Software.
+;;;
+;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+;;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+;;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+;;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+;;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+;;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+;;; IN THE SOFTWARE.
+
+(in-package :cells)
+
+;;;(defmethod update-instance-for-redefined-class ((self model-object) added lost plist &key)
+;;; (declare (ignorable added lost plist))
+;;; (when (slot-boundp self '.md-state) (call-next-method)))
+
+(defmethod occurence ((self model-object))
+ ;
+ ; whether multiply occuring or not, return index of self
+ ; within list of likenamed siblings, perhaps mixed amongst others
+ ; of diff names
+ ;
+ (let ((selfindex -1))
+ (dolist (kid (kids (fm-parent self)))
+ (when (eql (md-name kid) (md-name self))
+ (incf selfindex)
+ (when (eql self kid)
+ (return-from occurence selfindex))))))
+
+
+(defun md-awake (self) (eql :awake (md-state self)))
+
+
+(defun fm-grandparent (md)
+ (fm-parent (fm-parent md)))
+
+
+(defmethod md-release (other)
+ (declare (ignorable other)))
+
+;___________________ birth / death__________________________________
+
+(defmethod not-to-be :around (self)
+ (trc nil "not-to-be clearing 1 fm-parent, eternal-rest" self)
+ (c-assert (not (eq (md-state self) :eternal-rest)))
+
+ (call-next-method)
+
+ (setf (fm-parent self) nil
+ (md-state self) :eternal-rest)
+ (trc nil "not-to-be cleared 2 fm-parent, eternal-rest" self))
+
+(defmethod not-to-be ((self model-object))
+ (trc nil "not to be!!!" self)
+ (unless (md-untouchable self)
+ (md-quiesce self)))
+
+(defmethod md-untouchable (self) ;; would be t for closed-stream under acl
+ (declare (ignore self))
+ nil)
+
+(defun md-quiesce (self)
+ (trc nil "md-quiesce doing" self)
+ (md-map-cells self nil (lambda (c)
+ (trc nil "quiescing" c)
+ (c-assert (not (find c *c-calculators*)))
+ (c-quiesce c))))
+
+
+(defmethod not-to-be (other)
+ other)
+
+
+
+(defparameter *to-be-dbg* nil)
+
+(defun to-be (self)
+ (trc nil "to-be> entry" self (md-state self))
+
+ (progn ;;wtrc (0 100 "to-be> entry" self (md-state self) (length *to-be-awakened*))
+ (when (eql :nascent (md-state self)) ;; formwithview to-be-primary :after => rv-stitch! => side-effects
+ (let ((already *to-be-awakened*))
+ (setf *to-be-awakened* (nconc *to-be-awakened* (list self)))
+ (trc nil "to-be deferring awaken" self)
+ (kids self) ;; sick, just for side effect
+ (unless already
+ (trc nil "top to-be awakening deferred" self (length *to-be-awakened*))
+ (do* ((mds *to-be-awakened* (cdr mds))
+ (md (car mds) (car mds)))
+ ((null mds))
+ (if (eql :nascent (md-state md))
+ (md-awaken md)
+ (trc nil "not md-awakening non-nascent" md)))
+ (setf *to-be-awakened* nil)))))
+ self)
+
+(defun md-make (class &rest kwps)
+ (to-be (apply #'make-instance class kwps)))
+
Index: cells/model-object.lisp
diff -u cells/model-object.lisp:1.1.1.1 cells/model-object.lisp:1.2
--- cells/model-object.lisp:1.1.1.1 Sat Nov 8 18:44:28 2003
+++ cells/model-object.lisp Tue Dec 16 10:02:58 2003
@@ -1,193 +1,175 @@
-;; -*- mode: Lisp; Syntax: Common-Lisp; Package: cells; -*-
-;;;
-;;; Copyright © 1995,2003 by Kenneth William Tilton.
-;;;
-;;; Permission is hereby granted, free of charge, to any person obtaining a copy
-;;; of this software and associated documentation files (the "Software"), to deal
-;;; in the Software without restriction, including without limitation the rights
-;;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-;;; copies of the Software, and to permit persons to whom the Software is furnished
-;;; to do so, subject to the following conditions:
-;;;
-;;; The above copyright notice and this permission notice shall be included in
-;;; all copies or substantial portions of the Software.
-;;;
-;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-;;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-;;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-;;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-;;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-;;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-;;; IN THE SOFTWARE.
-
-(in-package :cells)
-
-;----------------- model-object ----------------------
-
-(eval-when (:compile-toplevel :load-toplevel :execute)
- (export '(md-name mdwhen fmparent .parent)))
-
-(defclass model-object ()
- ((.md-state :initform nil :accessor md-state) ; [nil | :nascent | :alive | :doomed]
- (.md-name :initform nil :initarg :md-name :accessor md-name)
- (.mdwhen :initform nil :initarg :mdwhen :accessor mdwhen)
- (.fmparent :initform nil :initarg :fmparent :accessor fmparent)
- (.cells :initform nil :initarg :cells :accessor cells)
- (.cells-flushed :initform nil :initarg cells :accessor cells-flushed
- :documentation "cells supplied but un-whenned or optimized-away")
- (adopt-ct :initform 0 :accessor adopt-ct)))
-
-(defmethod print-object ((self model-object) s)
- (format s "~a" (or (md-name self) (type-of self))))
-
-(define-symbol-macro .parent (fmparent self))
-
-(defun md-cell-defs (self)
- (get (type-of self) :cell-defs))
-
-(defmethod md-slot-cell (self slot-spec)
- (assocv (slot-spec-name slot-spec) (cells self)))
-
-(defun md-slot-cell-type (class-name slot-spec)
- (bif (entry (assoc (slot-spec-name slot-spec) (get class-name :cell-defs)))
- (cdr entry)
- (dolist (super (class-precedence-list (find-class class-name)))
- (bIf (entry (assoc (slot-spec-name slot-spec) (get (c-class-name super) :cell-defs)))
- (return (cdr entry))))))
-
-
-(defun (setf md-slot-cell-type) (new-type class-name slot-spec)
- (assocv-setf (get class-name :cell-defs) (slot-spec-name slot-spec) new-type))
-
-(defmethod md-slot-value-store ((self model-object) slot-spec new-value)
- (setf (slot-value self (slot-spec-name slot-spec)) new-value))
-
-;----------------- navigation: slot <> initarg <> esd <> cell -----------------
-
-#+cmu
-(defmethod c-class-name ((class pcl::standard-class))
- (pcl::class-name class))
-
-(defmethod c-class-name (other) (declare (ignore other)) nil)
-
-(defmethod c-class-name ((class standard-class))
- (class-name class))
-
-(defmethod cellwhen (other) (declare (ignorable other)) nil)
-
-(defun (setf md-slot-cell) (newcell self slot-spec)
- (bif (entry (assoc (slot-spec-name slot-spec) (cells self)))
- (let ((old (cdr entry))) ;; s/b being supplanted by kid-slotter
- (assert (null (un-users old)))
- (assert (null (cd-useds old)))
- (trc nil "replacing in model .cells" old newcell self)
- (rplacd entry newcell))
- (progn
- (trc nil "adding to model .cells" newcell self)
- (push (cons (slot-spec-name slot-spec) newcell)
- (cells self)))))
-
-(defun md-map-cells (self type celldo)
- (map type (lambda (cellentry)
- (bwhen (cell (cdr cellentry))
- (unless (listp cell)
- (funcall celldo cell))))
- (cells self)))
-
-(defun c-install (self sn c)
- (assert (typep c 'cell))
- (trc nil "installing cell" sn c)
- (setf
- (c-model c) self
- (c-slot-spec c) sn
- (md-slot-cell self sn) c
- (slot-value self sn) (when (typep c 'c-variable)
- (c-value c))))
-
-;------------------ md obj initialization ------------------
-
-(defmethod shared-initialize :after ((self model-object) slotnames
- &rest initargs &key fmparent mdwhen
- &allow-other-keys)
- (declare (ignorable initargs slotnames fmparent mdwhen))
-
- (dolist (esd (class-slots (class-of self)))
- (let* ((sn (slot-definition-name esd))
- (sv (when (slot-boundp self sn)
- (slot-value self sn))))
- (when (typep sv 'cell)
- (if (md-slot-cell-type (type-of self) sn)
- (c-install self sn sv)
- (when *c-debug*
- (trc "cell ~a offered for non-cellular model/slot ~a/~a" sv self sn))))))
-
- (md-initialize self))
-
-;;;(defun pick-if-when-slot (esd mdwhen &aux (cellwhen (cellwhen esd)))
-;;; (or (null cellwhen)
-;;; (some-x-is-in-y cellwhen mdwhen)))
-
-(defmethod md-initialize (self)
- (when (slot-boundp self '.md-name)
- (unless (md-name self)
- (setf (md-name self) (c-class-name (class-of self)))))
-
- (when (fmparent self)
- (md-adopt (fmparent self) self))
-
- (setf (md-state self) :nascent))
-
-(defun cells-clear (self)
- "allow gc"
- ;;
- ;; too extreme? 'close-device went after slot when a class
- ;; ended up without cells--should not be a crime 2k0320kt
- ;; (slot-makunbound self '.cells)
- ;; ...
- (setf (cells self) nil) ;; try instead
- )
-
-
-;--------- awaken only when ready (in family, for models) --------
-
-
-(defmethod md-awaken ((self model-object))
- (trc nil "md-awaken entry" self (md-state self))
- (assert (eql :nascent (md-state self)))
- ;; (trc nil "awaken doing")
- (count-it :md-awaken)
- ;;(count-it 'mdawaken (type-of self))
- (setf (md-state self) :awakening)
- ;; (trc "md-awaken entry" self)
- (dolist (esd (class-slots (class-of self)))
- (trc nil "md-awaken scoping slot" self (slot-definition-name esd))
- (when (md-slot-cell-type (type-of self) (slot-definition-name esd))
- (let ((slot-name (slot-definition-name esd)))
- (if (not (c-echo-defined slot-name))
- (progn ;; (count-it :md-awaken :no-echo-slot slot-name)
- (trc nil "md-awaken deferring cell-awaken since no echo" self esd))
-
- (let ((cell (md-slot-cell self slot-name)))
- (trc nil "md-awaken finds md-esd-cell " cell)
- (when *c-debug*
- ;
- ; check to see if cell snuck into actual slot value...
- ;
- (bwhen (sv (slot-value self slot-name))
- (when (typep sv 'cell)
- (error "md-awaken ~a found cell ~a in slot ~a" self sv esd))))
-
- (if cell
- (if (c-lazy-p cell)
- (progn
- (trc nil "md-awaken deferring cell-awaken since lazy" self esd))
- (c-awaken cell))
- (progn ;; next bit revised to avoid double-echo of optimized cells
- (when (eql '.kids slot-name)
- (bwhen (sv (slot-value self '.kids))
- (md-kids-change self sv nil :md-awaken-slot)))
- (c-echo-initially self slot-name))))))))
-
- (setf (md-state self) :awake)
- self)
-
+;; -*- mode: Lisp; Syntax: Common-Lisp; Package: cells; -*-
+;;;
+;;; Copyright (c) 1995,2003 by Kenneth William Tilton.
+;;;
+;;; Permission is hereby granted, free of charge, to any person obtaining a copy
+;;; of this software and associated documentation files (the "Software"), to deal
+;;; in the Software without restriction, including without limitation the rights
+;;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+;;; copies of the Software, and to permit persons to whom the Software is furnished
+;;; to do so, subject to the following conditions:
+;;;
+;;; The above copyright notice and this permission notice shall be included in
+;;; all copies or substantial portions of the Software.
+;;;
+;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+;;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+;;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+;;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+;;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+;;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+;;; IN THE SOFTWARE.
+
+(in-package :cells)
+
+;----------------- model-object ----------------------
+
+(eval-when (:compile-toplevel :load-toplevel :execute)
+ (export '(md-name mdwhen fm-parent .parent)))
+
+(defclass model-object ()
+ ((.md-state :initform nil :accessor md-state) ; [nil | :nascent | :alive | :doomed]
+ (.mdwhen :initform nil :initarg :mdwhen :accessor mdwhen)
+ (.cells :initform nil :accessor cells)
+ (.cells-flushed :initform nil :accessor cells-flushed
+ :documentation "cells supplied but un-whenned or optimized-away")
+ (adopt-ct :initform 0 :accessor adopt-ct)))
+
+(defmethod md-slot-cell (self slot-spec)
+ (cdr (assoc (slot-spec-name slot-spec) (cells self))))
+
+(defun md-slot-cell-type (class-name slot-spec)
+ (bif (entry (assoc (slot-spec-name slot-spec) (get class-name :cell-types)))
+ (cdr entry)
+ (dolist (super (class-precedence-list (find-class class-name)))
+ (bWhen (entry (assoc (slot-spec-name slot-spec) (get (c-class-name super) :cell-types)))
+ (return (setf (md-slot-cell-type class-name slot-spec) (cdr entry)))))))
+
+(defun (setf md-slot-cell-type) (new-type class-name slot-spec)
+ (assocv-setf (get class-name :cell-types) (slot-spec-name slot-spec) new-type))
+
+(defmethod md-slot-value-store ((self model-object) slot-spec new-value)
+ (setf (slot-value self (slot-spec-name slot-spec)) new-value))
+
+;----------------- navigation: slot <> initarg <> esd <> cell -----------------
+
+#+cmu
+(defmethod c-class-name ((class pcl::standard-class))
+ (pcl::class-name class))
+
+(defmethod c-class-name (other) (declare (ignore other)) nil)
+
+(defmethod c-class-name ((class standard-class))
+ (class-name class))
+
+(defmethod cellwhen (other) (declare (ignorable other)) nil)
+
+(defun (setf md-slot-cell) (newcell self slot-spec)
+ (bif (entry (assoc (slot-spec-name slot-spec) (cells self)))
+ (let ((old (cdr entry))) ;; s/b being supplanted by kid-slotter
+ (c-assert (null (c-users old)))
+ (c-assert (null (cd-useds old)))
+ (trc nil "replacing in model .cells" old newcell self)
+ (rplacd entry newcell))
+ (progn
+ (trc nil "adding to model .cells" newcell self)
+ (push (cons (slot-spec-name slot-spec) newcell)
+ (cells self)))))
+
+(defun md-map-cells (self type celldo)
+ (map type (lambda (cellentry)
+ (bwhen (cell (cdr cellentry))
+ (unless (listp cell)
+ (funcall celldo cell))))
+ (cells self)))
+
+(defun c-install (self sn c)
+ (c-assert (typep c 'cell))
+ (trc nil "installing cell" sn c)
+ (setf
+ (c-model c) self
+ (c-slot-spec c) sn
+ (md-slot-cell self sn) c
+ (slot-value self sn) (when (typep c 'c-variable)
+ (c-value c))))
+
+;------------------ md obj initialization ------------------
+
+(defmethod shared-initialize :after ((self model-object) slotnames
+ &rest initargs &key fm-parent mdwhen
+ &allow-other-keys)
+ (declare (ignorable initargs slotnames fm-parent mdwhen))
+
+ (dolist (esd (class-slots (class-of self)))
+ (let* ((sn (slot-definition-name esd))
+ (sv (when (slot-boundp self sn)
+ (slot-value self sn))))
+ (when (typep sv 'cell)
+ (if (md-slot-cell-type (type-of self) sn)
+ (c-install self sn sv)
+ (when *c-debug*
+ (trc "warning: cell ~a offered for non-cellular model/slot ~a/~a" sv self sn))))))
+
+ (md-initialize self))
+
+;;;(defun pick-if-when-slot (esd mdwhen &aux (cellwhen (cellwhen esd)))
+;;; (or (null cellwhen)
+;;; (some-x-is-in-y cellwhen mdwhen)))
+
+(defmethod md-initialize (self)
+ (setf (md-state self) :nascent))
+
+(defun cells-clear (self)
+ "allow gc"
+ ;;
+ ;; too extreme? 'close-device went after slot when a class
+ ;; ended up without cells--should not be a crime 2k0320kt
+ ;; (slot-makunbound self '.cells)
+ ;; ...
+ (setf (cells self) nil) ;; try instead
+ )
+
+
+;--------- awaken only when ready (in family, for models) --------
+
+
+(defmethod md-awaken ((self model-object))
+ (trc nil "md-awaken entry" self (md-state self))
+ (c-assert (eql :nascent (md-state self)))
+ ;; (trc nil "awaken doing")
+ (count-it :md-awaken)
+ ;;(count-it 'mdawaken (type-of self))
+ (setf (md-state self) :awakening)
+ ;; (trc "md-awaken entry" self)
+ (dolist (esd (class-slots (class-of self)))
+ (trc nil "md-awaken scoping slot" self (slot-definition-name esd))
+ (when (md-slot-cell-type (type-of self) (slot-definition-name esd))
+ (let ((slot-name (slot-definition-name esd)))
+ (if (not (c-echo-defined slot-name))
+ (progn ;; (count-it :md-awaken :no-echo-slot slot-name)
+ (trc nil "md-awaken deferring cell-awaken since no echo" self esd))
+
+ (let ((cell (md-slot-cell self slot-name)))
+ (trc nil "md-awaken finds md-esd-cell " cell)
+ (when *c-debug*
+ ;
+ ; check to see if cell snuck into actual slot value...
+ ;
+ (bwhen (sv (slot-value self slot-name))
+ (when (typep sv 'cell)
+ (c-break "md-awaken ~a found cell ~a in slot ~a" self sv esd))))
+
+ (if cell
+ (if (c-lazy-p cell)
+ (progn
+ (trc nil "md-awaken deferring cell-awaken since lazy" self esd))
+ (c-awaken cell))
+ (progn ;; next bit revised to avoid double-echo of optimized cells
+ (when (eql '.kids slot-name)
+ (bwhen (sv (slot-value self '.kids))
+ (md-kids-change self sv nil :md-awaken-slot)))
+ (c-echo-initially self slot-name))))))))
+
+ (setf (md-state self) :awake)
+ self)
+
Index: cells/optimization.lisp
diff -u cells/optimization.lisp:1.1.1.1 cells/optimization.lisp:1.2
--- cells/optimization.lisp:1.1.1.1 Sat Nov 8 18:44:28 2003
+++ cells/optimization.lisp Tue Dec 16 10:02:58 2003
@@ -1,83 +1,83 @@
-;; -*- mode: Lisp; Syntax: Common-Lisp; Package: cells; -*-
-;;;
-;;; Copyright © 1995,2003 by Kenneth William Tilton.
-;;;
-;;; Permission is hereby granted, free of charge, to any person obtaining a copy
-;;; of this software and associated documentation files (the "Software"), to deal
-;;; in the Software without restriction, including without limitation the rights
-;;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-;;; copies of the Software, and to permit persons to whom the Software is furnished
-;;; to do so, subject to the following conditions:
-;;;
-;;; The above copyright notice and this permission notice shall be included in
-;;; all copies or substantial portions of the Software.
-;;;
-;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-;;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-;;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-;;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-;;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-;;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-;;; IN THE SOFTWARE.
-
-(in-package :cells)
-
-;____________ cell when ____________________
-
-(defparameter *c-whentime* nil)
-
-(defun call-with-when-time? (whentimes function &aux old)
- (rotatef old *c-whentime* whentimes)
- ;; (trc "setting *c-whentime* to" *c-whentime*)
- (unwind-protect
- (funcall function)
- (setf *c-whentime* old)))
-
-;---------- optimizing away cells whose dependents all turn out to be constant ----------------
-;
-
-(defun c-optimize-away?! (c)
-
- (typecase c
- #+old-code
- (c-nested (trc nil "optimize-away nested")
- (when (and (null (cd-useds c)))
- (rplaca (member c (cellnestedcells (cellaggregatecell c))) (c-value c))
- t))
- (c-dependent
- (if (and *c-optimizep*
- (c-validp c)
- (null (cd-useds c)))
-
- (progn
- (trc nil "optimizing away" c)
- (count-it :c-optimized)
-
- (setf (c-state c) :optimized-away)
-
- (let ((entry (rassoc c (cells (c-model c))))) ; move from cells to cells-flushed
- (assert entry)
- (setf (cells (c-model c)) (delete entry (cells (c-model c))))
- (push entry (cells-flushed (c-model c))))
-
- (dolist (user (un-users c))
- (setf (cd-useds user) (delete c (cd-useds user)))
- (trc nil "checking opti2" c :user> user)
- (when (c-optimize-away?! user)
- (trc "Wow!!! optimizing chain reaction, first:" c :then user)))
-
- (setf ; drop foreign refs to aid gc (gc paranoia?)
- (c-model c) nil
- (un-users c) nil)
-
- t)
-
- (progn
- (trc nil "not optimizing away" *c-optimizep* (car (cd-useds c)) (c-validp c))
- #+no (dolist (used (cd-useds c))
- (assert (member c (un-users used)))
- ;;; (trc nil "found as user of" used)
- )
- ; (count-it :c-not-optimize)
- ; (count-it (intern-keyword "noopti-" #+nah (c-model c) "-" (symbol-name (c-slot-name c))))
- )))))
+;; -*- mode: Lisp; Syntax: Common-Lisp; Package: cells; -*-
+;;;
+;;; Copyright (c) 1995,2003 by Kenneth William Tilton.
+;;;
+;;; Permission is hereby granted, free of charge, to any person obtaining a copy
+;;; of this software and associated documentation files (the "Software"), to deal
+;;; in the Software without restriction, including without limitation the rights
+;;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+;;; copies of the Software, and to permit persons to whom the Software is furnished
+;;; to do so, subject to the following conditions:
+;;;
+;;; The above copyright notice and this permission notice shall be included in
+;;; all copies or substantial portions of the Software.
+;;;
+;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+;;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+;;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+;;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+;;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+;;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+;;; IN THE SOFTWARE.
+
+(in-package :cells)
+
+;____________ cell when ____________________
+
+(defparameter *c-whentime* nil)
+
+(defun call-with-when-time? (whentimes function &aux old)
+ (rotatef old *c-whentime* whentimes)
+ ;; (trc "setting *c-whentime* to" *c-whentime*)
+ (unwind-protect
+ (funcall function)
+ (setf *c-whentime* old)))
+
+;---------- optimizing away cells whose dependents all turn out to be constant ----------------
+;
+
+(defun c-optimize-away?! (c)
+
+ (typecase c
+ #+old-code
+ (c-nested (trc nil "optimize-away nested")
+ (when (and (null (cd-useds c)))
+ (rplaca (member c (cellnestedcells (cellaggregatecell c))) (c-value c))
+ t))
+ (c-dependent
+ (if (and *c-optimizep*
+ (c-validp c)
+ (null (cd-useds c)))
+
+ (progn
+ (trc nil "optimizing away" c)
+ (count-it :c-optimized)
+
+ (setf (c-state c) :optimized-away)
+
+ (let ((entry (rassoc c (cells (c-model c))))) ; move from cells to cells-flushed
+ (c-assert entry)
+ (setf (cells (c-model c)) (delete entry (cells (c-model c))))
+ (push entry (cells-flushed (c-model c))))
+
+ (dolist (user (c-users c))
+ (setf (cd-useds user) (delete c (cd-useds user)))
+ (trc nil "checking opti2" c :user> user)
+ (when (c-optimize-away?! user)
+ (trc "Wow!!! optimizing chain reaction, first:" c :then user)))
+
+ (setf ; drop foreign refs to aid gc (gc paranoia?)
+ (c-model c) nil
+ (c-users c) nil)
+
+ t)
+
+ (progn
+ (trc nil "not optimizing away" *c-optimizep* (car (cd-useds c)) (c-validp c))
+ #+no (dolist (used (cd-useds c))
+ (c-assert (member c (c-users used)))
+ ;;; (trc nil "found as user of" used)
+ )
+ ; (count-it :c-not-optimize)
+ ; (count-it (intern-keyword "noopti-" #+nah (c-model c) "-" (symbol-name (c-slot-name c))))
+ )))))
Index: cells/propagate.lisp
diff -u cells/propagate.lisp:1.1.1.1 cells/propagate.lisp:1.2
--- cells/propagate.lisp:1.1.1.1 Sat Nov 8 18:44:34 2003
+++ cells/propagate.lisp Tue Dec 16 10:02:58 2003
@@ -1,310 +1,308 @@
-;; -*- mode: Lisp; Syntax: Common-Lisp; Package: cells; -*-
-;;;
-;;; Copyright © 1995,2003 by Kenneth William Tilton.
-;;;
-;;; Permission is hereby granted, free of charge, to any person obtaining a copy
-;;; of this software and associated documentation files (the "Software"), to deal
-;;; in the Software without restriction, including without limitation the rights
-;;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-;;; copies of the Software, and to permit persons to whom the Software is furnished
-;;; to do so, subject to the following conditions:
-;;;
-;;; The above copyright notice and this permission notice shall be included in
-;;; all copies or substantial portions of the Software.
-;;;
-;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-;;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-;;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-;;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-;;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-;;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-;;; IN THE SOFTWARE.
-
-(in-package :cells)
-
-(defparameter *echodone* nil)
-
-(defun c-echo-defined (slot-name)
- (getf (symbol-plist slot-name) :echo-defined))
-
-(defmethod (setf c-true-stalep) (newvalue (user c-ruled))
- #+dfdbg (trc user "setting c-true-stalep" user newvalue)
- (assert (find user (cells (c-model user)) :key #'cdr))
- (setf (cd-stale-p user) newvalue))
-
-(defmethod (setf c-true-stalep) (newvalue (usersyn synapse))
- #+dfdbg (trc (syn-user usersyn) "synapse setting c-true-stalep" (syn-user usersyn) newvalue usersyn)
- (setf (cd-stale-p (syn-user usersyn)) newvalue))
-
-(defmethod (setf c-true-stalep) (newvalue other)
- (declare (ignore other))
- newvalue)
-
-(defun c-echo-initially (self slot-spec)
- "call during instance init. if echo is defined for slot, and value is non-nil (controversial) force initial echo."
- (trc nil "c-echo-initially" self slot-spec
- (c-echo-defined (slot-spec-name slot-spec))
- (md-slot-cell self slot-spec))
- (if (c-echo-defined (slot-spec-name slot-spec))
- (bif (c (md-slot-cell self slot-spec))
- (etypecase c
- (c-variable (md-propagate self slot-spec (c-value c) nil nil))
- (c-ruled (md-slot-value self slot-spec))) ;; this will echo after calculating if not nil
- ;
- ; new for 22-03-07: echo even if slot value is nil...
- (c-echo-slot-name (slot-spec-name slot-spec)
- self
- (bd-slot-value self slot-spec)
- nil nil))
- (bwhen (c (md-slot-cell self slot-spec))
- (c-ephemeral-reset c))))
-
-#-(or cormanlisp clisp)
-(defgeneric c-echo-slot-name (slotname self new old old-boundp) (:method-combination progn))
-
-
-(defmethod c-echo-slot-name
- #-(or cormanlisp clisp) progn
- #+(or cormanlisp clisp) :before
- (slot-name self new old old-boundp)
- (declare (ignorable slot-name self new old old-boundp)))
-
-#+(or cormanlisp clisp)
-(defmethod c-echo-slot-name (slot-name self new old old-boundp)
- (declare (ignorable slot-name self new old old-boundp)))
-
-;--------------- propagate ----------------------------
-;
-; n.b. 990414kt the cell argument may have been optimized away,
-; though it is still receiving final processing here.
-;
-
-(defun md-propagate (self slot-spec newvalue priorvalue priorvalue-supplied)
- (when (mdead self)
- (trc nil "md-propagate n-opping dead" self)
- (return-from md-propagate nil))
-
- (let (*c-calculators*
- (*c-prop-depth* (1+ *c-prop-depth*))
- (c (md-slot-cell self slot-spec)))
- ;
- ;------ debug stuff ---------
- ;
- (when *stop*
- (princ #\.)(princ #\!)
- (return-from md-propagate))
-
- (when c
- (trc nil "md-propagate> propping" self slot-spec (length (un-users c)) c)
- )
-
- (when *c-debug*
- (when (> *c-prop-depth* 250)
- (trc "md-propagate deep" *c-prop-depth* self (slot-spec-name slot-spec) #+nah c))
- (when (> *c-prop-depth* 300)
- (break "md-propagate looping" c)
- ))
-
- (when c
- ; ------ flag dependents as stale ------------
- ; do before echo in case echo gets back to some user
- ;
- (dolist (user (un-users c))
- #+dfdbg (trc user "md-prop now setting stale (changer, stale):" c user)
- (when (c-user-cares user)
- (setf (c-true-stalep user) c))))
-
- ; --- manifest new value as needed -----------
- (when (c-echo-defined (slot-spec-name slot-spec)) ;; /// faster than just dispatching?
- (when c (trc nil "md-prop now echoing" c))
- (c-echo-slot-name (slot-spec-name slot-spec)
- self
- newvalue
- priorvalue
- priorvalue-supplied)
- (when (mdead self) ;; hopefully expiration on perishable class
- (return-from md-propagate)))
-
- (when c ; --- now propagate to dependents ------------
- (trc nil "md-prop checking dependents" c (un-users c))
- (let ((*cause* c))
- (dolist (user (un-users c))
- (unless (cmdead user)
- (when (c-user-cares user)
- (if (c-user-lazy user)
- (progn
- (trc nil "lazy user not being propagated to" user :by c)
- (dolist (u (un-users user))
- (c-propagate-staleness u)))
- (progn
- (c-rethink user)
- (when (mdead self)
- (trc nil "md-propagate> self now dead after rethink user: ~a" self user)
- (return-from md-propagate nil))
- )))))
- (c-ephemeral-reset c)))))
-
-(defmethod c-propagate-staleness ((c c-ruled))
- (trc nil "inheriting staleness" c)
- (dolist (u (cr-users c))
- (c-propagate-staleness u)))
-
-(defmethod c-propagate-staleness ((s synapse))
- (trc "I hope this synapse isn't for efficiency" s)
- (break)
- (c-propagate-staleness (syn-user s)))
-
-(defmethod c-propagate-staleness (c)
- (declare (ignorable c))
- (trc "not inheriting or proagating staleness" c)
- )
-
-(defmethod c-user-cares (c) c) ;; ie, t
-(defmethod c-user-cares ((s synapse))
- (syn-relevant s))
-
-(defmethod c-user-lazy (c) (declare (ignore c)) nil)
-(defmethod c-user-lazy ((c c-ruled))
- (cr-lazy c))
-
-
-(defun c-ephemeral-reset (c)
- (when c
- (when (c-ephemeral-p c)
- (trc nil "c-ephemeral-reset resetting:" c)
- (setf (c-value c) nil)))) ;; good q: what does (setf <ephem> 'x) return? historically nil, but...?
-
-;----------------- change detection ---------------------------------
-
-(defun c-no-news (c newvalue oldvalue)
- ;;; (trc nil "c-no-news > checking news between" newvalue oldvalue)
-
- (if (unst-delta-p c)
- (c-identity-p newvalue)
- (bIf (test (c-unchanged-test (c-model c) (c-slot-name c)))
- (funcall test newvalue oldvalue)
- (eql newvalue oldvalue))))
-
-(defmacro def-c-unchanged-test ((class slotname) &body test)
- `(defmethod c-unchanged-test ((self ,class) (slotname (eql ',slotname)))
- ,@test))
-
-(defmethod c-unchanged-test (self slotname)
- (declare (ignore self slotname))
- nil)
-
-(defmethod c-identity-p ((value null)) t)
-(defmethod c-identity-p ((value number)) (zerop value))
-(defmethod c-identity-p ((value cons))
- ;; this def a little suspect?
- (and (c-identity-p (car value))
- (c-identity-p (cdr value))))
-
-
-;------------------- re think ---------------------------------
-
-(defun cmdead (c)
- (if (typep c 'synapse)
- (cmdead (syn-user c))
- (if (null (c-model c))
- (not (c-optimized-away-p c))
- (mdead (c-model c)))))
-
-(defun mdead (m) (eq :eternal-rest (md-state m)))
-
-(defun c-rethink (c)
- (when *stop*
- (princ #\.)
- (return-from c-rethink))
- ;;(trc "rethink entry: c, true-stale" c (c-true-stalep c))
- (assert (not (cmdead c))() "rethink entry cmdead ~a" c)
- (unless (c-true-stalep c)
- (return-from c-rethink))
-
- (when *rethink-deferred*
- (trc nil "bingo!!!!!! rethink deferring" c *cause*)
- (push (list c *cause*) *rethink-deferred*)
- (return-from c-rethink))
-
- (assert (not (cmdead c))() "rethink here?? cmdead ~a" c)
-
- ; looking ahead for interference avoids JIT detection, which where a dependency
- ; already exists causes re-entrance into the rule, which should calculate the same
- ; value twice and echo only once, but still seems like something to avoid since
- ; we do already have the technology.
- ;
-
- (bIf (interf (sw-detect-interference c nil))
- (progn
- (trc "!!!!!!!!!! rethink of " c :held-up-by interf)
- (c-pending-set c interf :interfered)
- #+dfdbg (when (trcp c)
- (trc "!!!!!!!!!! rethink of " c :held-up-by interf)
- #+nah (dump-stale-path interf)
- )
- (return-from c-rethink))
- (when (sw-pending c)
- (trc nil "no interference now for " c)
- (c-pending-set c nil :dis-interfered)))
-
- (when (cmdead c)
- (trc nil "woohoo!!! interference checking finished model off" c)
- (return-from c-rethink))
-
- (unless (c-true-stalep c)
- (trc nil "woohoo!!! interference checking refreshed" c)
- (return-from c-rethink))
-
- (typecase c
- (c-ruled (c-calculate-and-set c))
-
- (synapse
- (trc nil "c-rethink > testing rethink of: syn,salv,valu" c salvage (c-value (syn-used c)))
- (if (funcall (syn-fire-p c) c (c-value (syn-used c)))
- (progn
- (trc nil "c-rethink> decide yes on rethink on syn, valu" c (c-value (syn-used c)))
- (c-rethink (syn-user c)))
- (trc nil "c-rethink> decide nooooo on rethink on synapse" c (syn-user c) salvage)))
- ))
-
-(defmacro def-c-echo (slotname
- (&optional (selfarg 'self) (newvarg 'new-value)
- (oldvarg 'old-value) (oldvargboundp 'old-value-boundp))
- &body echobody)
- ;;;(trc "echo body" echobody)
- `(progn
- (eval-when (:compile-toplevel :load-toplevel :execute)
- (setf (get ',slotname :echo-defined) t))
- ,(if (eql (last1 echobody) :test)
- (let ((temp1 (gensym))
- (loc-self (gensym)))
- `(defmethod c-echo-slot-name #-(or clisp cormanlisp) progn ((slotname (eql ',slotname)) ,selfarg ,newvarg ,oldvarg ,oldvargboundp)
- (let ((,temp1 (bump-echo-count ,slotname))
- (,loc-self ,(if (listp selfarg)
- (car selfarg)
- selfarg)))
- (when (and ,oldvargboundp ,oldvarg)
- (format t "~&echo ~d (~a ~a) old: ~a" ,temp1 ',slotname ,loc-self ,oldvarg))
- (format t "~&echo ~d (~a ~a) new: ~a" ,temp1 ',slotname ,loc-self ,newvarg))))
- `(defmethod c-echo-slot-name
- #-(or clisp cormanlisp) progn
- ((slotname (eql ',slotname)) ,selfarg ,newvarg ,oldvarg ,oldvargboundp)
- (declare (ignorable ,(etypecase selfarg
- (list (car selfarg))
- (atom selfarg))
- ,(etypecase newvarg
- (list (car newvarg))
- (atom newvarg))
- ,(etypecase oldvarg
- (list (car oldvarg))
- (atom oldvarg))
- ,(etypecase oldvargboundp
- (list (car oldvargboundp))
- (atom oldvargboundp))))
- ,@echobody))))
-
-(defmacro bump-echo-count (slotname) ;; pure test func
- `(if (get ',slotname :echos)
- (incf (get ',slotname :echos))
- (setf (get ',slotname :echos) 1)))
-
+;; -*- mode: Lisp; Syntax: Common-Lisp; Package: cells; -*-
+;;;
+;;; Copyright (c) 1995,2003 by Kenneth William Tilton.
+;;;
+;;; Permission is hereby granted, free of charge, to any person obtaining a copy
+;;; of this software and associated documentation files (the "Software"), to deal
+;;; in the Software without restriction, including without limitation the rights
+;;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+;;; copies of the Software, and to permit persons to whom the Software is furnished
+;;; to do so, subject to the following conditions:
+;;;
+;;; The above copyright notice and this permission notice shall be included in
+;;; all copies or substantial portions of the Software.
+;;;
+;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+;;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+;;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+;;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+;;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+;;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+;;; IN THE SOFTWARE.
+
+(in-package :cells)
+
+(defparameter *echodone* nil)
+
+(defun c-echo-defined (slot-name)
+ (getf (symbol-plist slot-name) :echo-defined))
+
+(defmethod (setf c-true-stalep) (newvalue (user c-ruled))
+ #+dfdbg (trc user "setting c-true-stalep" user newvalue)
+ (c-assert (find user (cells (c-model user)) :key #'cdr))
+ (setf (cd-stale-p user) newvalue))
+
+(defmethod (setf c-true-stalep) (newvalue (usersyn synapse))
+ #+dfdbg (trc (syn-user usersyn) "synapse setting c-true-stalep" (syn-user usersyn) newvalue usersyn)
+ (setf (cd-stale-p (syn-user usersyn)) newvalue))
+
+(defmethod (setf c-true-stalep) (newvalue other)
+ (declare (ignore other))
+ newvalue)
+
+(defun c-echo-initially (self slot-spec)
+ "call during instance init. if echo is defined for slot, and value is non-nil (controversial) force initial echo."
+ (trc nil "c-echo-initially" self slot-spec
+ (c-echo-defined (slot-spec-name slot-spec))
+ (md-slot-cell self slot-spec))
+ (if (c-echo-defined (slot-spec-name slot-spec))
+ (bif (c (md-slot-cell self slot-spec))
+ (etypecase c
+ (c-variable (md-propagate self slot-spec (c-value c) nil nil))
+ (c-ruled (md-slot-value self slot-spec))) ;; this will echo after calculating if not nil
+ ;
+ ; new for 22-03-07: echo even if slot value is nil...
+ (c-echo-slot-name (slot-spec-name slot-spec)
+ self
+ (bd-slot-value self slot-spec)
+ nil nil))
+ (bwhen (c (md-slot-cell self slot-spec))
+ (c-ephemeral-reset c))))
+
+#-(or cormanlisp clisp)
+(defgeneric c-echo-slot-name (slotname self new old old-boundp) (:method-combination progn))
+
+
+(defmethod c-echo-slot-name
+ #-(or cormanlisp clisp) progn
+ #+(or cormanlisp clisp) :before
+ (slot-name self new old old-boundp)
+ (declare (ignorable slot-name self new old old-boundp)))
+
+#+(or cormanlisp clisp)
+(defmethod c-echo-slot-name (slot-name self new old old-boundp)
+ (declare (ignorable slot-name self new old old-boundp)))
+
+;--------------- propagate ----------------------------
+;
+; n.b. 990414kt the cell argument may have been optimized away,
+; though it is still receiving final processing here.
+;
+
+(defun md-propagate (self slot-spec newvalue priorvalue priorvalue-supplied)
+ (when (mdead self)
+ (trc nil "md-propagate n-opping dead" self)
+ (return-from md-propagate nil))
+
+ (let (*c-calculators*
+ (*c-prop-depth* (1+ *c-prop-depth*))
+ (c (md-slot-cell self slot-spec)))
+ ;
+ ;------ debug stuff ---------
+ ;
+ (when *stop*
+ (princ #\.)(princ #\!)
+ (return-from md-propagate))
+
+ (when c
+ (trc nil "md-propagate> propping" self slot-spec (length (c-users c)) c)
+ )
+
+ (when *c-debug*
+ (when (> *c-prop-depth* 250)
+ (trc "md-propagate deep" *c-prop-depth* self (slot-spec-name slot-spec) #+nah c))
+ (when (> *c-prop-depth* 300)
+ (c-break "md-propagate looping ~c" c)
+ ))
+
+ (when c
+ ; ------ flag dependents as stale ------------
+ ; do before echo in case echo gets back to some user
+ ;
+ (dolist (user (c-users c))
+ #+dfdbg (trc user "md-prop now setting stale (changer, stale):" c user)
+ (when (c-user-cares user)
+ (setf (c-true-stalep user) c))))
+
+ ; --- manifest new value as needed -----------
+ (when (c-echo-defined (slot-spec-name slot-spec)) ;; /// faster than just dispatching?
+ (when c (trc nil "md-prop now echoing" c))
+ (c-echo-slot-name (slot-spec-name slot-spec)
+ self
+ newvalue
+ priorvalue
+ priorvalue-supplied)
+ (when (mdead self) ;; hopefully expiration on perishable class
+ (return-from md-propagate)))
+
+ (when c ; --- now propagate to dependents ------------
+ (trc nil "md-prop checking dependents" c (c-users c))
+ (let ((*cause* c))
+ (dolist (user (c-users c))
+ (unless (cmdead user)
+ (when (c-user-cares user)
+ (if (c-user-lazy user)
+ (progn
+ (trc nil "lazy user not being propagated to" user :by c)
+ (dolist (u (c-users user))
+ (c-propagate-staleness u)))
+ (progn
+ (c-rethink user)
+ (when (mdead self)
+ (trc nil "md-propagate> self now dead after rethink user: ~a" self user)
+ (return-from md-propagate nil))
+ )))))
+ (c-ephemeral-reset c)))))
+
+(defmethod c-propagate-staleness ((c c-ruled))
+ (trc nil "inheriting staleness" c)
+ (dolist (u (cr-users c))
+ (c-propagate-staleness u)))
+
+(defmethod c-propagate-staleness ((s synapse))
+ (trc "I hope this synapse isn't for efficiency" s)
+ (break)
+ (c-propagate-staleness (syn-user s)))
+
+(defmethod c-propagate-staleness (c)
+ (declare (ignorable c))
+ (trc "not inheriting or proagating staleness" c)
+ )
+
+(defmethod c-user-cares (c) c) ;; ie, t
+(defmethod c-user-cares ((s synapse))
+ (syn-relevant s))
+
+(defmethod c-user-lazy (c) (declare (ignore c)) nil)
+(defmethod c-user-lazy ((c c-ruled))
+ (cr-lazy c))
+
+
+(defun c-ephemeral-reset (c)
+ (when c
+ (when (c-ephemeral-p c)
+ (trc nil "c-ephemeral-reset resetting:" c)
+ (setf (c-value c) nil)))) ;; good q: what does (setf <ephem> 'x) return? historically nil, but...?
+
+;----------------- change detection ---------------------------------
+
+(defun c-no-news (c newvalue oldvalue)
+ ;;; (trc nil "c-no-news > checking news between" newvalue oldvalue)
+
+ (bIf (test (c-unchanged-test (c-model c) (c-slot-name c)))
+ (funcall test newvalue oldvalue)
+ (eql newvalue oldvalue)))
+
+(defmacro def-c-unchanged-test ((class slotname) &body test)
+ `(defmethod c-unchanged-test ((self ,class) (slotname (eql ',slotname)))
+ ,@test))
+
+(defmethod c-unchanged-test (self slotname)
+ (declare (ignore self slotname))
+ nil)
+
+(defmethod c-identity-p ((value null)) t)
+(defmethod c-identity-p ((value number)) (zerop value))
+(defmethod c-identity-p ((value cons))
+ ;; this def a little suspect?
+ (and (c-identity-p (car value))
+ (c-identity-p (cdr value))))
+
+
+;------------------- re think ---------------------------------
+
+(defun cmdead (c)
+ (if (typep c 'synapse)
+ (cmdead (syn-user c))
+ (if (null (c-model c))
+ (not (c-optimized-away-p c))
+ (mdead (c-model c)))))
+
+(defun mdead (m) (eq :eternal-rest (md-state m)))
+
+(defun c-rethink (c)
+ (when *stop*
+ (princ #\.)
+ (return-from c-rethink))
+ ;;(trc "rethink entry: c, true-stale" c (c-true-stalep c))
+ (c-assert (not (cmdead c))() "rethink entry cmdead ~a" c)
+ (unless (c-true-stalep c)
+ (return-from c-rethink))
+
+ (when *rethink-deferred*
+ (trc nil "bingo!!!!!! rethink deferring" c *cause*)
+ (push (list c *cause*) *rethink-deferred*)
+ (return-from c-rethink))
+
+ (c-assert (not (cmdead c))() "rethink here?? cmdead ~a" c)
+
+ ; looking ahead for interference avoids JIT detection, which where a dependency
+ ; already exists causes re-entrance into the rule, which should calculate the same
+ ; value twice and echo only once, but still seems like something to avoid since
+ ; we do already have the technology.
+ ;
+
+ (bIf (interf (sw-detect-interference c nil))
+ (progn
+ (trc "!!!!!!!!!! rethink of " c :held-up-by interf)
+ (c-pending-set c interf :interfered)
+ #+dfdbg (when (trcp c)
+ (trc "!!!!!!!!!! rethink of " c :held-up-by interf)
+ #+nah (dump-stale-path interf)
+ )
+ (return-from c-rethink))
+ (when (sw-pending c)
+ (trc nil "no interference now for " c)
+ (c-pending-set c nil :dis-interfered)))
+
+ (when (cmdead c)
+ (trc nil "woohoo!!! interference checking finished model off" c)
+ (return-from c-rethink))
+
+ (unless (c-true-stalep c)
+ (trc nil "woohoo!!! interference checking refreshed" c)
+ (return-from c-rethink))
+
+ (typecase c
+ (c-ruled (c-calculate-and-set c))
+
+ (synapse
+ (trc nil "c-rethink > testing rethink of: syn,salv,valu" c salvage (c-value (syn-used c)))
+ (if (funcall (syn-fire-p c) c (c-value (syn-used c)))
+ (progn
+ (trc nil "c-rethink> decide yes on rethink on syn, valu" c (c-value (syn-used c)))
+ (c-rethink (syn-user c)))
+ (trc nil "c-rethink> decide nooooo on rethink on synapse" c (syn-user c) salvage)))
+ ))
+
+(defmacro def-c-echo (slotname
+ (&optional (selfarg 'self) (newvarg 'new-value)
+ (oldvarg 'old-value) (oldvargboundp 'old-value-boundp))
+ &body echobody)
+ ;;;(trc "echo body" echobody)
+ `(progn
+ (eval-when (:compile-toplevel :load-toplevel :execute)
+ (setf (get ',slotname :echo-defined) t))
+ ,(if (eql (last1 echobody) :test)
+ (let ((temp1 (gensym))
+ (loc-self (gensym)))
+ `(defmethod c-echo-slot-name #-(or clisp cormanlisp) progn ((slotname (eql ',slotname)) ,selfarg ,newvarg ,oldvarg ,oldvargboundp)
+ (let ((,temp1 (bump-echo-count ,slotname))
+ (,loc-self ,(if (listp selfarg)
+ (car selfarg)
+ selfarg)))
+ (when (and ,oldvargboundp ,oldvarg)
+ (format t "~&echo ~d (~a ~a) old: ~a" ,temp1 ',slotname ,loc-self ,oldvarg))
+ (format t "~&echo ~d (~a ~a) new: ~a" ,temp1 ',slotname ,loc-self ,newvarg))))
+ `(defmethod c-echo-slot-name
+ #-(or clisp cormanlisp) progn
+ ((slotname (eql ',slotname)) ,selfarg ,newvarg ,oldvarg ,oldvargboundp)
+ (declare (ignorable ,(etypecase selfarg
+ (list (car selfarg))
+ (atom selfarg))
+ ,(etypecase newvarg
+ (list (car newvarg))
+ (atom newvarg))
+ ,(etypecase oldvarg
+ (list (car oldvarg))
+ (atom oldvarg))
+ ,(etypecase oldvargboundp
+ (list (car oldvargboundp))
+ (atom oldvargboundp))))
+ ,@echobody))))
+
+(defmacro bump-echo-count (slotname) ;; pure test func
+ `(if (get ',slotname :echos)
+ (incf (get ',slotname :echos))
+ (setf (get ',slotname :echos) 1)))
+
Index: cells/qells.lisp
diff -u cells/qells.lisp:1.1.1.1 cells/qells.lisp:1.2
--- cells/qells.lisp:1.1.1.1 Sat Nov 8 18:44:34 2003
+++ cells/qells.lisp Tue Dec 16 10:02:58 2003
@@ -1,326 +1,326 @@
-;; -*- mode: Lisp; Syntax: Common-Lisp; Package: cells; -*-
-;;;
-;;; Copyright © 1995,2003 by Kenneth William Tilton.
-;;;
-;;; Permission is hereby granted, free of charge, to any person obtaining a copy
-;;; of this software and associated documentation files (the "Software"), to deal
-;;; in the Software without restriction, including without limitation the rights
-;;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-;;; copies of the Software, and to permit persons to whom the Software is furnished
-;;; to do so, subject to the following conditions:
-;;;
-;;; The above copyright notice and this permission notice shall be included in
-;;; all copies or substantial portions of the Software.
-;;;
-;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-;;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-;;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-;;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-;;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-;;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-;;; IN THE SOFTWARE.
-
-(in-package :cells)
-
-
-(defconstant *c-optimizep* t)
-(defvar *c-prop-depth* 0)
-(defvar *rethinker* nil)
-(defvar *rethink-deferred* nil)
-(defvar *synapse-factory* nil)
-(defvar *sw-looping* nil)
-
-(defun cell-reset ()
- (kwt-reset)
- (setf
- *c-prop-depth* 0
- *sw-looping* nil
- *to-be-awakened* nil
- ))
-
-
-(defun cellstop ()
- (break :in-cell-stop)
- (setf *stop* t))
-
-(defun cellbrk (&optional (tag :anon))
- (unless (or *stop*)
- ;; daring move, hoping having handler at outside stops the game (cellstop)
- (print `(cell break , tag))
- (break)))
-
-(defparameter *c-debug*
- #+runtime-system nil
- #-runtime-system nil) ;; make latter t when in trouble
-
-
-(defvar *c-calculators* nil)
-
-(defmacro without-c-dependency (&body body)
- `(let (*c-calculators*) ,@body))
-
-(defun slot-spec-name (slot-spec)
- slot-spec)
-
-(cc-defstruct (cell (:conc-name c-))
- waking-state
- model
- slot-spec
- value
- )
-
-(defun c-slot-name (c)
- (slot-spec-name (c-slot-spec c)))
-
-(defun c-validate (self c)
- (when (not (and (c-slot-spec c) (c-model c)))
-;;; (setf *stop* t)
- (format t "~&unadopted cell: ~s md:~s, awake:~s" c self (c-waking-state self))
- (error 'c-unadopted :cell c)))
-
-(defmethod c-when (other)
- (declare (ignorable other)) nil) ;; /// needs work
-
-(cc-defstruct (synapse
- (:include cell)
- (:conc-name syn-))
- user
- used
- fire-p
- relay-value)
-
-(defmacro mksynapse ((&rest closeovervars) &key fire-p relay-value)
- (let ((used (copy-symbol 'used)) (user (copy-symbol 'user)))
- `(lambda (,used ,user)
- ;; (trc "making synapse between user" ,user :and :used ,used)
- (let (,@closeovervars)
- (make-synapse
- :used ,used
- ;;; 210207kt why? use (c-model (syn-used <syn>)) :c-model (c-model ,used)
- :user ,user
-
- :fire-p ,fire-p
- :relay-value ,relay-value)))))
-
-(defmethod print-object ((syn synapse) stream)
- (format stream "{syn ~s ==> ~s" (syn-used syn) (syn-user syn)))
-
-
-(defmethod c-true-stalep ((syn synapse))
- (cd-stale-p (syn-user syn)))
-
-(cc-defstruct (c-user-notifying
- (:include cell)
- (:conc-name un-))
- (users nil :type list))
-
-(cc-defstruct (c-unsteady
- (:include c-user-notifying)
- (:conc-name unst-))
- cyclic-p
- delta-p
- setting-p)
-
-(cc-defstruct (c-variable
- (:include c-unsteady)))
-
-(cc-defstruct (c-ruled
- (:include c-unsteady)
- (:conc-name cr-))
- (state :unbound :type symbol)
- (rethinking 0 :type number)
- rule)
-
-(defun c-optimized-away-p (c)
- (eql :optimized-away (c-state c)))
-
-;----------------------------
-
-
-(defmethod c-true-stalep (c)
- (declare (ignore c)))
-
-(cc-defstruct (c-independent
- ;;
- ;; these do not optimize away, because also these can be set after initial evaluation of the rule,
- ;; so users better stay tuned.
- ;; the whole idea here is that the old idea of having cv bodies evaluated immediately finally
- ;; broke down when we wanted to say :kids (cv (list (fm-other vertex)))
- ;;
- (:include c-ruled)))
-
-;;;(defmethod trcp ((c c-dependent))
-;;; (trcp (c-model c)))
-
-(cc-defstruct (c-dependent
- (:include c-ruled)
- (:conc-name cd-))
- (useds nil :type list)
- (code nil :type list) ;; /// feature this out on production build
- (usage (make-array *cd-usagect* :element-type 'bit
- :initial-element 0) :type vector)
- stale-p
- )
-
-
-(defmethod c-true-stalep ((c c-dependent))
- (cd-stale-p c))
-
-(cc-defstruct (c-stream
- (:include c-ruled)
- (:conc-name cs-))
- values)
-
-;;; (defmacro cell~ (&body body)
-;;; `(make-c-stream
-;;; :rule (lambda ,@*c-lambda*
-;;; ,@body)))
-
-(cc-defstruct (c-drifter
- (:include c-dependent)))
-
-(cc-defstruct (c-drifter-absolute
- (:include c-drifter)))
-
-;_____________________ accessors __________________________________
-
-
-(defun (setf c-state) (new-value c)
- (if (typep c 'c-ruled)
- (setf (cr-state c) new-value)
- new-value))
-
-(defun c-state (c)
- (if (typep c 'c-ruled)
- (cr-state c)
- :valid))
-
-(defun c-unboundp (c)
- (eql :unbound (c-state c)))
-
-(defun c-validp (c)
- (find (c-state c) '(:valid :optimized-away)))
-
-;_____________________ print __________________________________
-
-(defmethod print-object :before ((c c-variable) stream)
- (declare (ignorable c))
- (format stream "[var:"))
-
-(defmethod print-object :before ((c c-dependent) stream)
- (declare (ignorable c))
- (format stream "[dep~a:" (cond
- ((null (c-model c)) #\0)
- ((eq :eternal-rest (md-state (c-model c))) #\_)
- ((cd-stale-p c) #\#)
- ((sw-pending c) #\?)
- (t #\space))))
-
-(defmethod print-object :before ((c c-independent) stream)
- (declare (ignorable c))
- (format stream "[ind:"))
-
-(defmethod print-object ((c cell) stream)
- (c-print-value c stream)
- (format stream "=~a/~a]"
- (symbol-name (or (c-slot-name c) :anoncell))
- (or (c-model c) :anonmd))
- #+dfdbg (unless *stop*
- (assert (find c (cells (c-model c)) :key #'cdr)))
- )
-
-
-;__________________
-
-(defmethod c-print-value ((c c-ruled) stream)
- (format stream "~a" (cond ((unst-setting-p c) "<^^^>")
- ((c-validp c) "<vld>")
- ((c-unboundp c) "<unb>")
- ((cd-stale-p c) "<obs>")
- (t "<err>"))))
-
-(defmethod c-print-value (c stream)
- (declare (ignore c stream)))
-
-
-;____________________ constructors _______________________________
-
-(defmacro c? (&body body)
- `(make-c-dependent
- :code ',body
- :rule (lambda (c &aux (self (c-model c)))
- (declare (ignorable self c))
- ,@body)))
- (define-symbol-macro .cache. (c-value c))
-
-(defmacro c?? ((&key (tagp nil) (in nil) (trigger nil) (out t))&body body)
- (let ((result (copy-symbol 'result))
- (thetag (gensym)))
- `(make-c-dependent
- :code ',body
- :rule (lambda (c &aux (self (c-model c)))
- (declare (ignorable self c))
- (let ((,thetag (gensym "tag"))
- (*trcdepth* (1+ *trcdepth*))
- )
- (declare (ignorable self ,thetag))
- ,(when in
- `(trc "c??> entry" (c-slot-name c) (c-model c) (when ,tagp ,thetag)))
- ,(when trigger `(trc "c??> trigger" *rethinker* c))
- (count-it :c?? (c-slot-name c) (md-name (c-model c)))
- (let ((,result (progn ,@body)))
- ,(when out `(trc "c?? result:" ,result (c-slot-name c) (when ,tagp ,thetag)))
- ,result))))))
-
-
-(defmacro cv (defn)
- `(make-c-variable
- :value ,defn)) ;; use c-independent if need deferred execution
-
-(defmacro cv8 (defn)
- `(make-c-variable
- :cyclic-p t
- :value ,defn)) ;; use c-independent if need deferred execution
-
-
-(defmacro c... ((value) &body body)
- `(make-c-drifter
- :code ',body
- :value ,value
- :rule (lambda (c &aux (self (c-model c)))
- (declare (ignorable self c))
- ,@body)))
-
-(defmacro c-abs (value &body body)
- `(make-c-drifter-absolute
- :code ',body
- :value ,value
- :rule (lambda (c &aux (self (c-model c)))
- (declare (ignorable self c))
- ,@body)))
-
-
-;;; (defmacro c?v (&body body)
-;;; `(make-c-independent
-;;; :rule (lambda ,@*c-lambda*
-;;; (declare (ignorable self askingcells))
-;;; ,@body)))
-;;;
-;;; (defmacro cvpi ((&body options) defn)
-;;; `(make-c-variable :value ,defn
-;;; ,@options))
-;;;
-;;; (defmacro ts? (&body body)
-;;; `(lambda (self)
-;;; (declare (ignorable self))
-;;; ,@body))
-;;;
-(defmacro c8 (&body body)
- `(make-c-dependent
- :cyclic-p t
- :rule (lambda (c)
- (let ((self (c-model c))
- (*c-calculators* (cons c *c-calculators*))
- *synapse-factory* ;; clear then re-estab via with-synapse on specific dependencies
- )
- ,@body))))
+;; -*- mode: Lisp; Syntax: Common-Lisp; Package: cells; -*-
+;;;
+;;; Copyright (c) 1995,2003 by Kenneth William Tilton.
+;;;
+;;; Permission is hereby granted, free of charge, to any person obtaining a copy
+;;; of this software and associated documentation files (the "Software"), to deal
+;;; in the Software without restriction, including without limitation the rights
+;;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+;;; copies of the Software, and to permit persons to whom the Software is furnished
+;;; to do so, subject to the following conditions:
+;;;
+;;; The above copyright notice and this permission notice shall be included in
+;;; all copies or substantial portions of the Software.
+;;;
+;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+;;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+;;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+;;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+;;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+;;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+;;; IN THE SOFTWARE.
+
+(in-package :cells)
+
+
+(defconstant *c-optimizep* t)
+(defvar *c-prop-depth* 0)
+(defvar *rethinker* nil)
+(defvar *rethink-deferred* nil)
+(defvar *synapse-factory* nil)
+(defvar *sw-looping* nil)
+
+(defun cell-reset ()
+ (kwt-reset)
+ (setf
+ *c-prop-depth* 0
+ *sw-looping* nil
+ *to-be-awakened* nil
+ ))
+
+
+(defun cellstop ()
+ (break :in-cell-stop)
+ (setf *stop* t))
+
+(defun cellbrk (&optional (tag :anon))
+ (unless (or *stop*)
+ ;; daring move, hoping having handler at outside stops the game (cellstop)
+ (print `(cell break , tag))
+ (break)))
+
+(defparameter *c-debug*
+ #+runtime-system nil
+ #-runtime-system nil) ;; make latter t when in trouble
+
+
+(defvar *c-calculators* nil)
+
+(defmacro without-c-dependency (&body body)
+ `(let (*c-calculators*) ,@body))
+
+(defun slot-spec-name (slot-spec)
+ slot-spec)
+
+(cc-defstruct (cell (:conc-name c-))
+ waking-state
+ model
+ slot-spec
+ value
+ )
+
+(defun c-slot-name (c)
+ (slot-spec-name (c-slot-spec c)))
+
+(defun c-validate (self c)
+ (when (not (and (c-slot-spec c) (c-model c)))
+;;; (setf *stop* t)
+ (format t "~&unadopted cell: ~s md:~s, awake:~s" c self (c-waking-state self))
+ (error 'c-unadopted :cell c)))
+
+(defmethod c-when (other)
+ (declare (ignorable other)) nil) ;; /// needs work
+
+(cc-defstruct (synapse
+ (:include cell)
+ (:conc-name syn-))
+ user
+ used
+ fire-p
+ relay-value)
+
+(defmacro mksynapse ((&rest closeovervars) &key fire-p relay-value)
+ (let ((used (copy-symbol 'used)) (user (copy-symbol 'user)))
+ `(lambda (,used ,user)
+ ;; (trc "making synapse between user" ,user :and :used ,used)
+ (let (,@closeovervars)
+ (make-synapse
+ :used ,used
+ ;;; 210207kt why? use (c-model (syn-used <syn>)) :c-model (c-model ,used)
+ :user ,user
+
+ :fire-p ,fire-p
+ :relay-value ,relay-value)))))
+
+(defmethod print-object ((syn synapse) stream)
+ (format stream "{syn ~s ==> ~s" (syn-used syn) (syn-user syn)))
+
+
+(defmethod c-true-stalep ((syn synapse))
+ (cd-stale-p (syn-user syn)))
+
+(cc-defstruct (c-user-notifying
+ (:include cell)
+ (:conc-name un-))
+ (users nil :type list))
+
+(cc-defstruct (c-unsteady
+ (:include c-user-notifying)
+ (:conc-name unst-))
+ cyclic-p
+ delta-p
+ setting-p)
+
+(cc-defstruct (c-variable
+ (:include c-unsteady)))
+
+(cc-defstruct (c-ruled
+ (:include c-unsteady)
+ (:conc-name cr-))
+ (state :unbound :type symbol)
+ (rethinking 0 :type number)
+ rule)
+
+(defun c-optimized-away-p (c)
+ (eql :optimized-away (c-state c)))
+
+;----------------------------
+
+
+(defmethod c-true-stalep (c)
+ (declare (ignore c)))
+
+(cc-defstruct (c-independent
+ ;;
+ ;; these do not optimize away, because also these can be set after initial evaluation of the rule,
+ ;; so users better stay tuned.
+ ;; the whole idea here is that the old idea of having cv bodies evaluated immediately finally
+ ;; broke down when we wanted to say :kids (cv (list (fm-other vertex)))
+ ;;
+ (:include c-ruled)))
+
+;;;(defmethod trcp ((c c-dependent))
+;;; (trcp (c-model c)))
+
+(cc-defstruct (c-dependent
+ (:include c-ruled)
+ (:conc-name cd-))
+ (useds nil :type list)
+ (code nil :type list) ;; /// feature this out on production build
+ (usage (make-array *cd-usagect* :element-type 'bit
+ :initial-element 0) :type vector)
+ stale-p
+ )
+
+
+(defmethod c-true-stalep ((c c-dependent))
+ (cd-stale-p c))
+
+(cc-defstruct (c-stream
+ (:include c-ruled)
+ (:conc-name cs-))
+ values)
+
+;;; (defmacro cell~ (&body body)
+;;; `(make-c-stream
+;;; :rule (lambda ,@*c-lambda*
+;;; ,@body)))
+
+(cc-defstruct (c-drifter
+ (:include c-dependent)))
+
+(cc-defstruct (c-drifter-absolute
+ (:include c-drifter)))
+
+;_____________________ accessors __________________________________
+
+
+(defun (setf c-state) (new-value c)
+ (if (typep c 'c-ruled)
+ (setf (cr-state c) new-value)
+ new-value))
+
+(defun c-state (c)
+ (if (typep c 'c-ruled)
+ (cr-state c)
+ :valid))
+
+(defun c-unboundp (c)
+ (eql :unbound (c-state c)))
+
+(defun c-validp (c)
+ (find (c-state c) '(:valid :optimized-away)))
+
+;_____________________ print __________________________________
+
+(defmethod print-object :before ((c c-variable) stream)
+ (declare (ignorable c))
+ (format stream "[var:"))
+
+(defmethod print-object :before ((c c-dependent) stream)
+ (declare (ignorable c))
+ (format stream "[dep~a:" (cond
+ ((null (c-model c)) #\0)
+ ((eq :eternal-rest (md-state (c-model c))) #\_)
+ ((cd-stale-p c) #\#)
+ ((sw-pending c) #\?)
+ (t #\space))))
+
+(defmethod print-object :before ((c c-independent) stream)
+ (declare (ignorable c))
+ (format stream "[ind:"))
+
+(defmethod print-object ((c cell) stream)
+ (c-print-value c stream)
+ (format stream "=~a/~a]"
+ (symbol-name (or (c-slot-name c) :anoncell))
+ (or (c-model c) :anonmd))
+ #+dfdbg (unless *stop*
+ (assert (find c (cells (c-model c)) :key #'cdr)))
+ )
+
+
+;__________________
+
+(defmethod c-print-value ((c c-ruled) stream)
+ (format stream "~a" (cond ((unst-setting-p c) "<^^^>")
+ ((c-validp c) "<vld>")
+ ((c-unboundp c) "<unb>")
+ ((cd-stale-p c) "<obs>")
+ (t "<err>"))))
+
+(defmethod c-print-value (c stream)
+ (declare (ignore c stream)))
+
+
+;____________________ constructors _______________________________
+
+(defmacro c? (&body body)
+ `(make-c-dependent
+ :code ',body
+ :rule (lambda (c &aux (self (c-model c)))
+ (declare (ignorable self c))
+ ,@body)))
+ (define-symbol-macro .cache. (c-value c))
+
+(defmacro c?? ((&key (tagp nil) (in nil) (trigger nil) (out t))&body body)
+ (let ((result (copy-symbol 'result))
+ (thetag (gensym)))
+ `(make-c-dependent
+ :code ',body
+ :rule (lambda (c &aux (self (c-model c)))
+ (declare (ignorable self c))
+ (let ((,thetag (gensym "tag"))
+ (*trcdepth* (1+ *trcdepth*))
+ )
+ (declare (ignorable self ,thetag))
+ ,(when in
+ `(trc "c??> entry" (c-slot-name c) (c-model c) (when ,tagp ,thetag)))
+ ,(when trigger `(trc "c??> trigger" *rethinker* c))
+ (count-it :c?? (c-slot-name c) (md-name (c-model c)))
+ (let ((,result (progn ,@body)))
+ ,(when out `(trc "c?? result:" ,result (c-slot-name c) (when ,tagp ,thetag)))
+ ,result))))))
+
+
+(defmacro cv (defn)
+ `(make-c-variable
+ :value ,defn)) ;; use c-independent if need deferred execution
+
+(defmacro cv8 (defn)
+ `(make-c-variable
+ :cyclic-p t
+ :value ,defn)) ;; use c-independent if need deferred execution
+
+
+(defmacro c... ((value) &body body)
+ `(make-c-drifter
+ :code ',body
+ :value ,value
+ :rule (lambda (c &aux (self (c-model c)))
+ (declare (ignorable self c))
+ ,@body)))
+
+(defmacro c-abs (value &body body)
+ `(make-c-drifter-absolute
+ :code ',body
+ :value ,value
+ :rule (lambda (c &aux (self (c-model c)))
+ (declare (ignorable self c))
+ ,@body)))
+
+
+;;; (defmacro c?v (&body body)
+;;; `(make-c-independent
+;;; :rule (lambda ,@*c-lambda*
+;;; (declare (ignorable self askingcells))
+;;; ,@body)))
+;;;
+;;; (defmacro cvpi ((&body options) defn)
+;;; `(make-c-variable :value ,defn
+;;; ,@options))
+;;;
+;;; (defmacro ts? (&body body)
+;;; `(lambda (self)
+;;; (declare (ignorable self))
+;;; ,@body))
+;;;
+(defmacro c8 (&body body)
+ `(make-c-dependent
+ :cyclic-p t
+ :rule (lambda (c)
+ (let ((self (c-model c))
+ (*c-calculators* (cons c *c-calculators*))
+ *synapse-factory* ;; clear then re-estab via with-synapse on specific dependencies
+ )
+ ,@body))))
Index: cells/qrock.lisp
diff -u cells/qrock.lisp:1.1.1.1 cells/qrock.lisp:1.2
--- cells/qrock.lisp:1.1.1.1 Sat Nov 8 18:44:46 2003
+++ cells/qrock.lisp Tue Dec 16 10:02:58 2003
@@ -1,83 +1,83 @@
-;; -*- mode: Lisp; Syntax: Common-Lisp; Package: cells; -*-
-;;;
-;;;
-;;; Copyright © 1995,2003 by Kenneth William Tilton.
-;;;
-;;; Permission is hereby granted, free of charge, to any person obtaining a copy
-;;; of this software and associated documentation files (the "Software"), to deal
-;;; in the Software without restriction, including without limitation the rights
-;;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-;;; copies of the Software, and to permit persons to whom the Software is furnished
-;;; to do so, subject to the following conditions:
-;;;
-;;; The above copyright notice and this permission notice shall be included in
-;;; all copies or substantial portions of the Software.
-;;;
-;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-;;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-;;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-;;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-;;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-;;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-;;; IN THE SOFTWARE.
-
-
-(in-package :cells)
-
-(defstruct (qrock (:include strudel-object)(:conc-name nil))
- (.accel 32)
- (.elapsed (cv 0))
- (.dist (c? (floor (* (qaccel self)(expt (elapsed self) 2)) 2))))
-
-(defun qaccel (self)
- (q-slot-value (.accel self)))
-
-(defun (setf qaccel) (newvalue self)
- (setf (md-slot-value self '.accel) newvalue))
-
-(defun elapsed (self)
- (q-slot-value (.elapsed self)))
-
-(defun (setf elapsed) (newvalue self)
- (setf (md-slot-value self '.elapsed) newvalue))
-
-(defun dist (self)
- (q-slot-value (.dist self)))
-
-(defun (setf dist) (newvalue self)
- (setf (md-slot-value self '.dist) newvalue))
-
-(def-c-echo .accel () (trc ".accel" self new-value old-value))
-(def-c-echo .elapsed ()
- (when (typep new-value 'cell) (break))
- (trc ".elapsed" self new-value old-value))
-(def-c-echo .dist () (trc ".dist" self new-value old-value))
-
-(progn
- (setf (md-slot-cell-type 'qrock '.accel) t)
- (setf (md-slot-cell-type 'qrock '.elapsed) t)
- (setf (md-slot-cell-type 'qrock '.dist) t))
-
-(defun make-cell-qrock (&rest iargs)
- (let ((self (apply #'make-qrock iargs)))
- (strudel-initialize self)
- (trc "qcs" (q-cells self))
- self))
-
-#+test
-(let (*to-be-awakened*)
- (let ((r (to-be (make-cell-qrock))))
- (dotimes (n 5)
- (trc "--------------- time " n)
- (setf (elapsed r) n))))
-
-(defmethod strudel-initialize :around ((self qrock))
- (flet ((ci (sn sv)
- (when (typep sv 'cell)
- (q-install self sn sv))))
- (ci '.accel (.accel self))
- (ci '.elapsed (.elapsed self))
- (ci '.dist (.dist self)))
- (call-next-method))
-
-
+;; -*- mode: Lisp; Syntax: Common-Lisp; Package: cells; -*-
+;;;
+;;;
+;;; Copyright (c) 1995,2003 by Kenneth William Tilton.
+;;;
+;;; Permission is hereby granted, free of charge, to any person obtaining a copy
+;;; of this software and associated documentation files (the "Software"), to deal
+;;; in the Software without restriction, including without limitation the rights
+;;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+;;; copies of the Software, and to permit persons to whom the Software is furnished
+;;; to do so, subject to the following conditions:
+;;;
+;;; The above copyright notice and this permission notice shall be included in
+;;; all copies or substantial portions of the Software.
+;;;
+;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+;;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+;;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+;;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+;;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+;;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+;;; IN THE SOFTWARE.
+
+
+(in-package :cells)
+
+(defstruct (qrock (:include strudel-object)(:conc-name nil))
+ (.accel 32)
+ (.elapsed (cv 0))
+ (.dist (c? (floor (* (qaccel self)(expt (elapsed self) 2)) 2))))
+
+(defun qaccel (self)
+ (q-slot-value (.accel self)))
+
+(defun (setf qaccel) (newvalue self)
+ (setf (md-slot-value self '.accel) newvalue))
+
+(defun elapsed (self)
+ (q-slot-value (.elapsed self)))
+
+(defun (setf elapsed) (newvalue self)
+ (setf (md-slot-value self '.elapsed) newvalue))
+
+(defun dist (self)
+ (q-slot-value (.dist self)))
+
+(defun (setf dist) (newvalue self)
+ (setf (md-slot-value self '.dist) newvalue))
+
+(def-c-echo .accel () (trc ".accel" self new-value old-value))
+(def-c-echo .elapsed ()
+ (when (typep new-value 'cell) (break))
+ (trc ".elapsed" self new-value old-value))
+(def-c-echo .dist () (trc ".dist" self new-value old-value))
+
+(progn
+ (setf (md-slot-cell-type 'qrock '.accel) t)
+ (setf (md-slot-cell-type 'qrock '.elapsed) t)
+ (setf (md-slot-cell-type 'qrock '.dist) t))
+
+(defun make-cell-qrock (&rest iargs)
+ (let ((self (apply #'make-qrock iargs)))
+ (strudel-initialize self)
+ (trc "qcs" (q-cells self))
+ self))
+
+#+test
+(let (*to-be-awakened*)
+ (let ((r (to-be (make-cell-qrock))))
+ (dotimes (n 5)
+ (trc "--------------- time " n)
+ (setf (elapsed r) n))))
+
+(defmethod strudel-initialize :around ((self qrock))
+ (flet ((ci (sn sv)
+ (when (typep sv 'cell)
+ (q-install self sn sv))))
+ (ci '.accel (.accel self))
+ (ci '.elapsed (.elapsed self))
+ (ci '.dist (.dist self)))
+ (call-next-method))
+
+
Index: cells/slot-utilities.lisp
diff -u cells/slot-utilities.lisp:1.1.1.1 cells/slot-utilities.lisp:1.2
--- cells/slot-utilities.lisp:1.1.1.1 Sat Nov 8 18:44:46 2003
+++ cells/slot-utilities.lisp Tue Dec 16 10:02:58 2003
@@ -1,91 +1,95 @@
-;; -*- mode: Lisp; Syntax: Common-Lisp; Package: cells; -*-
-;;;
-;;; Copyright © 1995,2003 by Kenneth William Tilton.
-;;;
-;;; Permission is hereby granted, free of charge, to any person obtaining a copy
-;;; of this software and associated documentation files (the "Software"), to deal
-;;; in the Software without restriction, including without limitation the rights
-;;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-;;; copies of the Software, and to permit persons to whom the Software is furnished
-;;; to do so, subject to the following conditions:
-;;;
-;;; The above copyright notice and this permission notice shall be included in
-;;; all copies or substantial portions of the Software.
-;;;
-;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-;;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-;;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-;;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-;;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-;;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-;;; IN THE SOFTWARE.
-
-(in-package :cells)
-
-(defun c-setting-debug (self slot-spec c newvalue)
- (declare (ignorable newvalue))
- (if (null c)
- (progn
- (format t "c-setting-debug > constant ~a in ~a may not be altered..init to (cv nil)"
- slot-spec self)
- (error "setting-const-cell"))
- (let ((self (c-model c))
- (slot-spec (c-slot-spec c)))
- ;(trc "c-setting-debug sees" c newvalue self slot-spec)
- (when (and c (not (and slot-spec self)))
- ;; cv-test handles errors, so don't set *stop* (cellstop)
- (error 'c-unadopted :cell c))
- (typecase c
- (c-variable)
- (c-independent)
- (c-dependent
- ;(trc "setting c-dependent" c newvalue)
- (format t "c-setting-debug > ruled ~a in ~a may not be setf'ed"
- (c-slot-name c) self)
- (error "setting-ruled-cell"))
- ))))
-
-(defun c-absorb-value (c value)
- (typecase c
- (c-drifter-absolute (c-value-incf c value 0)) ;; strange but true
- (c-drifter (c-value-incf c (c-value c) value))
- (t value)))
-
-(defmethod c-value-incf (c (envaluer c-envaluer) delta)
- (assert (c-model c))
- (c-value-incf c (funcall (envaluerule envaluer) (c-model c))
- delta))
-
-(defmethod c-value-incf (c (base number) delta)
- (declare (ignore c))
- (if delta
- (+ base delta)
- base))
-
-
-;----------------------------------------------------------------------
-
-(defun bd-slot-value (self slot-spec)
- (slot-value self (slot-spec-name slot-spec)))
-
-(defun (setf bd-slot-value) (newvalue self slot-spec)
- (setf (slot-value self (slot-spec-name slot-spec)) newvalue))
-
-(defun bd-bound-slot-value (self slot-spec callerid)
- (declare (ignorable callerid))
- (when (bd-slot-boundp self (slot-spec-name slot-spec))
- (bd-slot-value self (slot-spec-name slot-spec))))
-
-(defun bd-slot-boundp (self slot-spec)
- (slot-boundp self (slot-spec-name slot-spec)))
-
-(defun bd-slot-makunbound (self slot-spec)
- (slot-makunbound self (slot-spec-name slot-spec)))
-
-#| sample incf
-(defmethod c-value-incf ((base fpoint) delta)
- (declare (ignore model))
- (if delta
- (fp-add base delta)
- base))
-|#
+;; -*- mode: Lisp; Syntax: Common-Lisp; Package: cells; -*-
+;;;
+;;; Copyright (c) 1995,2003 by Kenneth William Tilton.
+;;;
+;;; Permission is hereby granted, free of charge, to any person obtaining a copy
+;;; of this software and associated documentation files (the "Software"), to deal
+;;; in the Software without restriction, including without limitation the rights
+;;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+;;; copies of the Software, and to permit persons to whom the Software is furnished
+;;; to do so, subject to the following conditions:
+;;;
+;;; The above copyright notice and this permission notice shall be included in
+;;; all copies or substantial portions of the Software.
+;;;
+;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+;;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+;;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+;;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+;;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+;;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+;;; IN THE SOFTWARE.
+
+(in-package :cells)
+
+(defun c-setting-debug (self slot-spec c newvalue)
+ (declare (ignorable newvalue))
+ (if (null c)
+ (progn
+ (format t "c-setting-debug > constant ~a in ~a may not be altered..init to (cv nil)"
+ slot-spec self)
+
+ (c-break "setting-const-cell")
+ (error "setting-const-cell"))
+ (let ((self (c-model c))
+ (slot-spec (c-slot-spec c)))
+ ;(trc "c-setting-debug sees" c newvalue self slot-spec)
+ (when (and c (not (and slot-spec self)))
+ ;; cv-test handles errors, so don't set *stop* (c-stop)
+ (c-break "unadopted ~a for self ~a spec ~a" c self slot-spec)
+ (error 'c-unadopted :cell c))
+ (typecase c
+ (c-variable)
+ (c-dependent
+ ;(trc "setting c-dependent" c newvalue)
+ (format t "c-setting-debug > ruled ~a in ~a may not be setf'ed"
+ (c-slot-name c) self)
+
+ (c-break "setting-ruled-cell")
+ (error "setting-ruled-cell"))
+ ))))
+
+(defun c-absorb-value (c value)
+ (typecase c
+ (c-drifter-absolute (c-value-incf c value 0)) ;; strange but true
+ (c-drifter (c-value-incf c (c-value c) value))
+ (t value)))
+
+(defmethod c-value-incf (c (envaluer c-envaluer) delta)
+ (c-assert (c-model c))
+ (c-value-incf c (funcall (envaluerule envaluer) c)
+ delta))
+
+(defmethod c-value-incf (c (base number) delta)
+ (declare (ignore c))
+ (if delta
+ (+ base delta)
+ base))
+
+
+;----------------------------------------------------------------------
+
+(defun bd-slot-value (self slot-spec)
+ (slot-value self (slot-spec-name slot-spec)))
+
+(defun (setf bd-slot-value) (newvalue self slot-spec)
+ (setf (slot-value self (slot-spec-name slot-spec)) newvalue))
+
+(defun bd-bound-slot-value (self slot-spec callerid)
+ (declare (ignorable callerid))
+ (when (bd-slot-boundp self (slot-spec-name slot-spec))
+ (bd-slot-value self (slot-spec-name slot-spec))))
+
+(defun bd-slot-boundp (self slot-spec)
+ (slot-boundp self (slot-spec-name slot-spec)))
+
+(defun bd-slot-makunbound (self slot-spec)
+ (slot-makunbound self (slot-spec-name slot-spec)))
+
+#| sample incf
+(defmethod c-value-incf ((base fpoint) delta)
+ (declare (ignore model))
+ (if delta
+ (fp-add base delta)
+ base))
+|#
Index: cells/strings.lisp
diff -u cells/strings.lisp:1.1.1.1 cells/strings.lisp:1.2
--- cells/strings.lisp:1.1.1.1 Sat Nov 8 18:44:46 2003
+++ cells/strings.lisp Tue Dec 16 10:02:58 2003
@@ -1,204 +1,204 @@
-;; -*- mode: Lisp; Syntax: Common-Lisp; Package: cells; -*-
-;;;
-;;; Copyright © 1995,2003 by Kenneth William Tilton.
-;;;
-;;; Permission is hereby granted, free of charge, to any person obtaining a copy
-;;; of this software and associated documentation files (the "Software"), to deal
-;;; in the Software without restriction, including without limitation the rights
-;;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-;;; copies of the Software, and to permit persons to whom the Software is furnished
-;;; to do so, subject to the following conditions:
-;;;
-;;; The above copyright notice and this permission notice shall be included in
-;;; all copies or substantial portions of the Software.
-;;;
-;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-;;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-;;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-;;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-;;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-;;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-;;; IN THE SOFTWARE.
-
-(in-package :cells)
-
-(eval-when (compile load eval)
- (export '(case$ strloc$ make$ space$ char$ conclist$ conc$
- left$ mid$ seg$ right$ insert$ remove$
- trim$ trunc$ abbrev$ empty$ find$ num$
- normalize$ down$ lower$ up$ upper$ equal$
- min$ numeric$ alpha$ assoc$ member$ match-left$
- +return$+ +LF$+)))
-
-(defmacro case$ (stringForm &rest cases)
- (let ((v$ (gensym))
- (default (or (find 'otherwise cases :key #'car)
- (find 'otherwise cases :key #'car))))
- (when default
- (setf cases (delete default cases)))
- `(let ((,v$ ,stringForm))
- (cond
- ,@(mapcar (lambda (caseForms)
- `((string-equal ,v$ ,(car caseForms)) ,@(rest caseForms)))
- cases)
- (t ,@(or (cdr default) `(nil)))))))
-
-;--------
-
-(defmethod shortc (other)
- (declare (ignorable other))
- (concatenate 'string "noshortc" (symbol-name (class-name (class-of other)))))
-
-(defmethod longc (other) (shortc other))
-
-(defmethod shortc ((nada null)) nil)
-(defmethod shortc ((many list))
- (if (consp (cdr many))
- (mapcar #'shortc many)
- (conc$ (shortc (car many)) " " (shortc (cdr many)))))
-(defmethod shortc ((self string)) self)
-(defmethod shortc ((self symbol)) (string self))
-(defmethod shortc ((self number)) (num$ self))
-(defmethod shortc ((self character)) (string self))
-
-;-----------------------
-
-(defun strloc$ (substr str)
- (when (and substr str (not (string= substr "")))
- (search substr str)))
-
-(defun make$ (&optional (size 0) (char #\space))
- (make-string size :initial-element (etypecase char
- (character char)
- (number (code-char char)))))
-
-(DEFUN space$ (size)
- (make$ size))
-
-(defun char$ (char)
- (make$ 1 char))
-
-(defun conclist$ (ss)
- (when ss
- (reduce (lambda (s1 s2) (concatenate 'string s1 s2)) ss)))
-
-(defun conc$ (&rest ss)
- (with-output-to-string (stream)
- (dolist (s ss)
- (when s
- (princ (shortc s) stream)))))
-
-(defun left$ (s n)
- (subseq s 0 (max (min n (length s)) 0)))
-
-(defun mid$ (s offset length)
- (let* ((slen (length s))
- (start (min slen (max offset 0)))
- (end (max start (min (+ offset length) slen))))
- (subseq s start end)))
-
-(defun seg$ (s offset end)
- (let* ((slen (length s))
- (start (min slen (max offset 0)))
- (end (max start (min end slen))))
- (subseq s start end)))
-
-(defun right$ (s n)
- (subseq s (min n (length s))))
-
-(defun insert$ (s c &optional (offset (length s)))
- (conc$ (subseq s 0 offset)
- (string c)
- (subseq s offset)))
-
-(defun remove$ (s offset)
- (conc$ (subseq s 0 (1- offset))
- (subseq s offset)))
-
-(defun trim$ (s)
- (assert (or (null s) (stringp s)))
- (string-trim '(#\space) s))
-
-(defun trunc$ (s char)
- (let ((pos (position char s)))
- (if pos
- (subseq s 0 pos)
- s)))
-
-(defun abbrev$ (long$ max)
- (if (<= (length long$) max)
- long$
- (conc$ (left$ long$ (- max 3)) "...")))
-
-(defmethod empty ((nada null)) t)
-(defmethod empty ((c cons))
- (and (empty (car c))
- (empty (cdr c))))
-(defmethod empty ((s string)) (empty$ s))
-(defmethod empty (other) (declare (ignorable other)) nil)
-
-(defun empty$ (s)
- (or (null s)
- (if (stringp s)
- (string-equal "" (trim$ s))
- #+not (trc nil "empty$> sees non-string" (type-of s)))
- ))
-
-(defmacro find$ (it where &rest args)
- `(find ,it ,where ,@args :test #'string-equal))
-
-(defmethod num$ ((n number))
- (format nil "~d" n))
-
-(defmethod num$ (n)
- (format nil "~d" n))
-
-(defun normalize$ (s)
- (etypecase s
- (null "")
- (string (string-downcase s))
- (symbol (string-downcase (symbol-name s)))))
-
-(defun down$ (s)
- (string-downcase s))
-
-(defun lower$ (s)
- (string-downcase s))
-
-(defun up$ (s)
- (string-upcase s))
-
-(defun upper$ (s)
- (string-upcase s))
-
-(defun equal$ (s1 s2)
- (if (empty$ s1)
- (empty$ s2)
- (when s2
- (string-equal s1 s2))))
-
-(defun min$ (&rest ss)
- (cond
- ((null ss) nil)
- ((null (cdr ss)) (car ss))
- (t (let ((rmin$ (apply #'min$ (cdr ss))))
- (if (string< (car ss) rmin$)
- (car ss) rmin$)))))
-
-(defun numeric$ (s &optional trimmed)
- (every (lambda (c) (digit-char-p c)) (if trimmed (Trim$ s) s)))
-
-(defun alpha$ (s)
- (every (lambda (c) (alpha-char-p c)) s))
-
-(defmacro assoc$ (item alist &rest kws)
- `(assoc ,item ,alist :test #'equal ,@kws))
-
-(defmacro member$ (item list &rest kws)
- `(member ,item ,list :test #'string= ,@kws))
-
-(defun match-left$ (a b)
- (string-equal a (subseq b 0 (length a))))
-
-(defparameter *return$* (conc$ (char$ #\return) (char$ #\linefeed)))
-(defparameter *LF$* (string #\linefeed))
+;; -*- mode: Lisp; Syntax: Common-Lisp; Package: cells; -*-
+;;;
+;;; Copyright (c) 1995,2003 by Kenneth William Tilton.
+;;;
+;;; Permission is hereby granted, free of charge, to any person obtaining a copy
+;;; of this software and associated documentation files (the "Software"), to deal
+;;; in the Software without restriction, including without limitation the rights
+;;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+;;; copies of the Software, and to permit persons to whom the Software is furnished
+;;; to do so, subject to the following conditions:
+;;;
+;;; The above copyright notice and this permission notice shall be included in
+;;; all copies or substantial portions of the Software.
+;;;
+;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+;;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+;;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+;;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+;;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+;;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+;;; IN THE SOFTWARE.
+
+(in-package :cells)
+
+(eval-when (compile load eval)
+ (export '(case$ strloc$ make$ space$ char$ conclist$ conc$
+ left$ mid$ seg$ right$ insert$ remove$
+ trim$ trunc$ abbrev$ empty$ find$ num$
+ normalize$ down$ lower$ up$ upper$ equal$
+ min$ numeric$ alpha$ assoc$ member$ match-left$
+ +return$+ +LF$+)))
+
+(defmacro case$ (stringForm &rest cases)
+ (let ((v$ (gensym))
+ (default (or (find 'otherwise cases :key #'car)
+ (find 'otherwise cases :key #'car))))
+ (when default
+ (setf cases (delete default cases)))
+ `(let ((,v$ ,stringForm))
+ (cond
+ ,@(mapcar (lambda (caseForms)
+ `((string-equal ,v$ ,(car caseForms)) ,@(rest caseForms)))
+ cases)
+ (t ,@(or (cdr default) `(nil)))))))
+
+;--------
+
+(defmethod shortc (other)
+ (declare (ignorable other))
+ (concatenate 'string "noshortc" (symbol-name (class-name (class-of other)))))
+
+(defmethod longc (other) (shortc other))
+
+(defmethod shortc ((nada null)) nil)
+(defmethod shortc ((many list))
+ (if (consp (cdr many))
+ (mapcar #'shortc many)
+ (conc$ (shortc (car many)) " " (shortc (cdr many)))))
+(defmethod shortc ((self string)) self)
+(defmethod shortc ((self symbol)) (string self))
+(defmethod shortc ((self number)) (num$ self))
+(defmethod shortc ((self character)) (string self))
+
+;-----------------------
+
+(defun strloc$ (substr str)
+ (when (and substr str (not (string= substr "")))
+ (search substr str)))
+
+(defun make$ (&optional (size 0) (char #\space))
+ (make-string size :initial-element (etypecase char
+ (character char)
+ (number (code-char char)))))
+
+(DEFUN space$ (size)
+ (make$ size))
+
+(defun char$ (char)
+ (make$ 1 char))
+
+(defun conclist$ (ss)
+ (when ss
+ (reduce (lambda (s1 s2) (concatenate 'string s1 s2)) ss)))
+
+(defun conc$ (&rest ss)
+ (with-output-to-string (stream)
+ (dolist (s ss)
+ (when s
+ (princ (shortc s) stream)))))
+
+(defun left$ (s n)
+ (subseq s 0 (max (min n (length s)) 0)))
+
+(defun mid$ (s offset length)
+ (let* ((slen (length s))
+ (start (min slen (max offset 0)))
+ (end (max start (min (+ offset length) slen))))
+ (subseq s start end)))
+
+(defun seg$ (s offset end)
+ (let* ((slen (length s))
+ (start (min slen (max offset 0)))
+ (end (max start (min end slen))))
+ (subseq s start end)))
+
+(defun right$ (s n)
+ (subseq s (min n (length s))))
+
+(defun insert$ (s c &optional (offset (length s)))
+ (conc$ (subseq s 0 offset)
+ (string c)
+ (subseq s offset)))
+
+(defun remove$ (s offset)
+ (conc$ (subseq s 0 (1- offset))
+ (subseq s offset)))
+
+(defun trim$ (s)
+ (c-assert (or (null s) (stringp s)))
+ (string-trim '(#\space) s))
+
+(defun trunc$ (s char)
+ (let ((pos (position char s)))
+ (if pos
+ (subseq s 0 pos)
+ s)))
+
+(defun abbrev$ (long$ max)
+ (if (<= (length long$) max)
+ long$
+ (conc$ (left$ long$ (- max 3)) "...")))
+
+(defmethod empty ((nada null)) t)
+(defmethod empty ((c cons))
+ (and (empty (car c))
+ (empty (cdr c))))
+(defmethod empty ((s string)) (empty$ s))
+(defmethod empty (other) (declare (ignorable other)) nil)
+
+(defun empty$ (s)
+ (or (null s)
+ (if (stringp s)
+ (string-equal "" (trim$ s))
+ #+not (trc nil "empty$> sees non-string" (type-of s)))
+ ))
+
+(defmacro find$ (it where &rest args)
+ `(find ,it ,where ,@args :test #'string-equal))
+
+(defmethod num$ ((n number))
+ (format nil "~d" n))
+
+(defmethod num$ (n)
+ (format nil "~d" n))
+
+(defun normalize$ (s)
+ (etypecase s
+ (null "")
+ (string (string-downcase s))
+ (symbol (string-downcase (symbol-name s)))))
+
+(defun down$ (s)
+ (string-downcase s))
+
+(defun lower$ (s)
+ (string-downcase s))
+
+(defun up$ (s)
+ (string-upcase s))
+
+(defun upper$ (s)
+ (string-upcase s))
+
+(defun equal$ (s1 s2)
+ (if (empty$ s1)
+ (empty$ s2)
+ (when s2
+ (string-equal s1 s2))))
+
+(defun min$ (&rest ss)
+ (cond
+ ((null ss) nil)
+ ((null (cdr ss)) (car ss))
+ (t (let ((rmin$ (apply #'min$ (cdr ss))))
+ (if (string< (car ss) rmin$)
+ (car ss) rmin$)))))
+
+(defun numeric$ (s &optional trimmed)
+ (every (lambda (c) (digit-char-p c)) (if trimmed (Trim$ s) s)))
+
+(defun alpha$ (s)
+ (every (lambda (c) (alpha-char-p c)) s))
+
+(defmacro assoc$ (item alist &rest kws)
+ `(assoc ,item ,alist :test #'equal ,@kws))
+
+(defmacro member$ (item list &rest kws)
+ `(member ,item ,list :test #'string= ,@kws))
+
+(defun match-left$ (a b)
+ (string-equal a (subseq b 0 (length a))))
+
+(defparameter *return$* (conc$ (char$ #\return) (char$ #\linefeed)))
+(defparameter *LF$* (string #\linefeed))
Index: cells/strudel-object.lisp
diff -u cells/strudel-object.lisp:1.1.1.1 cells/strudel-object.lisp:1.2
--- cells/strudel-object.lisp:1.1.1.1 Sat Nov 8 18:44:46 2003
+++ cells/strudel-object.lisp Tue Dec 16 10:02:58 2003
@@ -1,145 +1,145 @@
-;; -*- mode: Lisp; Syntax: Common-Lisp; Package: cells; -*-
-;;;
-;;;
-;;; Copyright © 1995,2003 by Kenneth William Tilton.
-;;;
-;;; Permission is hereby granted, free of charge, to any person obtaining a copy
-;;; of this software and associated documentation files (the "Software"), to deal
-;;; in the Software without restriction, including without limitation the rights
-;;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-;;; copies of the Software, and to permit persons to whom the Software is furnished
-;;; to do so, subject to the following conditions:
-;;;
-;;; The above copyright notice and this permission notice shall be included in
-;;; all copies or substantial portions of the Software.
-;;;
-;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-;;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-;;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-;;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-;;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-;;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-;;; IN THE SOFTWARE.
-
-(in-package :cells)
-
-;----------------- model-object ----------------------
-
-(eval-when (:compile-toplevel :load-toplevel :execute)
- (export '(strudel-object)))
-
-(cc-defstruct (strudel-object (:conc-name nil))
- (q-state :nascent :type keyword) ; [nil | :nascent | :alive | :doomed]
- (q-name nil :type symbol)
- (q-parent nil)
- (q-cells nil :type list)
- (q-cells-flushed nil :type list)
- (q-adopt-ct 0 :type fixnum))
-
-(defmethod strudel-initialize (self)
- (unless (q-name self)
- (setf (q-name self) (class-name (class-of self))))
-
- #+wait (when (q-parent self)
- (q-adopt (q-parent self) self))
- self)
-
-(defmethod cells ((self strudel-object))
- (q-cells self))
-
-(defmethod (setf cells) (new-value (self strudel-object))
- (setf (q-cells self) new-value))
-
-(defmethod kids ((other strudel-object)) nil)
-
-(defun q-install (self sn c)
- (assert (typep c 'cell))
- (trc nil "installing cell" sn c)
- (setf
- (c-model c) self
- (c-slot-spec c) sn
- (md-slot-cell self sn) c))
-
-(defmethod (setf md-state) (newv (self strudel-object))
- (setf (q-state self) newv))
-
-(defmethod md-state ((self strudel-object))
- (q-state self))
-
-(defmethod md-name ((self strudel-object)) (q-name self))
-(defmethod fmparent ((self strudel-object)) (q-parent self))
-
-(defmethod print-object ((self strudel-object) s)
- (format s "~a" (or (md-name self) (type-of self))))
-
-(defun q-slot-value (slot-c)
- (when *stop*
- (princ #\.)
- (return-from q-slot-value))
- ;; (count-it :q-slot-value slot-name slot-spec))
-
-;;; (when (eql :nascent (q-state self))
-;;; (md-awaken self))
-
- (let ((slot-value (typecase slot-c
- (c-variable (c-value slot-c))
-
- (c-ruled (cond
- ((c-validp slot-c) (c-value slot-c)) ;; good to go
-
- ((find slot-c *c-calculators*) ;; circularity
- (setf *stop* t)
- (trc "q-slot-value breaking on circlularity" slot-c *c-calculators*)
- (error "cell ~a midst askers: ~a" slot-c *c-calculators*))
-
- (t (let ((*cause* :on-demand)) ; normal path first time asked
- (trc nil "md-slot-value calc" self slot-spec *c-calculators*)
- (c-calculate-and-set slot-c)))))
- (otherwise (return-from q-slot-value slot-c)))))
-
- (bif (synapse (when (car *c-calculators*)
- (c-link-ex slot-c)))
- (c-relay-value synapse slot-value)
- slot-value)))
-
-
-
-
-(defmethod md-awaken :around ((self strudel-object))
- (trc nil "md-awaken entry" self (md-state self))
- (assert (eql :nascent (md-state self)))
- ;; (trc nil "awaken doing")
- (count-it :md-awaken)
- ;;(count-it 'mdawaken (type-of self))
- (setf (md-state self) :awakening)
- ;; (trc "md-awaken entry" self)
- (dolist (esd (class-slots (class-of self)))
- ;;(trc "md-awaken scoping slot" self (slot-definition-name esd))
- (when (md-slot-cell-type (type-of self) (slot-definition-name esd))
- (let ((slot-name (slot-definition-name esd)))
- (if (not (c-echo-defined slot-name))
- (progn ;; (count-it :md-awaken :no-echo-slot slot-name)
- (trc nil "md-awaken deferring cell-awaken since no echo" self esd))
-
- (let ((cell (md-slot-cell self slot-name)))
- (trc nil "md-awaken finds md-esd-cell " self slot-name cell)
-
-
- (if cell
- (c-awaken cell)
- ;
- ; next bit revised to avoid double-echo of optimized cells
- ;
- (progn
- (when (eql '.kids slot-name)
- (bwhen (sv (slot-value self '.kids))
- (md-kids-change self sv nil :md-awaken-slot)))
- (c-echo-initially self slot-name)))))))
- )
-
- (setf (md-state self) :awake)
- self)
-
-(defmethod md-slot-value-store ((self strudel-object) slot-spec new-value)
- (declare (ignorable slot-spec))
+;; -*- mode: Lisp; Syntax: Common-Lisp; Package: cells; -*-
+;;;
+;;;
+;;; Copyright (c) 1995,2003 by Kenneth William Tilton.
+;;;
+;;; Permission is hereby granted, free of charge, to any person obtaining a copy
+;;; of this software and associated documentation files (the "Software"), to deal
+;;; in the Software without restriction, including without limitation the rights
+;;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+;;; copies of the Software, and to permit persons to whom the Software is furnished
+;;; to do so, subject to the following conditions:
+;;;
+;;; The above copyright notice and this permission notice shall be included in
+;;; all copies or substantial portions of the Software.
+;;;
+;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+;;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+;;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+;;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+;;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+;;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+;;; IN THE SOFTWARE.
+
+(in-package :cells)
+
+;----------------- model-object ----------------------
+
+(eval-when (:compile-toplevel :load-toplevel :execute)
+ (export '(strudel-object)))
+
+(cc-defstruct (strudel-object (:conc-name nil))
+ (q-state :nascent :type keyword) ; [nil | :nascent | :alive | :doomed]
+ (q-name nil :type symbol)
+ (q-parent nil)
+ (q-cells nil :type list)
+ (q-cells-flushed nil :type list)
+ (q-adopt-ct 0 :type fixnum))
+
+(defmethod strudel-initialize (self)
+ (unless (q-name self)
+ (setf (q-name self) (class-name (class-of self))))
+
+ #+wait (when (q-parent self)
+ (q-adopt (q-parent self) self))
+ self)
+
+(defmethod cells ((self strudel-object))
+ (q-cells self))
+
+(defmethod (setf cells) (new-value (self strudel-object))
+ (setf (q-cells self) new-value))
+
+(defmethod kids ((other strudel-object)) nil)
+
+(defun q-install (self sn c)
+ (assert (typep c 'cell))
+ (trc nil "installing cell" sn c)
+ (setf
+ (c-model c) self
+ (c-slot-spec c) sn
+ (md-slot-cell self sn) c))
+
+(defmethod (setf md-state) (newv (self strudel-object))
+ (setf (q-state self) newv))
+
+(defmethod md-state ((self strudel-object))
+ (q-state self))
+
+(defmethod md-name ((self strudel-object)) (q-name self))
+(defmethod fm-parent ((self strudel-object)) (q-parent self))
+
+(defmethod print-object ((self strudel-object) s)
+ (format s "~a" (or (md-name self) (type-of self))))
+
+(defun q-slot-value (slot-c)
+ (when *stop*
+ (princ #\.)
+ (return-from q-slot-value))
+ ;; (count-it :q-slot-value slot-name slot-spec))
+
+;;; (when (eql :nascent (q-state self))
+;;; (md-awaken self))
+
+ (let ((slot-value (typecase slot-c
+ (c-variable (c-value slot-c))
+
+ (c-ruled (cond
+ ((c-validp slot-c) (c-value slot-c)) ;; good to go
+
+ ((find slot-c *c-calculators*) ;; circularity
+ (setf *stop* t)
+ (trc "q-slot-value breaking on circlularity" slot-c *c-calculators*)
+ (error "cell ~a midst askers: ~a" slot-c *c-calculators*))
+
+ (t (let ((*cause* :on-demand)) ; normal path first time asked
+ (trc nil "md-slot-value calc" self slot-spec *c-calculators*)
+ (c-calculate-and-set slot-c)))))
+ (otherwise (return-from q-slot-value slot-c)))))
+
+ (bif (synapse (when (car *c-calculators*)
+ (c-link-ex slot-c)))
+ (c-relay-value synapse slot-value)
+ slot-value)))
+
+
+
+
+(defmethod md-awaken :around ((self strudel-object))
+ (trc nil "md-awaken entry" self (md-state self))
+ (assert (eql :nascent (md-state self)))
+ ;; (trc nil "awaken doing")
+ (count-it :md-awaken)
+ ;;(count-it 'mdawaken (type-of self))
+ (setf (md-state self) :awakening)
+ ;; (trc "md-awaken entry" self)
+ (dolist (esd (class-slots (class-of self)))
+ ;;(trc "md-awaken scoping slot" self (slot-definition-name esd))
+ (when (md-slot-cell-type (type-of self) (slot-definition-name esd))
+ (let ((slot-name (slot-definition-name esd)))
+ (if (not (c-echo-defined slot-name))
+ (progn ;; (count-it :md-awaken :no-echo-slot slot-name)
+ (trc nil "md-awaken deferring cell-awaken since no echo" self esd))
+
+ (let ((cell (md-slot-cell self slot-name)))
+ (trc nil "md-awaken finds md-esd-cell " self slot-name cell)
+
+
+ (if cell
+ (c-awaken cell)
+ ;
+ ; next bit revised to avoid double-echo of optimized cells
+ ;
+ (progn
+ (when (eql '.kids slot-name)
+ (bwhen (sv (slot-value self '.kids))
+ (md-kids-change self sv nil :md-awaken-slot)))
+ (c-echo-initially self slot-name)))))))
+ )
+
+ (setf (md-state self) :awake)
+ self)
+
+(defmethod md-slot-value-store ((self strudel-object) slot-spec new-value)
+ (declare (ignorable slot-spec))
new-value)
Index: cells/synapse.lisp
diff -u cells/synapse.lisp:1.1.1.1 cells/synapse.lisp:1.2
--- cells/synapse.lisp:1.1.1.1 Sat Nov 8 18:44:46 2003
+++ cells/synapse.lisp Tue Dec 16 10:02:58 2003
@@ -1,213 +1,213 @@
-;; -*- mode: Lisp; Syntax: Common-Lisp; Package: cells; -*-
-;;;
-;;; Copyright © 1995,2003 by Kenneth William Tilton.
-;;;
-;;; Permission is hereby granted, free of charge, to any person obtaining a copy
-;;; of this software and associated documentation files (the "Software"), to deal
-;;; in the Software without restriction, including without limitation the rights
-;;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-;;; copies of the Software, and to permit persons to whom the Software is furnished
-;;; to do so, subject to the following conditions:
-;;;
-;;; The above copyright notice and this permission notice shall be included in
-;;; all copies or substantial portions of the Software.
-;;;
-;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-;;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-;;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-;;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-;;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-;;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-;;; IN THE SOFTWARE.
-
-(in-package :cells)
-
-(eval-when (:compile-toplevel :load-toplevel :execute)
- (export '(mksynapse fDelta fSensitivity fPlusp fZerop fDifferent)))
-
-; ___________________________ cell relay value ___________________________________
-
-(defparameter *relayspeak* nil)
-(defmethod c-relay-value ((syn synapse) value)
- ;(trc "c-relay-value> syn, raw value:" syn value)
- (let ((res (funcall (syn-relay-value syn) syn value)))
- ;(trc "c-relay-value> cell, filtered value:" syn res)
- res))
-
-(defmethod c-relay-value (cell value)
- (declare (ignorable cell))
- (when *relayspeak*
- (trc "c-relay-value unspecial > cell value" cell value)
- (setf *relayspeak* nil))
- value)
-
-;__________________________________________________________________________________
-;
-(defmethod delta-diff ((new number) (old number) subtypename)
- (declare (ignore subtypename))
- (- new old))
-
-(defmethod delta-identity ((dispatcher number) subtypename)
- (declare (ignore subtypename))
- 0)
-
-(defmethod delta-abs ((n number) subtypename)
- (declare (ignore subtypename))
- (abs n))
-
-(defmethod delta-exceeds ((d1 number) (d2 number) subtypename)
- (declare (ignore subtypename))
- (> d1 d2))
-
-(defmethod delta-greater-or-equal ((d1 number) (d2 number) subtypename)
- (declare (ignore subtypename))
- (>= d1 d2))
-
-;_________________________________________________________________________________
-;
-(defmethod delta-diff (new old (subtypename (eql 'boolean)))
- (if new
- (if old
- :unchanged
- :on)
- (if old
- :off
- :unchanged)))
-
-
-(defmethod delta-identity (dispatcher (subtypename (eql 'boolean)))
- (declare (ignore dispatcher))
- :unchanged)
-
-;______________________________________________________________
-
-(defun fdeltalist (&key (test #'true))
- (mksynapse (priorlist)
- :fire-p (lambda (syn newlist)
- (declare (ignorable syn))
- (or (find-if (lambda (new)
- ;--- gaining one? ----
- (and (not (member new priorlist))
- (funcall test new)))
- newlist)
- (find-if (lambda (old)
- ;--- losing one? ----
- (not (member old newlist))) ;; all olds have passed test, so skip test here
- priorlist)))
-
- :relay-value (lambda (syn newlist)
- (declare (ignorable syn))
- ;/// excess consing on long lists
- (setf priorlist (remove-if-not test newlist)))))
-
-;_______________________________________________________________
-
-(defun ffindonce (finderfn)
- (mksynapse (bingo bingobound)
-
- :fire-p (lambda (syn newlist)
- (declare (ignorable syn))
- (unless bingo ;; once found, yer done
- (setf bingobound t
- bingo (find-if finderfn newlist))))
-
- :relay-value (lambda (syn newlist)
- (declare (ignorable syn))
- (or bingo
- (and (not bingobound) ;; don't bother if fire? already looked
- (find-if finderfn newlist))))))
-
-;___________________________________________________________________
-
-(defun fsensitivity (sensitivity &optional subtypename)
- (mksynapse (priorrelayvalue)
- :fire-p (lambda (syn newvalue)
- (declare (ignorable syn))
- (trc nil "fire-p decides" priorrelayvalue sensitivity)
- (or (xor priorrelayvalue newvalue)
- (eko (nil "fire-p decides" newvalue priorrelayvalue sensitivity)
- (delta-greater-or-equal
- (delta-abs (delta-diff newvalue priorrelayvalue subtypename) subtypename)
- (delta-abs sensitivity subtypename)
- subtypename))))
-
- :relay-value (lambda (syn newvalue)
- (declare (ignorable syn))
- (eko (nil "fsensitivity relays")
- (setf priorrelayvalue newvalue)) ;; no modulation of value, but do record for next time
- )))
-
-(defun fPlusp ()
- (mksynapse (priorrelayvalue)
- :fire-p (lambda (syn new-basis)
- (declare (ignorable syn))
- (eko (nil "fPlusp fire-p decides" priorrelayvalue sensitivity)
- (xor priorrelayvalue (plusp new-basis))))
-
- :relay-value (lambda (syn new-basis)
- (declare (ignorable syn))
- (eko (nil "fPlusp relays")
- (setf priorrelayvalue (plusp new-basis))) ;; no modulation of value, but do record for next time
- )))
-
-(defun fZerop ()
- (mksynapse (priorrelayvalue)
- :fire-p (lambda (syn new-basis)
- (declare (ignorable syn))
- (eko (nil "fZerop fire-p decides")
- (xor priorrelayvalue (zerop new-basis))))
-
- :relay-value (lambda (syn new-basis)
- (declare (ignorable syn))
- (eko (nil "fZerop relays")
- (setf priorrelayvalue (zerop new-basis)))
- )))
-
-(defun fDifferent ()
- (mksynapse (prior-object)
- :fire-p (lambda (syn new-object)
- (declare (ignorable syn))
- (trc nil "fDiff: prior,new" (not (eql new-object prior-object))
- prior-object new-object)
- (not (eql new-object prior-object)))
-
- :relay-value (lambda (syn new-object)
- (declare (ignorable syn))
- (unless (eql new-object prior-object)
- (setf prior-object new-object)))
- ))
-;
-;____________________ synapse constructors _______________________________
-;
-(defun fdelta (&key sensitivity (type 'number))
- (mksynapse (lastrelaybasis lastboundp)
- :fire-p (lambda (syn newbasis)
- (declare (ignorable syn))
- (eko (nil "delta fire-p")
- (or (null sensitivity)
- (let ((delta (delta-diff newbasis lastrelaybasis type)))
- (delta-exceeds delta sensitivity type)))))
-
- :relay-value (lambda (syn newbasis)
- (declare (ignorable syn))
- (prog1
- (if lastboundp
- (delta-diff newbasis lastrelaybasis type)
- (delta-identity newbasis type))
- ;(trc "filter yields to user, value" (c-slot-name user) (c-slot-spec syn) relayvalue)
- ;(trc "fdelta > ********************* new lastrelay! " syn lastrelaybasis)
- (setf lastboundp t)
- (setf lastrelaybasis newbasis)))
- ))
-
-
-
-(defmethod delta-exceeds (booldelta sensitivity (subtypename (eql 'boolean)))
- (unless (eql booldelta :unchanged)
- (or (eq sensitivity t)
- (eq sensitivity booldelta))))
-
-(defun fboolean (&optional (sensitivity 't))
- (fdelta :sensitivity sensitivity :type 'boolean))
-
-
+;; -*- mode: Lisp; Syntax: Common-Lisp; Package: cells; -*-
+;;;
+;;; Copyright (c) 1995,2003 by Kenneth William Tilton.
+;;;
+;;; Permission is hereby granted, free of charge, to any person obtaining a copy
+;;; of this software and associated documentation files (the "Software"), to deal
+;;; in the Software without restriction, including without limitation the rights
+;;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+;;; copies of the Software, and to permit persons to whom the Software is furnished
+;;; to do so, subject to the following conditions:
+;;;
+;;; The above copyright notice and this permission notice shall be included in
+;;; all copies or substantial portions of the Software.
+;;;
+;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+;;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+;;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+;;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+;;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+;;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+;;; IN THE SOFTWARE.
+
+(in-package :cells)
+
+(eval-when (:compile-toplevel :load-toplevel :execute)
+ (export '(mksynapse fDelta fSensitivity fPlusp fZerop fDifferent)))
+
+; ___________________________ cell relay value ___________________________________
+
+(defparameter *relayspeak* nil)
+(defmethod c-relay-value ((syn synapse) value)
+ ;(trc "c-relay-value> syn, raw value:" syn value)
+ (let ((res (funcall (syn-relay-value syn) syn value)))
+ ;(trc "c-relay-value> cell, filtered value:" syn res)
+ res))
+
+(defmethod c-relay-value (cell value)
+ (declare (ignorable cell))
+ (when *relayspeak*
+ (trc "c-relay-value unspecial > cell value" cell value)
+ (setf *relayspeak* nil))
+ value)
+
+;__________________________________________________________________________________
+;
+(defmethod delta-diff ((new number) (old number) subtypename)
+ (declare (ignore subtypename))
+ (- new old))
+
+(defmethod delta-identity ((dispatcher number) subtypename)
+ (declare (ignore subtypename))
+ 0)
+
+(defmethod delta-abs ((n number) subtypename)
+ (declare (ignore subtypename))
+ (abs n))
+
+(defmethod delta-exceeds ((d1 number) (d2 number) subtypename)
+ (declare (ignore subtypename))
+ (> d1 d2))
+
+(defmethod delta-greater-or-equal ((d1 number) (d2 number) subtypename)
+ (declare (ignore subtypename))
+ (>= d1 d2))
+
+;_________________________________________________________________________________
+;
+(defmethod delta-diff (new old (subtypename (eql 'boolean)))
+ (if new
+ (if old
+ :unchanged
+ :on)
+ (if old
+ :off
+ :unchanged)))
+
+
+(defmethod delta-identity (dispatcher (subtypename (eql 'boolean)))
+ (declare (ignore dispatcher))
+ :unchanged)
+
+;______________________________________________________________
+
+(defun fdeltalist (&key (test #'true))
+ (mksynapse (priorlist)
+ :fire-p (lambda (syn newlist)
+ (declare (ignorable syn))
+ (or (find-if (lambda (new)
+ ;--- gaining one? ----
+ (and (not (member new priorlist))
+ (funcall test new)))
+ newlist)
+ (find-if (lambda (old)
+ ;--- losing one? ----
+ (not (member old newlist))) ;; all olds have passed test, so skip test here
+ priorlist)))
+
+ :relay-value (lambda (syn newlist)
+ (declare (ignorable syn))
+ ;/// excess consing on long lists
+ (setf priorlist (remove-if-not test newlist)))))
+
+;_______________________________________________________________
+
+(defun ffindonce (finderfn)
+ (mksynapse (bingo bingobound)
+
+ :fire-p (lambda (syn newlist)
+ (declare (ignorable syn))
+ (unless bingo ;; once found, yer done
+ (setf bingobound t
+ bingo (find-if finderfn newlist))))
+
+ :relay-value (lambda (syn newlist)
+ (declare (ignorable syn))
+ (or bingo
+ (and (not bingobound) ;; don't bother if fire? already looked
+ (find-if finderfn newlist))))))
+
+;___________________________________________________________________
+
+(defun fsensitivity (sensitivity &optional subtypename)
+ (mksynapse (priorrelayvalue)
+ :fire-p (lambda (syn newvalue)
+ (declare (ignorable syn))
+ (trc nil "fire-p decides" priorrelayvalue sensitivity)
+ (or (xor priorrelayvalue newvalue)
+ (eko (nil "fire-p decides" newvalue priorrelayvalue sensitivity)
+ (delta-greater-or-equal
+ (delta-abs (delta-diff newvalue priorrelayvalue subtypename) subtypename)
+ (delta-abs sensitivity subtypename)
+ subtypename))))
+
+ :relay-value (lambda (syn newvalue)
+ (declare (ignorable syn))
+ (eko (nil "fsensitivity relays")
+ (setf priorrelayvalue newvalue)) ;; no modulation of value, but do record for next time
+ )))
+
+(defun fPlusp ()
+ (mksynapse (priorrelayvalue)
+ :fire-p (lambda (syn new-basis)
+ (declare (ignorable syn))
+ (eko (nil "fPlusp fire-p decides" priorrelayvalue sensitivity)
+ (xor priorrelayvalue (plusp new-basis))))
+
+ :relay-value (lambda (syn new-basis)
+ (declare (ignorable syn))
+ (eko (nil "fPlusp relays")
+ (setf priorrelayvalue (plusp new-basis))) ;; no modulation of value, but do record for next time
+ )))
+
+(defun fZerop ()
+ (mksynapse (priorrelayvalue)
+ :fire-p (lambda (syn new-basis)
+ (declare (ignorable syn))
+ (eko (nil "fZerop fire-p decides")
+ (xor priorrelayvalue (zerop new-basis))))
+
+ :relay-value (lambda (syn new-basis)
+ (declare (ignorable syn))
+ (eko (nil "fZerop relays")
+ (setf priorrelayvalue (zerop new-basis)))
+ )))
+
+(defun fDifferent ()
+ (mksynapse (prior-object)
+ :fire-p (lambda (syn new-object)
+ (declare (ignorable syn))
+ (trc nil "fDiff: prior,new" (not (eql new-object prior-object))
+ prior-object new-object)
+ (not (eql new-object prior-object)))
+
+ :relay-value (lambda (syn new-object)
+ (declare (ignorable syn))
+ (unless (eql new-object prior-object)
+ (setf prior-object new-object)))
+ ))
+;
+;____________________ synapse constructors _______________________________
+;
+(defun fdelta (&key sensitivity (type 'number))
+ (mksynapse (lastrelaybasis lastboundp)
+ :fire-p (lambda (syn newbasis)
+ (declare (ignorable syn))
+ (eko (nil "delta fire-p")
+ (or (null sensitivity)
+ (let ((delta (delta-diff newbasis lastrelaybasis type)))
+ (delta-exceeds delta sensitivity type)))))
+
+ :relay-value (lambda (syn newbasis)
+ (declare (ignorable syn))
+ (prog1
+ (if lastboundp
+ (delta-diff newbasis lastrelaybasis type)
+ (delta-identity newbasis type))
+ ;(trc "filter yields to user, value" (c-slot-name user) (c-slot-spec syn) relayvalue)
+ ;(trc "fdelta > ********************* new lastrelay! " syn lastrelaybasis)
+ (setf lastboundp t)
+ (setf lastrelaybasis newbasis)))
+ ))
+
+
+
+(defmethod delta-exceeds (booldelta sensitivity (subtypename (eql 'boolean)))
+ (unless (eql booldelta :unchanged)
+ (or (eq sensitivity t)
+ (eq sensitivity booldelta))))
+
+(defun fboolean (&optional (sensitivity 't))
+ (fdelta :sensitivity sensitivity :type 'boolean))
+
+