home *** CD-ROM | disk | FTP | other *** search
/ vis-ftp.cs.umass.edu / vis-ftp.cs.umass.edu.tar / vis-ftp.cs.umass.edu / pub / Software / ASCENDER / ascendMar8.tar / UMass / ISR / isr2tss.lisp < prev    next >
Lisp/Scheme  |  1995-04-11  |  59KB  |  1,512 lines

  1. ;;; -*- Mode:Common-Lisp; Package:isr2; Base:10; -*-
  2. ;;;------------------------------------------------------------------------
  3. ;;; ISR2TSS.LISP - Token[sub]sequence functions
  4. ;;; Created: Wed May 18 10:07:22 1988
  5. ;;; Author: Robert Heller
  6. ;;;------------------------------------------------------------------------
  7. ;;; Copyright (c) University of Massachusetts 1988
  8. ;;;------------------------------------------------------------------------
  9.  
  10. (in-package "ISR2")
  11.  
  12. (export '(make-tss make-null-tss make-null-tss! token-count make-tss-extents 
  13.       tss-extents-minrow tss-extents-mincol tss-extents-maxrow tss-extents-maxcol
  14.       tss-extents tss-extents-p copy-tss-extents make-range range-min range-max 
  15.       range-feature range-circular-p range range-p copy-range make-predicate
  16.       predicate-function predicate-features predicate predicate-p copy-predicate
  17.       tss-intersection tss-intersection! tss-union tss-union! tss-set-difference
  18.       tss-set-difference! tss-sort tss-sort-key sort-update! tss-mem pick pick-reset!
  19.       for-every-token for-every-token! for-every-feature! add-tokens add-tokens!
  20.       remove-tokens remove-tokens! optimize-tss-storage add-token add-token! 
  21.       remove-token remove-token! pick pick-reset! compress tss-make-sort
  22.       tss-sort-by-predicate))
  23.  
  24. (defun tss-index-memq (index tss-existence-vector)
  25.   (cond ((typep tss-existence-vector '2index-vector-vector)
  26.      (= (vvref tss-existence-vector index) 1))
  27.     (t (not (null (member index tss-existence-vector))))))
  28.  
  29. (defun make-tss (path &aux parsed-path handle more-parsed-path)
  30.   "Make a new TSS from path."
  31.   (setf parsed-path (parse-token-name path))
  32.   (multiple-value-setq (handle more-parsed-path)
  33.     (make-handle-from-parsed-path parsed-path))
  34.   (unless (and handle
  35.            (check-terminal-path handle more-parsed-path)
  36.            (member (handle-type handle) '(:frame :token-subset
  37.                              :token-sort))
  38.            (null more-parsed-path))
  39.     (error "~S is not a legitimate path!" path))
  40.   (make-handle :type :token-subset
  41.            :frame (handle-frame handle)
  42.            :token-existence-array
  43.            (cond ((eq (handle-type handle) :frame)
  44.               (deep-copy-evv (frame-token-set-globalp-vector
  45.                        (handle-frame handle))))
  46.              ((eq (handle-type handle) :token-sort)
  47.               (let ((new-evv (deep-copy-evv (handle-token-existence-array
  48.                               handle))))
  49.                (when (listp new-evv)
  50.                  (setf new-evv (sort new-evv #'<)))
  51.                new-evv))
  52.              (t (deep-copy-evv (handle-token-existence-array
  53.                      handle)))))
  54.   )
  55.  
  56. (defun make-null-tss (path &aux parsed-path handle more-parsed-path)
  57.   "Make a new TSS from path."
  58.   (setf parsed-path (parse-token-name path))
  59.   (multiple-value-setq (handle more-parsed-path)
  60.     (make-handle-from-parsed-path parsed-path))
  61.   (unless (and handle
  62.            (check-terminal-path handle more-parsed-path)
  63.            (member (handle-type handle) '(:frame :token-subset
  64.                              :token-sort))
  65.            (null more-parsed-path))
  66.     (error "~S is not a legitimate path!" path))
  67.   (make-handle :type :token-subset
  68.            :frame (handle-frame handle)
  69.            :token-existence-array nil)
  70.   )
  71.  
  72. (defun deep-copy-evv (e-vector)
  73.   (cond ((typep e-vector '2index-vector-vector)
  74.      (deep-copy-evv-2vv-optimize e-vector))
  75.     (t (deep-copy-evv-tis-optimize e-vector)))
  76.   )
  77.  
  78.  ;; when a 2vv is < 30% used, convert to a list
  79. (defconstant 2VV-TO-TIS-OPT-RATIO 0.3)
  80.  ;; when a list (if converted to a 2vv) would be > 80% used, convert it to a 2vv
  81. (defconstant TIS-TO-2VV-OPT-RATIO 0.8)
  82.  
  83. (defun active-token-count-2vv (2vv)
  84.   "This function returns the number of active tokens."
  85.   (let ((count 0))
  86.     (do-active-tokens (tokindex 2vv)
  87.       (incf count))
  88.     count))
  89.  
  90.  
  91. (#-(or :allegro :lispworks) defsubst #+(or :allegro :lispworks) defun total-token-count-2vv (2vv)
  92.   "This function retuns the total count of tokens."
  93.   (* (fill-pointer (2index-vector-vector-data 2vv))
  94.      *default-2index-vector-size*)
  95.   )
  96.  
  97. (defun compute-2VV-use-ratio (2vv)
  98.   (let ((number-of-active-tokens (active-token-count-2vv 2vv))
  99.     (allocated-token-count (* *default-2index-vector-size*
  100.                   (2vv-used-block-count 2vv)))
  101.     )
  102.        (if (> number-of-active-tokens 0)
  103.        (/ (float number-of-active-tokens)
  104.           (float allocated-token-count))
  105.        0.0)
  106.        )
  107.   )
  108.  
  109. (defun compute-tis-use-ratio (tis)
  110.   (if (null tis) 
  111.       0.0
  112.       (let ((number-of-active-tokens (length tis))
  113.         (allocated-token-count (figure-allocation tis))
  114.         )
  115.        (/ (float number-of-active-tokens)
  116.           (float allocated-token-count))       
  117.        )
  118.       )
  119.   )
  120.  
  121. (defun 2vv-used-block-count (2vv)
  122.   (let* ((outer-vector (2index-vector-vector-data 2vv))
  123.      (ov-size (fill-pointer outer-vector))
  124.      (count 0))
  125.     (dotimes (ov ov-size)
  126.        (when (aref outer-vector ov)
  127.          (incf count)))
  128.     count)
  129.   )
  130.  
  131. (defun figure-allocation (tis &aux (min (reduce #'min tis))
  132.                   (max (reduce #'max tis)))
  133.   (do ((count 0)
  134.        (istart (truncate min *default-2index-vector-size*)
  135.            (1+ istart)))
  136.       ((> istart (truncate (+ max *default-2index-vector-size*)
  137.                *default-2index-vector-size*))
  138.        (* count *default-2index-vector-size*))
  139.       (when (some #'(lambda (tindx)
  140.                 (and (>= tindx (* istart *default-2index-vector-size*)
  141.                      )
  142.                  (< tindx (* (1+ istart)
  143.                          *default-2index-vector-size*)
  144.                     )))
  145.           tis)
  146.     (incf count)))
  147.   )
  148.  
  149.  
  150. (defun deep-copy-evv-2vv-optimize (2vv)
  151.   (let ((2vv-use-ratio (compute-2VV-use-ratio 2vv)))
  152.        (if (< 2vv-use-ratio 2VV-TO-TIS-OPT-RATIO)
  153.        (let* ((result (make-list (active-token-count-2vv 2vv)))
  154.           (p result))
  155.          (do-active-tokens (token-index 2vv)
  156.             (setf (first p) token-index
  157.                p        (rest p)))
  158.          result)
  159.        (let* ((new-tok-exist (make-2index-vector-vector 0))
  160.           (old-outer-vector (2index-vector-vector-data 2vv))
  161.           (new-outer-vector (2index-vector-vector-data 
  162.                       new-tok-exist))
  163.           (old-fill-pointer (fill-pointer old-outer-vector))
  164.           old-inner-vector old-iv
  165.           new-inner-vector new-iv
  166.           )
  167.          (dotimes (ov old-fill-pointer)
  168.            (vector-push-extend nil new-outer-vector)
  169.            (when (setf old-inner-vector
  170.                    (aref old-outer-vector ov))
  171.              (setf new-inner-vector
  172.                (allocate-resource
  173.                  '2index-bin-vector
  174.                  (* ov *default-2index-vector-size*))
  175.                new-iv (2index-vector-data-vector new-inner-vector)
  176.                old-iv (2index-vector-data-vector old-inner-vector)
  177.                (aref new-outer-vector ov) new-inner-vector
  178.                )
  179.              (dotimes (iv *default-2index-vector-size*)
  180.             (setf (aref new-iv iv)
  181.                   (aref old-iv iv)))
  182.              )
  183.            )
  184.          new-tok-exist)
  185.        )
  186.        )
  187.   )
  188.  
  189.  
  190. (defun deep-copy-evv-tis-optimize (tis)
  191.   (let ((tis-use-ratio (compute-tis-use-ratio tis)))
  192.        (if (> tis-use-ratio TIS-TO-2VV-OPT-RATIO)
  193.        (let ((new-tok-exist (make-2index-vector-vector 0)))
  194.         (map nil #'(lambda (iv)
  195.                   (setf (vvref new-tok-exist iv) 1))
  196.              tis)
  197.         new-tok-exist)
  198.        (copy-seq tis))))
  199.  
  200. (defun make-null-tss! (tss)
  201.   "MAKE-NULL-TSS! tss - release storage used by tss.  Tss *must* be a tss-handle.
  202. This function is only meaningful iff tss's existence vector is a 2index
  203. bit-vector. "
  204.   (unless (and (handle-p tss)
  205.            (eq (handle-type tss) :token-subset))
  206.     (error "~S is not a TSS handle!" tss))
  207.   (let ((evv (handle-token-existence-array tss)))
  208.        (if (typep evv '2index-vector-vector)
  209.      (with-lock ((2index-vector-vector-lock evv))
  210.        (let* ((outer-vect (2index-vector-vector-data evv))
  211.           (ov-size (fill-pointer outer-vect))
  212.           ivect)
  213.          (dotimes (ov ov-size)
  214.             (setf ivect (aref outer-vect ov))
  215.             (when ivect
  216.               (deallocate-resource
  217.             (type-of ivect) ivect)
  218.               (setf (aref outer-vect ov) nil)
  219.               ))
  220.          (setf (fill-pointer outer-vect) 0)
  221.          )
  222.        (setf (handle-token-existence-array tss) nil))
  223.      (setf (handle-token-existence-array tss) nil))
  224.        )
  225.   tss
  226.   )
  227.  
  228. (defun token-count (frame-or-tss &aux parsed-path handle more-parsed-path)
  229.   "TOKEN-COUNT frame-or-tss - Returns the number of active tokens in the 
  230. frame or TSS."
  231.   (setf parsed-path (parse-token-name frame-or-tss))
  232.   (multiple-value-setq (handle more-parsed-path)
  233.     (make-handle-from-parsed-path parsed-path))
  234.   (unless (and handle
  235.            (check-terminal-path handle more-parsed-path)
  236.            (member (handle-type handle) '(:frame :token-subset
  237.                              :token-sort))
  238.            (null more-parsed-path))
  239.     (error "~S is not a legitimate path!" frame-or-tss))
  240.   (if (eq (handle-type handle) :frame)
  241.       (active-token-count-2vv (frame-token-set-globalp-vector
  242.                 (handle-frame handle)))
  243.       (let ((evv (handle-token-existence-array
  244.            handle)))
  245.        (if (typep evv '2index-vector-vector)
  246.            (active-token-count-2vv evv)
  247.            (length evv))))
  248.   )
  249.  
  250. (defun optimize-tss-storage (tss &aux new-tss)
  251.   "OPTIMIZE-TSS-STORAGE tss - optimize TSS's storage.  Does a MAKE-TSS on
  252. tss and then frees the old tss and returns the new (copied) one."
  253.   (setf new-tss (make-tss tss))
  254.   (make-null-tss! tss)
  255.   new-tss)
  256.  
  257. (defun tss-intersection (path set-description &KEY (if-uncalculated nil)
  258.              (if-getting nil) (if-undefined nil))
  259.   "TSS-INTERSECTION path set-description &KEY (:if-uncalculated nil)
  260.              (:if-getting nil) (:if-undefined nil) -
  261. Compute the intersection of the TSS described by path and the TSS described 
  262. by set-description.  If-uncalculated specifies what to do if a feature is
  263. uncalculated (nil - skip, T - use, :calculate or :compute compute the
  264. feature (i.e. call the :if-needed function(s))).  If-undefined specifies
  265. what to do if the feature is undefined (nil - skip, T - use, :calculate or 
  266. :compute - error).  If-getting specifies whether to call the :if-getting
  267. function for a feature.  Set-description is one of
  268.   A] A TSS or frame,
  269.   B] A tss-extents structure (see documentation for isr2::make-tss-extents),
  270.   C] A range structure (see documentation for isr2::make-range), or
  271.   D] A predicate structure (see documentation for isr2::make-predicate)."
  272.   (tss-intersection! (make-tss path) set-description :if-uncalculated 
  273.              if-uncalculated :if-getting if-getting :if-undefined
  274.              if-undefined))
  275.  
  276. (defun tss-union (path set-description &KEY (if-uncalculated nil)
  277.              (if-getting nil) (if-undefined nil))
  278.   "TSS-UNION path set-description &KEY (:if-uncalculated nil)
  279.              (:if-getting nil) (:if-undefined nil) -
  280. Compute the union of the TSS described by path and the TSS described 
  281. by set-description.  If-uncalculated specifies what to do if a feature is
  282. uncalculated (nil - skip, T - use, :calculate or :compute compute the
  283. feature (i.e. call the :if-needed function(s)).  If-undefined specifies
  284. what to do if the feature is undefined (nil - skip, T - use, :calculate or 
  285. :compute - error).  If-getting specifies whether to call the :if-getting
  286. function for a feature.  Set-description is one of
  287.   A] A TSS or frame,
  288.   B] A tss-extents structure (see documentation for isr2::make-tss-extents),
  289.   C] A range structure (see documentation for isr2::make-range), or
  290.   D] A predicate structure (see documentation for isr2::make-predicate)."
  291.   (tss-union! (make-tss path) set-description :if-uncalculated 
  292.           if-uncalculated :if-getting if-getting :if-undefined
  293.           if-undefined))
  294.  
  295. (defun tss-difference (path set-description &KEY (if-uncalculated nil)
  296.              (if-getting nil) (if-undefined nil))
  297.   "TSS-DIFFERENCE path set-description &KEY (:if-uncalculated nil)
  298.              (:if-getting nil) (:if-undefined nil) -
  299. Compute the set difference of the TSS described by path and the TSS described 
  300. by set-description.  If-uncalculated specifies what to do if a feature is
  301. uncalculated (nil - skip, T - use, :calculate or :compute compute the
  302. feature (i.e. call the :if-needed function(s)).  If-undefined specifies
  303. what to do if the feature is undefined (nil - skip, T - use, :calculate or 
  304. :compute - error).  If-getting specifies whether to call the :if-getting
  305. function for a feature.  Set-description is one of
  306.   A] A TSS or frame,
  307.   B] A tss-extents structure (see documentation for isr2::make-tss-extents),
  308.   C] A range structure (see documentation for isr2::make-range), or
  309.   D] A predicate structure (see documentation for isr2::make-predicate)."
  310.   (tss-difference! (make-tss path) set-description :if-uncalculated 
  311.            if-uncalculated :if-getting if-getting :if-undefined
  312.            if-undefined))
  313.  
  314. (defstruct tss-extents 
  315.        (minrow 0 :type integer)
  316.        (mincol 0 :type integer)
  317.        (maxrow 0 :type integer)
  318.        (maxcol 0 :type integer)
  319.        )
  320.  
  321. (setf (documentation 'make-tss-extents 'function)
  322.       "MAKE-TSS-EXTENTS &KEY (minrow 0) (mincol 0) (maxrow 0) (maxcol 0) -
  323. Make a TSS-Extents structure.  Used in the various TSS-xxx functions to
  324. choose tokens within a specific spacial range.")
  325.  
  326. (defstruct range 
  327.        (min 0 :type number)
  328.        (max 0 :type number)
  329.        (feature "" :type string)
  330.        (circular-p nil)
  331.        )
  332.  
  333. (setf (documentation 'make-range 'function)
  334.       "MAKE-RANGE &KEY (min 0) (max 0) (feature \"\") (circular-p nil) -
  335. Make a Range stucture.  Used in the various TSS-xxx functions to choose
  336. tokens with a feature values in a selected range.  Circluar-p is used
  337. to indicate a circular feature or to select a complementary range.")
  338.  
  339. (defstruct predicate
  340.        (function #'(lambda (&rest ignore) (declare (ignore ignore)) nil))
  341.        (features nil :type list))
  342.  
  343. (setf (documentation 'make-predicate 'function)
  344.       "MAKE-PREDICATE &KEY (function #'(lambda (frame token-index &rest featurevalues)
  345.                                         &body code))
  346.                     (features nil) -
  347. Make a Predicate structure.  Used in the various TSS-xxx functions to choose
  348. tokens based on some predicate computed over zero or more feature values.")
  349.  
  350.  
  351. (defun tss-intersection! (tss set-description &KEY (if-uncalculated nil)
  352.               (if-getting nil) (if-undefined nil))
  353.   "TSS-INTERSECTION! tss set-description &KEY (:if-uncalculated nil)
  354.              (:if-getting nil) (:if-undefined nil) -
  355. Compute the intersection of the TSS described by tss and the TSS described 
  356. by set-description.  This function *destructively* modifies its first argument.
  357. If-uncalculated specifies what to do if a feature is uncalculated (nil - skip,
  358. T - use, :calculate or :compute compute the feature (i.e. call the :if-needed
  359. function(s)).  If-undefined specifies what to do if the feature is undefined
  360. (nil - skip, T - use, :calculate or :compute - error).  If-getting specifies
  361. whether to call the :if-getting function for a feature.  Set-description is one of
  362.   A] A TSS or frame,
  363.   B] A tss-extents structure (see documentation for isr2::make-tss-extents),
  364.   C] A range structure (see documentation for isr2::make-range), or
  365.   D] A predicate structure (see documentation for isr2::make-predicate)."
  366.   (unless (and (handle-p tss)
  367.            (eq (handle-type tss) :token-subset))
  368.     (error "Argument must be a TSS: ~S" tss))
  369.   (cond ((typep set-description 'range)
  370.      (let ((min (range-min set-description))
  371.            (max (range-max set-description))
  372.            (circ-p (range-circular-p set-description)))
  373.           (tss-intersection!-by-predicate
  374.         tss
  375.         (if (and circ-p (<= max min))
  376.             #'(lambda (ignore1 ignore2 feature-value)
  377.                   (declare (ignore ignore1 ignore2))
  378.                   (or (<= feature-value max)
  379.                   (>= feature-value min)))
  380.             #'(lambda (ignore1 ignore2 feature-value)
  381.                   (declare (ignore ignore1 ignore2))
  382.                   (and (>= feature-value min)
  383.                    (<= feature-value max)))
  384.             )
  385.         (list (range-feature set-description))
  386.         if-uncalculated
  387.             if-undefined
  388.             if-getting)))
  389.     ((typep set-description 'tss-extents)
  390.      (let ((mincol (tss-extents-mincol set-description))
  391.            (minrow (tss-extents-minrow set-description))
  392.            (maxcol (tss-extents-maxcol set-description))
  393.            (maxrow (tss-extents-maxrow set-description))
  394.            )
  395.           (tss-intersection!-by-predicate
  396.         tss
  397.         #'(lambda (ignore1 ignore2 extents)
  398.             (declare (ignore ignore1 ignore2))
  399.                     (and
  400.                       (or (<= (minx-of extents) mincol (maxx-of extents))
  401.                           (<= (minx-of extents) maxcol (maxx-of extents))
  402.                           (<= mincol (minx-of extents) maxcol))
  403.                       (or (<= (miny-of extents) minrow (maxy-of extents))
  404.                           (<= (miny-of extents) maxrow (maxy-of extents))
  405.                           (<= minrow (miny-of extents) maxrow))))
  406.         (list "extents")
  407.         if-uncalculated
  408.             if-undefined
  409.             if-getting)))
  410.     ((typep set-description 'predicate)
  411.      (tss-intersection!-by-predicate
  412.        tss
  413.        (predicate-function set-description)
  414.        (predicate-features set-description)
  415.        if-uncalculated
  416.        if-undefined
  417.        if-getting))
  418.         ;; If we get this far, the second argument must be a TSS or a frame!
  419.     ;; now we must worry about the different TSS storage formats.
  420.     ((and (typep (handle-token-existence-array tss) '2index-vector-vector)
  421.           (typep set-description 'handle)
  422.           (eq (handle-type set-description) :frame))
  423.      (bitblt-2index-vectors! (handle-token-existence-array tss)
  424.                  (frame-token-set-globalp-vector 
  425.                    (handle-frame set-description))
  426.                  :alu-function #-:EXPLORER :and #+:EXPLORER tv::alu-and))
  427.     ((and (typep (handle-token-existence-array tss) 'list)
  428.           (typep set-description 'handle)
  429.           (eq (handle-type set-description) :frame))
  430.      (do* ((evv (frame-token-set-globalp-vector
  431.               (handle-frame set-description)))
  432.            (result (cons nil (handle-token-existence-array tss)))
  433.            (ptr result))
  434.           ((null (rest ptr))(setf (handle-token-existence-array tss) (rest result)))
  435.           (if (= (vvref evv (second ptr)) 0)
  436.           (setf (rest ptr) (rest (rest ptr)))
  437.           (setf ptr (rest ptr)))
  438.           ))
  439.     ((or (not (typep set-description 'handle))
  440.          (not (member (handle-type set-description) '(:token-subset :token-sort))))
  441.      (error "Not a set description: ~S!" set-description))
  442.     ((and (typep (handle-token-existence-array tss) '2index-vector-vector)
  443.           (typep (handle-token-existence-array set-description) 
  444.              '2index-vector-vector))
  445.      (bitblt-2index-vectors! (handle-token-existence-array tss)
  446.                  (handle-token-existence-array set-description)
  447.                  :alu-function #-:EXPLORER :and #+:EXPLORER tv::alu-and))
  448.     ((and (typep (handle-token-existence-array tss) '2index-vector-vector)
  449.           (typep (handle-token-existence-array set-description) 'list))
  450.      (do* ((evv (handle-token-existence-array tss))
  451.            (result (cons nil (copy-list
  452.                    (handle-token-existence-array set-description))))
  453.            (ptr result))
  454.           ((null (rest ptr))
  455.            (make-null-tss! tss)
  456.            (setf (handle-token-existence-array tss) (rest result)))
  457.           (if (= (vvref evv (second ptr)) 0)
  458.           (setf (rest ptr) (rest (rest ptr)))
  459.           (setf ptr (rest ptr)))
  460.           )
  461.      )
  462.     ((and (typep (handle-token-existence-array tss) 'list)
  463.           (typep (handle-token-existence-array set-description)
  464.              '2index-vector-vector))
  465.      (do* ((evv (handle-token-existence-array set-description))
  466.            (result (cons nil (handle-token-existence-array tss)))
  467.            (ptr result))
  468.           ((null (rest ptr))(setf (handle-token-existence-array tss) (rest result)))
  469.           (if (= (vvref evv (second ptr)) 0)
  470.           (setf (rest ptr) (rest (rest ptr)))
  471.           (setf ptr (rest ptr)))
  472.           ))
  473.     ((and (typep (handle-token-existence-array tss) 'list)
  474.           (typep (handle-token-existence-array set-description) 'list))
  475.      (setf (handle-token-existence-array tss)
  476.            (nintersection (handle-token-existence-array tss) 
  477.                (handle-token-existence-array set-description))))
  478.     (t (error "(internal error) Attempt to intersect unknown types: ~S and ~S" 
  479.           tss set-description)))
  480.   tss)
  481.  
  482. (defun tss-union! (tss set-description &KEY (if-uncalculated nil)
  483.               (if-getting nil) (if-undefined nil))
  484.   "TSS-UNION! tss set-description &KEY (:if-uncalculated nil)
  485.              (:if-getting nil) (:if-undefined nil) -
  486. Compute the union of the TSS described by tss and the TSS described 
  487. by set-description.  This function *destructively* modifies its first argument.
  488. If-uncalculated specifies what to do if a feature is uncalculated (nil - skip,
  489. T - use, :calculate or :compute compute the feature (i.e. call the :if-needed
  490. function(s)).  If-undefined specifies what to do if the feature is undefined
  491. (nil - skip, T - use, :calculate or :compute - error).  If-getting specifies
  492. whether to call the :if-getting function for a feature.  Set-description is one of
  493.   A] A TSS or frame,
  494.   B] A tss-extents structure (see documentation for isr2::make-tss-extents),
  495.   C] A range structure (see documentation for isr2::make-range), or
  496.   D] A predicate structure (see documentation for isr2::make-predicate)."
  497.   (unless (and (handle-p tss)
  498.            (eq (handle-type tss) :token-subset))
  499.     (error "Argument must be a TSS: ~S" tss))
  500.   (cond ((typep set-description 'range)
  501.      (let ((min (range-min set-description))
  502.            (max (range-max set-description))
  503.            (circ-p (range-circular-p set-description))
  504.            )
  505.           (tss-union!-by-predicate
  506.         tss
  507.         (if (and circ-p (<= max min))
  508.             #'(lambda (ignore1 ignore2 feature-value)
  509.                   (declare (ignore ignore1 ignore2))
  510.                   (or (<= feature-value max)
  511.                   (>= feature-value min)))
  512.             #'(lambda (ignore1 ignore2 feature-value)
  513.                   (declare (ignore ignore1 ignore2))
  514.                   (and (>= feature-value min)
  515.                    (<= feature-value max)))
  516.             )
  517.         (list (range-feature set-description))
  518.         if-uncalculated
  519.             if-undefined
  520.             if-getting)))
  521.     ((typep set-description 'tss-extents)
  522.      (let ((mincol (tss-extents-mincol set-description))
  523.            (minrow (tss-extents-minrow set-description))
  524.            (maxcol (tss-extents-maxcol set-description))
  525.            (maxrow (tss-extents-maxrow set-description))
  526.            )
  527.           (tss-union!-by-predicate
  528.         tss
  529.         #'(lambda (ignore1 ignore2 extents)
  530.             (declare (ignore ignore1 ignore2))
  531.                     (and
  532.                       (or (<= (minx-of extents) mincol (maxx-of extents))
  533.                           (<= (minx-of extents) maxcol (maxx-of extents))
  534.                           (<= mincol (minx-of extents) maxcol))
  535.                       (or (<= (miny-of extents) minrow (maxy-of extents))
  536.                           (<= (miny-of extents) maxrow (maxy-of extents))
  537.                           (<= minrow (miny-of extents) maxrow))))
  538.         (list "extents")
  539.         if-uncalculated
  540.             if-undefined
  541.             if-getting)))
  542.     ((typep set-description 'predicate)
  543.      (tss-union!-by-predicate
  544.        tss
  545.        (predicate-function set-description)
  546.        (predicate-features set-description)
  547.        if-uncalculated
  548.        if-undefined
  549.        if-getting))
  550.         ;; If we get this far, the second argument must be a TSS or a frame!
  551.     ;; now we must worry about the different TSS storage formats.
  552.     ((and (typep (handle-token-existence-array tss) '2index-vector-vector)
  553.           (typep set-description 'handle)
  554.           (eq (handle-type set-description) :frame))
  555.      (bitblt-2index-vectors! (handle-token-existence-array tss)
  556.                  (frame-token-set-globalp-vector 
  557.                    (handle-frame set-description))
  558.                  :alu-function #-:EXPLORER :ior #+:EXPLORER tv::alu-ior))
  559.     ((and (typep (handle-token-existence-array tss) 'list)
  560.           (typep set-description 'handle)
  561.           (eq (handle-type set-description) :frame))
  562.      (let ((old-tss-existence-list (handle-token-existence-array tss)))
  563.        (setf (handle-token-existence-array tss)
  564.          (deep-copy-evv-2vv-nooptimize (frame-token-set-globalp-vector
  565.                          (handle-frame set-description))))
  566.        (dolist (val old-tss-existence-list)
  567.          (setf (vvref (handle-token-existence-array tss) val) 1))))
  568.     ((or (not (typep set-description 'handle))
  569.          (not (member (handle-type set-description) '(:token-subset :token-sort))))
  570.      (error "Not a set description: ~S!" set-description))
  571.     ((and (typep (handle-token-existence-array tss) '2index-vector-vector)
  572.           (typep (handle-token-existence-array set-description) 
  573.              '2index-vector-vector))
  574.      (bitblt-2index-vectors! (handle-token-existence-array tss)
  575.                  (handle-token-existence-array set-description)
  576.                  :alu-function #-:EXPLORER :ior #+:EXPLORER tv::alu-ior))
  577.     ((and (typep (handle-token-existence-array tss) '2index-vector-vector)
  578.           (typep (handle-token-existence-array set-description) 'list))
  579.      (dolist (val (handle-token-existence-array set-description))
  580.        (setf (vvref (handle-token-existence-array tss) val) 1)))
  581.     ((and (typep (handle-token-existence-array tss) 'list)
  582.           (typep (handle-token-existence-array set-description)
  583.              '2index-vector-vector))
  584.      (let ((old-tss-existence-list (handle-token-existence-array tss)))
  585.        (setf (handle-token-existence-array tss)
  586.          (deep-copy-evv-2vv-nooptimize (handle-token-existence-array 
  587.                          set-description)))
  588.        (dolist (val old-tss-existence-list)
  589.          (setf (vvref (handle-token-existence-array tss) val) 1))))
  590.     ((and (typep (handle-token-existence-array tss) 'list)
  591.           (typep (handle-token-existence-array set-description) 'list))
  592.      (setf (handle-token-existence-array tss)
  593.            (n-ordered-union (handle-token-existence-array tss) 
  594.                 (handle-token-existence-array set-description))))
  595.     (t (error "(internal error) Attempt to union unknown types: ~S and ~S" 
  596.           tss set-description)))
  597.   tss)
  598.  
  599. (defun n-ordered-union (oset set)
  600.   (dolist (elt set)
  601.      (setf oset (ordered-insert! elt oset)))
  602.   oset)
  603.  
  604.  
  605. (defun tss-difference! (tss set-description &KEY (if-uncalculated nil)
  606.               (if-getting nil) (if-undefined nil))
  607.   "TSS-DIFFERENCE! tss set-description &KEY (:if-uncalculated nil)
  608.              (:if-getting nil) (:if-undefined nil) -
  609. Compute the difference of the TSS described by tss and the TSS described 
  610. by set-description.  This function *destructively* modifies its first argument.
  611. If-uncalculated specifies what to do if a feature is uncalculated (nil - skip,
  612. T - use, :calculate or :compute compute the feature (i.e. call the :if-needed
  613. function(s)).  If-undefined specifies what to do if the feature is undefined
  614. (nil - skip, T - use, :calculate or :compute - error).  If-getting specifies
  615. whether to call the :if-getting function for a feature.  Set-description is one of
  616.   A] A TSS or frame,
  617.   B] A tss-extents structure (see documentation for isr2::make-tss-extents),
  618.   C] A range structure (see documentation for isr2::make-range), or
  619.   D] A predicate structure (see documentation for isr2::make-predicate)."
  620.   (unless (and (handle-p tss)
  621.            (eq (handle-type tss) :token-subset))
  622.     (error "Argument must be a TSS: ~S" tss))
  623.   (cond ((typep set-description 'range)
  624.      (let ((min (range-min set-description))
  625.            (max (range-max set-description))
  626.            (circ-p (range-circular-p set-description))
  627.            )
  628.           (tss-difference!-by-predicate
  629.         tss
  630.         (if (and circ-p (<= max min))
  631.             #'(lambda (ignore1 ignore2 feature-value)
  632.                   (declare (ignore ignore1 ignore2))
  633.                   (or (<= feature-value max)
  634.                   (>= feature-value min)))
  635.             #'(lambda (ignore1 ignore2 feature-value)
  636.                   (declare (ignore ignore1 ignore2))
  637.                   (and (>= feature-value min)
  638.                    (<= feature-value max)))
  639.             )
  640.         (list (range-feature set-description))
  641.         if-uncalculated
  642.             if-undefined
  643.             if-getting)))
  644.     ((typep set-description 'tss-extents)
  645.      (let ((mincol (tss-extents-mincol set-description))
  646.            (minrow (tss-extents-minrow set-description))
  647.            (maxcol (tss-extents-maxcol set-description))
  648.            (maxrow (tss-extents-maxrow set-description))
  649.            )
  650.           (tss-difference!-by-predicate
  651.         tss
  652.         #'(lambda (ignore1 ignore2 extents)
  653.             (declare (ignore ignore1 ignore2))
  654.                     (and
  655.                       (or (<= (minx-of extents) mincol (maxx-of extents))
  656.                           (<= (minx-of extents) maxcol (maxx-of extents))
  657.                           (<= mincol (minx-of extents) maxcol))
  658.                       (or (<= (miny-of extents) minrow (maxy-of extents))
  659.                           (<= (miny-of extents) maxrow (maxy-of extents))
  660.                           (<= minrow (miny-of extents) maxrow))))
  661.         (list "extents")
  662.         if-uncalculated
  663.             if-undefined
  664.             if-getting)))
  665.     ((typep set-description 'predicate)
  666.      (tss-difference!-by-predicate
  667.        tss
  668.        (predicate-function set-description)
  669.        (predicate-features set-description)
  670.        if-uncalculated
  671.        if-undefined
  672.        if-getting))
  673.         ;; If we get this far, the second argument must be a TSS or a frame!
  674.     ;; now we must worry about the different TSS storage formats.
  675.     ((and (typep (handle-token-existence-array tss) '2index-vector-vector)
  676.           (typep set-description 'handle)
  677.           (eq (handle-type set-description) :frame))
  678.      (bitblt-2index-vectors! (handle-token-existence-array tss)
  679.                  (frame-token-set-globalp-vector 
  680.                    (handle-frame set-description))
  681.                  :alu-function #-:EXPLORER :andc1 #+:EXPLORER tv::alu-andca))
  682.     ((and (typep (handle-token-existence-array tss) 'list)
  683.           (typep set-description 'handle)
  684.           (eq (handle-type set-description) :frame))
  685.      (do* ((evv (frame-token-set-globalp-vector
  686.               (handle-frame set-description)))
  687.            (result (cons nil (handle-token-existence-array tss)))
  688.            (ptr result))
  689.           ((null (rest ptr)) (setf (handle-token-existence-array tss) (rest result)))
  690.           (if (= (vvref evv (second ptr)) 1)
  691.           (setf (rest ptr) (rest (rest ptr)))
  692.           (setf ptr (rest ptr)))))
  693.     ((or (not (typep set-description 'handle))
  694.          (not (member (handle-type set-description) '(:token-subset :token-sort))))
  695.      (error "Not a set description: ~S!" set-description))
  696.     ((and (typep (handle-token-existence-array tss) '2index-vector-vector)
  697.           (typep (handle-token-existence-array set-description) 
  698.              '2index-vector-vector))
  699.      (bitblt-2index-vectors! (handle-token-existence-array tss)
  700.                  (handle-token-existence-array set-description)
  701.                  :alu-function #-:EXPLORER :andc1 #+:EXPLORER tv::alu-andca))
  702.     ((and (typep (handle-token-existence-array tss) '2index-vector-vector)
  703.           (typep (handle-token-existence-array set-description) 'list))
  704.      (dolist (val (handle-token-existence-array set-description))
  705.        (setf (vvref (handle-token-existence-array tss) val) 0)))
  706.     ((and (typep (handle-token-existence-array tss) 'list)
  707.           (typep (handle-token-existence-array set-description)
  708.              '2index-vector-vector))
  709.      (do* ((evv (handle-token-existence-array set-description))
  710.            (result (cons nil (handle-token-existence-array tss)))
  711.            (ptr result))
  712.           ((null (rest ptr)) (setf (handle-token-existence-array tss) (rest result)))
  713.           (if (= (vvref evv (second ptr)) 1)
  714.           (setf (rest ptr) (rest (rest ptr)))
  715.           (setf ptr (rest ptr)))))
  716.     ((and (typep (handle-token-existence-array tss) 'list)
  717.           (typep (handle-token-existence-array set-description) 'list))
  718.      (setf (handle-token-existence-array tss)
  719.            (nset-difference (handle-token-existence-array tss) 
  720.                 (handle-token-existence-array set-description))))
  721.     (t (error "(internal error) Attempt to set-difference unknown types: ~S and ~S" 
  722.           tss set-description)))
  723.   tss)
  724.  
  725. (defun bitblt-2index-vectors! (2index-vector-1 2index-vector-2
  726.                    &key (alu-function #-:EXPLORER :iot #+:EXPLORER tv::alu-ior))
  727.   "Bitblt two 2index-vectors together. ALU-FUNCTION must be one of: tv:alu-ior [union], 
  728.     tv:alu-and [intersection] or tv:alu-andca [set-difference]." 
  729.   (let* ((top-data-1 (2index-vector-vector-data 2index-vector-1))
  730.      (top-data-2 (2index-vector-vector-data 2index-vector-2))
  731.      ;; array length is a function of the fill pointers, not length of the
  732.      ;; main struct!
  733.      (top-level-length (max (fill-pointer top-data-1) (fill-pointer top-data-2))))
  734.     (dotimes (ptr top-level-length)
  735.       (cond ((and (aref top-data-1 ptr)
  736.           (aref top-data-2 ptr))
  737.          (let ((overlay-1 (make-array `(1 ,*default-2index-vector-size*) 
  738.                       :element-type 'bit
  739.                       :displaced-to (2index-bin-vector-data-vector  
  740.                               (aref top-data-1 ptr))))
  741.            (overlay-2 (make-array `(1 ,*default-2index-vector-size*) 
  742.                       :element-type 'bit
  743.                       :displaced-to (2index-bin-vector-data-vector
  744.                               (aref top-data-2 ptr)))))
  745.            (bitblt alu-function *default-2index-vector-size* 1 
  746.                overlay-2 0 0
  747.                overlay-1 0 0)))
  748.         ((and (not (aref top-data-1 ptr))
  749.           (= alu-function #-:EXPLORER :ior #+:EXPLORER tv::alu-ior))
  750.          (setf (aref top-data-1 ptr)
  751.            (copy-seq (aref top-data-2 ptr))))
  752.         ((and (not (aref top-data-2 ptr))
  753.           (= alu-function #-:EXPLORER :and #+:EXPLORER tv::alu-and))
  754.          (setf (aref top-data-1 ptr) nil))
  755.         (t nil)))))
  756.  
  757.  
  758. (defun deep-copy-evv-2vv-nooptimize (2vv)
  759.   (let* ((new-tok-exist (make-2index-vector-vector 0))
  760.      (old-outer-vector (2index-vector-vector-data 2vv))
  761.      (new-outer-vector (2index-vector-vector-data 
  762.                  new-tok-exist))
  763.      (old-fill-pointer (fill-pointer old-outer-vector))
  764.      old-inner-vector old-iv
  765.      new-inner-vector new-iv
  766.      )
  767.     (dotimes (ov old-fill-pointer)
  768.       (vector-push-extend nil new-outer-vector)
  769.       (when (setf old-inner-vector
  770.           (aref old-outer-vector ov))
  771.     (setf new-inner-vector
  772.           (allocate-resource
  773.         '2index-bin-vector
  774.         (* ov *default-2index-vector-size*))
  775.           new-iv (2index-vector-data-vector new-inner-vector)
  776.           old-iv (2index-vector-data-vector old-inner-vector)
  777.           (aref new-outer-vector ov) new-inner-vector
  778.           )
  779.     (dotimes (iv *default-2index-vector-size*)
  780.       (setf (aref new-iv iv)
  781.         (aref old-iv iv)))
  782.     )
  783.       )
  784.     new-tok-exist))
  785.  
  786.  
  787. (defun tss-intersection!-by-predicate (tss function features if-calc if-undef
  788.                        if-get)
  789.   (setf features (mapcar #'string-upcase features))
  790.   (let ((frame-handle (make-handle :type :frame :frame (handle-frame tss)))
  791.     (fhandles (mapcar #'(lambda (feat) (handle (list (frame tss) "<?>" feat)))
  792.               features))
  793.     )
  794.        (for-every-token! (token tss fhandles :error-check t)
  795.       (cond ((process-uncalc-features (handle-token token)
  796.                       fhandles if-calc) 
  797.          (remove-tokens (list token) tss))
  798.         ((process-undef-features (handle-token token)
  799.                       fhandles if-undef) 
  800.          (remove-tokens (list token) tss))
  801.         ((apply function frame-handle (handle-token token)
  802.             (mapcar #'(lambda (fhand) (fetch-feature (handle-token token)
  803.                                  fhand
  804.                                  if-get))
  805.                 fhandles))
  806.          t)
  807.         (t (remove-token! token tss))))
  808.        )
  809.   tss)
  810.  
  811. (defun tss-difference!-by-predicate (tss function features if-calc if-undef
  812.                        if-get)
  813.   (setf features (mapcar #'string-upcase features))
  814.   (let ((frame-handle (make-handle :type :frame :frame (handle-frame tss)))
  815.     (fhandles (mapcar #'(lambda (feat) (handle (list (frame tss) "<?>" feat)))
  816.               features))
  817.     )
  818.        (for-every-token! (token frame-handle fhandles :error-check t)
  819.       (cond ((process-uncalc-features (handle-token token)
  820.                       fhandles if-calc) t)
  821.         ((process-undef-features (handle-token token)
  822.                       fhandles if-undef) t)
  823.         ((apply function frame-handle (handle-token token)
  824.             (mapcar #'(lambda (fhand) (fetch-feature (handle-token token)
  825.                                  fhand
  826.                                  if-get))
  827.                 fhandles))
  828.          (remove-token! token tss))))
  829.        )
  830.   tss)
  831.  
  832. (defun tss-union!-by-predicate (tss function features if-calc if-undef
  833.                        if-get)
  834.   (setf features (mapcar #'string-upcase features))
  835.   (let ((frame-handle (make-handle :type :frame :frame (handle-frame tss)))
  836.     (fhandles (mapcar #'(lambda (feat) (handle (list (frame tss) "<?>" feat)))
  837.               features))
  838.     )
  839.        (for-every-token! (token frame-handle fhandles :error-check t)
  840.       (cond ((process-uncalc-features (handle-token token)
  841.                       fhandles if-calc) t)
  842.         ((process-undef-features (handle-token token)
  843.                       fhandles if-undef) t)
  844.         ((apply function frame-handle (handle-token token)
  845.             (mapcar #'(lambda (fhand) (fetch-feature (handle-token token)
  846.                                  fhand
  847.                                  if-get))
  848.                 fhandles))
  849.          (add-token! token tss))))
  850.        )
  851.   tss)
  852.  
  853. (defun process-uncalc-features (token-index fhandles if-uncalc)
  854.   (some #'(lambda (fhand)
  855.           (let ((fdescr (handle-fdescr fhand)))
  856.                (when (equalp (vvref (fdescr-value fdescr) token-index)
  857.                      (case (fdescr-type fdescr)
  858.                        (#.*int* *int-undefined*)
  859.                        (#.*real* *real-undefined*)
  860.                        (t *ptr-undefined*)))
  861.              (cond ((null if-uncalc) t)
  862.                    ((member if-uncalc '(:calculate :compute))
  863.                 (value fhand) nil)
  864.                    (t t))
  865.              )
  866.                )
  867.           )
  868.     fhandles)
  869.   )
  870.  
  871. (defun process-undef-features (token-index fhandles if-undef)
  872.   (some #'(lambda (fhand)
  873.         (let ((fdescr (handle-fdescr fhand)))
  874.          (when (equalp (vvref (fdescr-value fdescr) token-index)
  875.                    (case (fdescr-type fdescr)
  876.                      (#.*int* *int-undefinable*)
  877.                      (#.*real* *real-undefinable*)
  878.                      (t *ptr-undefinable*)))
  879.            (cond ((null if-undef) t)
  880.              ((member if-undef '(:calculate :compute))
  881.               (error
  882.                 "Bad value for :IF-UNDEFINED key: ~S, you probably meant it for :IF-UNCALCULATED" if-undef)
  883.               )
  884.              (t nil))
  885.            )
  886.          )
  887.         )
  888.     fhandles)
  889.   )
  890.  
  891. (defun fetch-feature (token-index fhand if-get)
  892.   (if if-get
  893.       (value fhand)
  894.       (let ((fvalue (vvref (fdescr-value (handle-fdescr fhand)) token-index)))
  895.        (cond ((equalp fvalue
  896.               (case (fdescr-type (handle-fdescr fhand))
  897.                 (#.*int* *int-undefined*)
  898.                 (#.*real* *real-undefined*)
  899.                 (t *ptr-undefined*)))
  900.           :uncalculated)
  901.          ((equalp fvalue
  902.               (case (fdescr-type (handle-fdescr fhand))
  903.                 (#.*int* *int-undefinable*)
  904.                 (#.*real* *real-undefinable*)
  905.                 (t *ptr-undefinable*)))
  906.           :undefined)
  907.          (t fvalue)))
  908.       )
  909.   )
  910.  
  911. (defun tss-mem (token-path tss-path &aux parsed-token-path token-handle more-token-path
  912.         tss-handle tss-fval #| parsed-tss-path more-tss-path tss-fdescr |#)
  913.   "TSS-MEM token-path tss-path - 
  914. Predicate to test if token-path is in TSS defined by tss-path."
  915.   (setf parsed-token-path (parse-token-name token-path))
  916.   (multiple-value-setq (token-handle more-token-path)
  917.     (make-handle-from-parsed-path parsed-token-path))
  918.   (unless (and token-handle
  919.            (check-terminal-path token-handle more-token-path)
  920.            (eq (handle-type token-handle) :token)
  921.            (null more-token-path))
  922.     (error "~S is not a legitimate path!" token-path))
  923.   (cond ((and (handle-p tss-path)
  924.           (member (handle-type tss-path) '(:token-subset :token-sort)))
  925.      (setf tss-handle tss-path))
  926.     (t #|
  927.        (setf parsed-tss-path (parse-tss-name tss-path))
  928.        (multiple-value-setq (tss-handle more-tss-path)
  929.          (make-handle-from-parsed-path parsed-path))
  930.        (unless (and tss-handle
  931.             (check-terminal-path tss-handle more-tss-path)
  932.             (member (handle-type tss-handle)
  933.                 '(:frame-feature :token-feature))
  934.             (eq (fdescr-type (handle-fdescr tss-handle)) *handle*)
  935.             (null more-tss-path))
  936.          (error "~S is not a legitimate path!" tss-path))
  937.        (setf tss-fdescr (handle-fdescr tss-handle))
  938.        (if (eq (handle-type tss-handle) :token-feature)
  939.            (setf tss-fval (vvref (fdescr-value tss-fdescr) 
  940.                      (handle-token tss-handle)))
  941.            (setf tss-fval (fdescr-value tss-fdescr)))
  942.        |#
  943.  
  944.        (setf tss-fval (value tss-path))
  945.        
  946.        (unless (and (handle-p tss-fval)
  947.             (member (handle-type tss-fval) '(:token-subset 
  948.                              :token-sort)))
  949.          (error "~S is not a TSS !" tss-path))
  950.        (setf tss-handle tss-fval)))
  951.   (unless (eq (handle-frame tss-handle) (handle-frame token-handle))
  952.     (error "~S and ~S are from different TS's!" token-path tss-path))
  953.   (unless (integerp (handle-token token-handle))
  954.     (error "Ambigous token not allowed in tss-mem: ~S" token-handle))
  955.   (tss-index-memq (handle-token token-handle)
  956.           (handle-token-existence-array tss-handle))
  957.   )
  958.  
  959. (defun tss-mem@ (feature-path tss &aux fval)
  960.   "TSS-MEM@ feature-path tss - like TSS-MEM, but gets the value of feature-path
  961. (which must be a token) and uses it as the token to check for membership."
  962.   (setf fval (value feature-path))
  963.   (unless (and (handle-p fval)
  964.            (eq (handle-type fval) :token))
  965.     (error "~S (the value of ~S) is not a token handle!" fval feature-path))
  966.   (tss-mem fval tss))
  967.  
  968.  
  969.  
  970. (defun add-tokens (token-handle-list tss)
  971.   "ADD-TOKENS token-handle-list tss - make a new tss and add the listed tokens to
  972. it."
  973.   (add-tokens! token-handle-list (make-tss tss)))
  974.  
  975. (defun add-tokens! (token-handle-list tss)
  976.   "ADD-TOKENS! token-handle-list tss - modify tss to include the listed tokens."
  977.   (unless (and (handle-p tss)
  978.            (eq (handle-type tss) :token-subset))
  979.     (error "~S is not a TSS !" tss))
  980.   (map nil #'(lambda (token) (add-token! token tss))
  981.        token-handle-list)
  982.   tss)
  983.  
  984. (defun add-token (token-handle tss)
  985.   "ADD-TOKEN token-handle tss - make a new tss and add the token to it."
  986.   (add-token! token-handle (make-tss tss)))
  987.  
  988. (defun add-token! (token tss &aux parsed-path handle more-path)
  989.   "ADD-TOKEN! token tss - modify tss to include the token."
  990.   (unless (and (handle-p tss)
  991.            (eq (handle-type tss) :token-subset))
  992.     (error "~S is not a TSS !" tss))
  993.   (setf parsed-path (parse-token-name token))
  994.   (multiple-value-setq (handle more-path)
  995.     (make-handle-from-parsed-path parsed-path))
  996.   (unless (and handle
  997.            (check-terminal-path handle more-path)
  998.            (eq (handle-type handle) :token)
  999.            (null more-path))
  1000.     (error "~S is not a token!" token))
  1001.   (unless (eq (handle-frame handle) (handle-frame tss))
  1002.     (error "~S and ~S are not from the same frame!"
  1003.        token tss))
  1004.   (if (typep (handle-token-existence-array tss)
  1005.          '2index-vector-vector)
  1006.       (setf (vvref (handle-token-existence-array tss)
  1007.            (handle-token handle)) 1)
  1008.       (setf (handle-token-existence-array tss)
  1009.         (ordered-insert! (handle-token handle)
  1010.                  (handle-token-existence-array tss))))
  1011.   tss)
  1012.  
  1013. (defun tss-index-add (new-index tss)
  1014.   (if (typep (handle-token-existence-array tss)
  1015.          '2index-vector-vector)
  1016.       (setf (vvref (handle-token-existence-array tss)
  1017.            new-index) 1)
  1018.       (setf (handle-token-existence-array tss)
  1019.         (ordered-insert! new-index
  1020.                  (handle-token-existence-array tss)))
  1021.       )
  1022.   )
  1023.  
  1024.  
  1025. (defun ordered-insert! (elt olist)
  1026.   (cond ((null olist) (list elt))
  1027.     ((< elt (first olist)) (cons elt olist))
  1028.     ((= elt (first olist)) olist)
  1029.     (t (do ((ol olist (rest ol)))
  1030.            ((or (null (rest ol))
  1031.             (< elt (second ol)))
  1032.         (unless (= elt (first ol))
  1033.           (setf (rest ol)
  1034.             (cons elt (rest ol))))))
  1035.        olist)))
  1036.  
  1037. (defun remove-tokens (token-handle-list tss)
  1038.   "REMOVE-TOKENS token-handle-list tss - make a new tss and remove the listed tokens from
  1039. it."
  1040.   (remove-tokens! token-handle-list (make-tss tss)))
  1041.  
  1042. (defun remove-tokens! (token-handle-list tss)
  1043.   "REMOVE-TOKENS! token-handle-list tss - modify tss to not include the listed tokens."
  1044.   (unless (and (handle-p tss)
  1045.            (eq (handle-type tss) :token-subset))
  1046.     (error "~S is not a TSS !" tss))
  1047.   (map nil #'(lambda (token) (remove-token! token tss))
  1048.        token-handle-list)
  1049.   tss)
  1050.  
  1051. (defun remove-token (token-handle tss)
  1052.   "REMOVE-TOKEN token-handle tss - make a new tss and remove the token from it."
  1053.   (remove-token! token-handle (make-tss tss)))
  1054.  
  1055. (defun remove-token! (token tss &aux parsed-path handle more-path)
  1056.   "REMOVE-TOKENS! token-handle tss - modify tss to not include the token."
  1057.   (unless (and (handle-p tss)
  1058.            (eq (handle-type tss) :token-subset))
  1059.     (error "~S is not a TSS !" tss))
  1060.   (setf parsed-path (parse-token-name token))
  1061.   (multiple-value-setq (handle more-path)
  1062.     (make-handle-from-parsed-path parsed-path))
  1063.   (unless (and handle
  1064.            (check-terminal-path handle more-path)
  1065.            (eq (handle-type handle) :token)
  1066.            (null more-path))
  1067.     (error "~S is not a token!" token))
  1068.   (unless (eq (handle-frame handle) (handle-frame tss))
  1069.     (error "~S and ~S are not from the same frame!"
  1070.        token tss))
  1071.   (if (typep (handle-token-existence-array tss)
  1072.          '2index-vector-vector)
  1073.       (setf (vvref (handle-token-existence-array tss)
  1074.            (handle-token handle)) 0)
  1075.       (setf (handle-token-existence-array tss)
  1076.         (delete (handle-token handle)
  1077.             (handle-token-existence-array tss))))
  1078.   tss)
  1079.  
  1080. (defun pick (tss)
  1081.   "PICK tss - return the next available token in TSS.  Returns NIL when the
  1082. end of the token subset is encountered.  After returning NIL, the next call
  1083. to pick will return the first token (i.e. pick will recycle)."
  1084.   (unless (and (handle-p tss)
  1085.            (member (handle-type tss) '(:token-subset :token-sort)))
  1086.     (error "~S is not a TSS!" tss))
  1087.   (cond ((typep (handle-token-existence-array tss) '2index-vector-vector)
  1088.      (pick-2vv tss))
  1089.     (t (pick-tis tss))
  1090.     )
  1091.   )
  1092.  
  1093. (defun highest-index-of (2vv)
  1094.   (let ((high-ov (fill-pointer (2index-vector-vector-data 2vv))))
  1095.        (1- (* high-ov *default-2index-vector-size*)))
  1096.   )
  1097.  
  1098. (defun pick-2vv (tss &aux (evv (handle-token-existence-array tss))
  1099.                   (highest-index (highest-index-of evv)))
  1100.   (do ((last-index (1+ (or (handle-last-picked tss) -1)) (1+ last-index)))
  1101.       ((or (> last-index highest-index)
  1102.        (and (= (vvref evv last-index) 1)
  1103.         (= (vvref (frame-token-set-existence-vector
  1104.                 (handle-frame tss)) last-index) 1)
  1105.         ))
  1106.        (if (> last-index highest-index)
  1107.        (setf (handle-last-picked tss) nil)
  1108.        (progn
  1109.          (setf (handle-last-picked tss) last-index)
  1110.          (make-handle :type :token
  1111.               :frame (handle-frame tss)
  1112.               :token last-index))))
  1113.       )
  1114.   )
  1115.  
  1116. (defun pick-tis (tss &aux token-index)
  1117.   (do ((last-index (rest (or (handle-last-picked tss)
  1118.                  (cons nil (handle-token-existence-array tss))))
  1119.            (rest last-index)))
  1120.       ((or (null last-index)
  1121.        (= (vvref (frame-token-set-existence-vector
  1122.                (handle-frame tss)) (first last-index)) 1))
  1123.        (setf token-index (first last-index)
  1124.          (handle-last-picked tss) last-index)
  1125.        (when token-index
  1126.      (make-handle :type :token
  1127.               :frame (handle-frame tss)
  1128.               :token token-index))
  1129.        )
  1130.       )
  1131.   )
  1132.  
  1133.  
  1134. (defun pick-reset! (tss)
  1135.   "PICK-RESET! tss - reset the pick context for TSS."
  1136.   (unless (and (handle-p tss)
  1137.            (member (handle-type tss) '(:token-subset :token-sort)))
  1138.     (error "Not a sort or TSS: ~S" tss))
  1139.   (setf (handle-last-picked tss) nil)
  1140.   tss)
  1141.       
  1142.  
  1143.  
  1144.  
  1145.  
  1146. (defun compress (path)
  1147.   "COMPRESS path - compress the token-indexs in path.  WARNING: This
  1148. procedure will invalidate all TSS and token-handles associated with this
  1149. frame. Use with extreem caution!"
  1150.   (let* ((frame-handle (%internal-handle path :error-p t :terminal-p t))
  1151.      (frame-name (isr2:value `(,frame-handle name))))
  1152.        (unless (and (handle-p frame-handle)
  1153.             (eq (handle-type frame-handle) :frame))
  1154.      (error "~S is not a frame!" path))
  1155.        (let* ((parent (parent frame-handle))
  1156.           (scratch-frame
  1157.         (copy-definition frame-handle
  1158.                  (list parent (gensym))))
  1159.           (new-token 0))
  1160.          (map nil
  1161.           #'(lambda (ffpair)
  1162.                (setf (fdescr-value
  1163.                    (cdr (assoc (first ffpair)
  1164.                        (frame-feature-alist
  1165.                          (handle-frame scratch-frame))
  1166.                        :test #'equalp)))
  1167.                  (fdescr-value (rest ffpair))))
  1168.           (frame-feature-alist
  1169.             (handle-frame frame-handle)))
  1170.          (for-every-token (old-token frame-handle)
  1171.         (create (list scratch-frame new-token))
  1172.         (map nil
  1173.              #'(lambda (fdescr)
  1174.               (setf (vvref (fdescr-value
  1175.                      (first (member
  1176.                           (fdescr-featurename fdescr)
  1177.                           (frame-token-set-feature-vector
  1178.                             (handle-frame scratch-frame))
  1179.                           :test #'equalp
  1180.                           :key #'fdescr-featurename)))
  1181.                        new-token)
  1182.                 (vvref (fdescr-value fdescr) (token-index-of old-token))))
  1183.              (frame-token-set-feature-vector
  1184.                (handle-frame frame-handle)))
  1185.         (incf new-token))
  1186.          (map nil
  1187.           #'(lambda (fdescr)
  1188.                (do ((i (* (truncate new-token *default-2index-vector-size*)
  1189.                   *default-2index-vector-size*)
  1190.                    (- i *default-2index-vector-size*)))
  1191.                ((< i 0))
  1192.                (check-and-destroy-empty-block
  1193.                  (fdescr-value fdescr)
  1194.                  i)
  1195.                ))
  1196.           (frame-token-set-feature-vector
  1197.             (handle-frame scratch-frame)))
  1198.          (destroy `(,(isr2:parent frame-handle) ,frame-name))
  1199.          (destroy `(,(isr2:parent frame-handle) ,frame-name))
  1200.          (rename scratch-frame frame-name)
  1201.          )
  1202.        )
  1203.   )
  1204.  
  1205.  
  1206. (defun tss-sort (tss-path key-feature &key (order :ascending) calculate-p
  1207.          value-p &aux new-sort fdescr fval tlist scratch-fd-handle)
  1208.   "TSS-SORT tss-path key-feature &KEY (order :ascending) calculate-p value-p - 
  1209. make a TSS-SORT object from tss-path and key-feature.  Order can be either
  1210. :ASCENDING (data values go from lowest to highest) or :DESCENDING (data values 
  1211. go from highest to lowest). If calculate-p is non-NIL, uncalculated values
  1212. are computed and if value-p is non-NIL, then VALUE is used to fetch values.
  1213. The default is to simply omit uncalculated values and skip the access functions.
  1214. Undefinable values are allways ommited from the sort."
  1215.   (unless (member order '(:ascending :descending))
  1216.     (error "Bad sort order: ~S" order))
  1217.   (setf new-sort (make-null-tss tss-path))
  1218.   (setf key-feature (string key-feature)
  1219.     (handle-type new-sort) :token-sort
  1220.     (handle-feature new-sort) key-feature
  1221.     (handle-sort-order new-sort) order
  1222.     (handle-fdescr new-sort) (setf fdescr
  1223.                        (first
  1224.                      (member
  1225.                        key-feature
  1226.                        (frame-token-set-feature-vector
  1227.                          (handle-frame new-sort))
  1228.                        :test #'equalp
  1229.                        :key #'fdescr-featurename)))
  1230.     scratch-fd-handle (copy-handle new-sort)
  1231.     (handle-type scratch-fd-handle) :token-feature)
  1232.   (unless fdescr (error "No such feature defined: ~A for tss-path ~S" 
  1233.             key-feature tss-path))
  1234.   (unless (member (fdescr-type fdescr) `(,*int* ,*real* ,*string*))
  1235.     (error "Feature is not of a numeric or string type: ~A for tss-path ~S"
  1236.        key-feature tss-path))
  1237.   (for-every-token (token tss-path)
  1238.     (setf (handle-token scratch-fd-handle) (handle-token token)
  1239.       fval (if (or value-p calculate-p) (value scratch-fd-handle)
  1240.            (vvref (fdescr-value fdescr) (handle-token token))))
  1241.     (unless (or (equalp (case (fdescr-type fdescr)
  1242.                   (#.*int* *int-undefined*)
  1243.                   (#.*real* *real-undefined*)
  1244.                   (#.*string* *ptr-undefined*))
  1245.             fval)
  1246.         (equalp (case (fdescr-type fdescr)
  1247.                   (#.*int* *int-undefinable*)
  1248.                   (#.*real* *real-undefinable*)
  1249.                   (#.*string* *ptr-undefinable*))
  1250.             fval))
  1251.       (setf tlist (if (eq order :ascending)
  1252.               (if value-p
  1253.               (ordered-insert-fv-v-ascending! (handle-token token) 
  1254.                             tlist scratch-fd-handle)
  1255.               (ordered-insert-fv-ascending! (handle-token token) 
  1256.                             tlist (fdescr-value fdescr)))
  1257.               (if value-p
  1258.               (ordered-insert-fv-v-descending! (handle-token token) 
  1259.                              tlist scratch-fd-handle)
  1260.               (ordered-insert-fv-descending! (handle-token token) 
  1261.                              tlist (fdescr-value fdescr))))))
  1262.     )
  1263.   (setf (handle-token-existence-array new-sort) tlist)
  1264.   new-sort)
  1265.  
  1266. (defun tss-make-sort (token-list &aux tlist new-sort p)
  1267.   "TSS-MAKE-SORT token-list -
  1268. make a TSS-SORT object from token-list.  Token-list must be a list of tokens, 
  1269. all from the same frame."
  1270.   (unless (and (consp token-list)
  1271.            (list-length token-list)
  1272.            (every #'(lambda (temp)
  1273.                 (and (handle-p temp)
  1274.                      (eq (handle-type temp) :token)
  1275.                      (numberp (handle-token temp))))
  1276.               token-list))
  1277.     (error "Not a list of token handles: ~S" token-list))
  1278.   (setf new-sort (make-null-tss (frame (first token-list))))
  1279.   (setf (handle-type new-sort) :token-sort
  1280.     (handle-feature new-sort) nil
  1281.     (handle-sort-order new-sort) nil
  1282.     (handle-fdescr new-sort) nil
  1283.     tlist (list nil)
  1284.     p tlist)
  1285.   (dolist (token token-list)
  1286.       (if (eq (handle-frame new-sort) (handle-frame token))
  1287.           (setf (rest p) (list (handle-token token))
  1288.             p (rest p))
  1289.           (error "Token not in the same frame: ~S not in frame ~S"
  1290.              token (frame new-sort))))
  1291.   (setf (handle-token-existence-array new-sort) (rest tlist))
  1292.   new-sort)
  1293.  
  1294. (defun tss-sort-by-predicate (tss-sort predicate &key (stable-sort nil) 
  1295.                        &aux new-sort tlist t1-hand t2-hand)
  1296.   "TSS-SORT-BY-PREDICATE tss-sort predicate &KEY (stable-sort nil) -
  1297. Copy and sort a tss-sort using a predicate.  If :STABLE-SORT is NIL (the 
  1298. default), the Common LISP function SORT is used, otherwise the Common LISP 
  1299. function STABLE-SORT is used.  Predicate gets passed two token handles, which
  1300. get modified by this function.  The predicate should return T iff its first 
  1301. argument is less-than its second argument."
  1302.   (unless (and (handle-p tss-sort)
  1303.            (eq (handle-type tss-sort) :token-sort))
  1304.     (error "Not a TSS-SORT: ~S" tss-sort))
  1305.   (setf new-sort (copy-handle tss-sort)
  1306.     tlist (copy-list (handle-token-existence-array new-sort))
  1307.     (handle-feature new-sort) nil
  1308.     (handle-fdescr new-sort) nil
  1309.     (handle-sort-order new-sort) nil
  1310.     t1-hand (copy-handle tss-sort)
  1311.     (handle-type t1-hand) :token
  1312.     t2-hand (copy-handle tss-sort)
  1313.     (handle-type t2-hand) :token)
  1314.   (if stable-sort
  1315.       (setf tlist (stable-sort tlist #'(lambda (i1 i2)
  1316.                            (setf (handle-token t1-hand) i1
  1317.                              (handle-token t2-hand) i2)
  1318.                            (funcall predicate t1-hand t2-hand))))
  1319.       (setf tlist (sort tlist #'(lambda (i1 i2)
  1320.                     (setf (handle-token t1-hand) i1
  1321.                           (handle-token t2-hand) i2)
  1322.                     (funcall predicate t1-hand t2-hand))))
  1323.       )
  1324.   (setf (handle-token-existence-array new-sort) tlist)
  1325.   new-sort)
  1326.  
  1327. (#-(or :allegro :lispworks) defsubst #+(or :allegro :lispworks) defun less-p (a b)
  1328.    (if (numberp a)
  1329.        (< a b)
  1330.        (string< a b)))
  1331.  
  1332. (#-(or :allegro :lispworks) defsubst #+(or :allegro :lispworks) defun greater-p (a b)
  1333.    (if (numberp a)
  1334.        (> a b)
  1335.        (string> a b)))
  1336.  
  1337. (defun ordered-insert-fv-ascending! (index olist val-vvec &aux fval)
  1338.   (setf fval (vvref val-vvec index))
  1339.   (cond #|((member index olist) olist)|#
  1340.     ((null olist) (list index))
  1341.     ((less-p fval (vvref val-vvec (first olist)))
  1342.      (cons index olist))
  1343.     (t (do ((ol olist (rest ol)))
  1344.            ((or (null (rest ol))
  1345.             (less-p fval (vvref val-vvec (second ol))))
  1346.         (setf (rest ol)
  1347.               (cons index (rest ol)))))
  1348.        olist)
  1349.     )
  1350.   )
  1351.  
  1352. (defun ordered-insert-fv-v-ascending! (index olist fd-handle &aux fval)
  1353.   (setf (handle-token fd-handle) index
  1354.     fval (value fd-handle))
  1355.   (cond #|((member index olist) olist)|#
  1356.     ((null olist) (list index))
  1357.     ((less-p fval (progn (setf (handle-token fd-handle) (first olist))
  1358.                  (value fd-handle)))
  1359.      (cons index olist))
  1360.     (t (do ((ol olist (rest ol)))
  1361.            ((or (null (rest ol))
  1362.             (less-p fval (progn
  1363.                    (setf (handle-token fd-handle) (second ol))
  1364.                    (value fd-handle))))
  1365.         (setf (rest ol)
  1366.               (cons index (rest ol)))))
  1367.        olist))
  1368.   )
  1369.  
  1370. (defun ordered-insert-fv-descending! (index olist val-vvec &aux fval)
  1371.   (setf fval (vvref val-vvec index))
  1372.   (cond #|((member index olist) olist)|#
  1373.     ((null olist) (list index))
  1374.     ((greater-p fval (vvref val-vvec (first olist))) (cons index olist))
  1375.     (t (do ((ol olist (rest ol)))
  1376.            ((or (null (rest ol))
  1377.             (greater-p fval (vvref val-vvec (second ol))))
  1378.         (setf (rest ol)
  1379.               (cons index (rest ol)))))
  1380.        olist))
  1381.   )
  1382.  
  1383. (defun ordered-insert-fv-v-descending! (index olist fd-handle &aux fval)
  1384.   (setf (handle-token fd-handle) index
  1385.     fval (value fd-handle))
  1386.   (cond #|((member index olist) olist)|#
  1387.     ((null olist) (list index))
  1388.     ((greater-p fval (progn (setf (handle-token fd-handle) (first olist))
  1389.                 (value fd-handle)))
  1390.      (cons index olist))
  1391.     (t (do ((ol olist (rest ol)))
  1392.            ((or (null (rest ol))
  1393.             (greater-p fval (progn
  1394.                       (setf (handle-token fd-handle) (second ol))
  1395.                       (value fd-handle))))
  1396.         (setf (rest ol)
  1397.               (cons index (rest ol)))))
  1398.        olist))
  1399.   )
  1400.  
  1401. (defun tss-sort-key (sort-tss)
  1402.   "TSS-SORT-KEY sort-tss - returns two values: the sort key (token feature
  1403. handle) and the sort order."
  1404.   (if (and (handle-p sort-tss)
  1405.        (eq (handle-type sort-tss) :token-sort))
  1406.       (if (null (handle-feature sort-tss))
  1407.       (values nil nil)
  1408.       (values (make-handle :type :token-feature
  1409.                    :frame (handle-frame sort-tss)
  1410.                    :feature (handle-feature sort-tss)
  1411.                    :fdescr (handle-fdescr sort-tss)
  1412.                    :token :?
  1413.                    )
  1414.           (handle-sort-order sort-tss)))
  1415.       (error "Not a valid sort: ~S" sort-tss))
  1416.   )
  1417.  
  1418. (defun sort-update! (sort-tss &key calculate-p value-p)
  1419.   "SORT-UPDATE! sort-tss &KEY calculate-p value-p - resort an existing tss-sort.  
  1420. Note: this only handles added/droped tokens.  If the feature value(s) the sort
  1421. is based on  have been altered, the sort might not be valid.  A new TSS-SORT
  1422. handle should be built (i.e. by calling TSS-SORT). If calculate-p is non-NIL,
  1423. uncalculated values are computed and if value-p is non-NIL, then VALUE is used
  1424. to fetch values. The default is to simply omit uncalculated values and skip the
  1425. access functions. Undefinable values are allways ommited from the sort."
  1426.   (unless (and (handle-p sort-tss)
  1427.            (eq (handle-type sort-tss) :token-sort))
  1428.     (error "Not a Sort: ~S" sort-tss))
  1429.   (when (null (handle-feature sort-tss))
  1430.     (error "Not a re-sortable sort: ~S" sort-tss))
  1431.   (when (null (handle-fdescr sort-tss))
  1432.     (cerror "Fetch feature descriptor, if posible."
  1433.         "Feature descriptor missing in ~S" sort-tss)
  1434.     (setf (handle-fdescr sort-tss)
  1435.       (first (member (handle-feature sort-tss)
  1436.              (frame-token-set-feature-vector
  1437.                (handle-frame sort-tss))
  1438.              :test #'equalp
  1439.              :key #'fdescr-featurename)))
  1440.     (when (null (handle-fdescr sort-tss))
  1441.       (error "Feature descriptor missing in ~S" sort-tss))
  1442.     )
  1443.   (let ((tlist (handle-token-existence-array sort-tss))
  1444.     (scratch-tss (make-tss (frame sort-tss)))
  1445.     (scratch-fd-handle (copy-handle sort-tss))
  1446.     )
  1447.        (setf (handle-type scratch-fd-handle) :token-feature)
  1448.        (do* ((result (cons nil tlist))
  1449.          (p result)
  1450.          (dummy-handle (make-handle :type :token
  1451.                     :frame (handle-frame sort-tss)
  1452.                     :token :?))
  1453.          (index (second p) (second p)))
  1454.         ((null (rest p)) (setf tlist (rest result)))
  1455.         (setf (handle-token dummy-handle) index)
  1456.         (if (tss-mem dummy-handle scratch-tss)
  1457.         (progn
  1458.           (remove-tokens! (list dummy-handle) scratch-tss)
  1459.           (setf p (rest p)))
  1460.         (progn
  1461.           (setf (rest p) (rest (rest p))))
  1462.         )
  1463.         )
  1464.        (let ((fdescr (handle-fdescr sort-tss))
  1465.          (order (handle-sort-order sort-tss))
  1466.          fval
  1467.          )
  1468.         (for-every-token (token scratch-tss)
  1469.            (setf (handle-token scratch-fd-handle) (handle-token token)
  1470.              fval (if (or value-p calculate-p) (value scratch-fd-handle)
  1471.                   (vvref (fdescr-value fdescr) (handle-token token))))
  1472.            (unless (or (equalp (case (fdescr-type fdescr)
  1473.                      (#.*int* *int-undefined*)
  1474.                      (#.*real* *real-undefined*)
  1475.                      (#.*string* *ptr-undefined*))
  1476.                    fval)
  1477.                (equalp (case (fdescr-type fdescr)
  1478.                      (#.*int* *int-undefinable*)
  1479.                      (#.*real* *real-undefinable*)
  1480.                      (#.*string* *ptr-undefinable*))
  1481.                    fval))
  1482.          (setf tlist (if (eq order :ascending)
  1483.                  (if value-p
  1484.                      (ordered-insert-fv-v-ascending!
  1485.                        (handle-token token) 
  1486.                        tlist scratch-fd-handle)
  1487.                      (ordered-insert-fv-ascending!
  1488.                        (handle-token token) 
  1489.                        tlist (fdescr-value fdescr)))
  1490.                  (if value-p
  1491.                      (ordered-insert-fv-v-descending!
  1492.                        (handle-token token) 
  1493.                        tlist scratch-fd-handle)
  1494.                      (ordered-insert-fv-descending!
  1495.                        (handle-token token) 
  1496.                        tlist (fdescr-value fdescr))))))
  1497.            )
  1498.         )
  1499.        (setf (handle-token-existence-array sort-tss) tlist
  1500.          (handle-last-picked sort-tss) nil)
  1501.        )
  1502.   sort-tss
  1503.   )
  1504.  
  1505.  
  1506.  
  1507.  
  1508.  
  1509.            
  1510.  
  1511.  
  1512.