Filtering...

memoize-raw

memoize-raw
other
(in-package "ACL2")
other
(eval-when (:execute :compile-toplevel :load-toplevel)
  (when (ignore-errors (mv-let (x y)
        (funcall (intern "READ-CYCLE-COUNTER" "SB-IMPL"))
        (not (and (eql x 0) (eql y 0)))))
    (format t "; Note: pushing :RDTSC onto *features*.~&")
    (finish-output)
    (pushnew :rdtsc *features*)))
other
(defg *enable-multithreaded-memoization* nil)
mf-multiprocessingfunction
(defun mf-multiprocessing
  (flg &optional quiet)
  (cond ((iff *enable-multithreaded-memoization* flg) (when (not quiet)
        (format *standard-output*
          "~%; Note: Multiprocessing is already ~a.~%"
          (if *enable-multithreaded-memoization*
            "on"
            "off"))))
    (t (unwind-protect (setq *enable-multithreaded-memoization* flg)
        (rememoize-all t))))
  flg)
other
(defg *global-memoize-lock*
  (make-lock "*GLOBAL-MEMOIZE-LOCK*"))
with-global-memoize-lockmacro
(defmacro with-global-memoize-lock
  (&rest forms)
  `(if *enable-multithreaded-memoization*
    (with-lock-raw *global-memoize-lock* ,@FORMS)
    (progn ,@FORMS)))
with-global-memoize-lock-staticmacro
(defmacro with-global-memoize-lock-static
  (&rest forms)
  (if *enable-multithreaded-memoization*
    `(with-lock-raw *global-memoize-lock* . ,FORMS)
    `(progn . ,FORMS)))
mf-mhtmacro
(defmacro mf-mht
  (&rest args)
  (if (assoc-keyword :shared args)
    `(hl-mht ,@ARGS)
    `(if *enable-multithreaded-memoization*
      (hl-mht :shared :default ,@ARGS)
      (hl-mht ,@ARGS))))
mf-gethashmacro
(defmacro mf-gethash
  (key ht)
  `(gethash ,KEY (the hash-table ,HT)))
mf-sethashmacro
(defmacro mf-sethash
  (key val ht)
  `(setf (gethash ,KEY (the hash-table ,HT)) ,VAL))
mf-flex-aconsmacro
(defmacro mf-flex-acons
  (elem al)
  `(hl-flex-acons ,ELEM ,AL *enable-multithreaded-memoization*))
mf-hash-table-countmacro
(defmacro mf-hash-table-count
  (ht)
  `(hash-table-count (the hash-table ,HT)))
mf-hash-table-sizemacro
(defmacro mf-hash-table-size
  (ht)
  `(hash-table-size (the hash-table ,HT)))
mf-maphashmacro
(defmacro mf-maphash
  (lam ht)
  `(maphash ,LAM (the hash-table ,HT)))
other
(defparameter *record-bytes*
  (and (or (member :ccl *features*)
      (member :sbcl *features*)
      (member :lispworks *features*))
    (> most-positive-fixnum (expt 2 32))))
other
(defparameter *record-calls* t)
other
(defparameter *record-hits* t)
other
(defparameter *record-mht-calls* t)
other
(defparameter *record-pons-calls* t)
other
(defparameter *record-time* t)
other
(defg *mf-print-right-margin* 79)
other
(defv *report-bytes* t)
other
(defv *report-calls* t)
other
(defv *report-calls-from* t)
other
(defv *report-calls-to* t)
other
(defv *report-hits* t)
other
(defv *report-mht-calls* t)
other
(defv *report-pons-calls* t)
other
(defv *report-time* t)
other
(defv *report-on-memo-tables* t)
other
(defv *report-on-pons-tables* t)
other
(defg *sort-to-from-by-calls* nil)
other
(defg *memoize-summary-order-reversed* nil)
other
(defg *mf-print-alist-width* 45)
other
(defg *memoize-summary-order-list*
  '(total-time number-of-calls))
other
(defg *memoize-summary-limit* 100)
other
(defg *condition-nil-as-hit* nil)
other
(defvar *never-memoize-ht*
  (let ((ht (mf-mht :test 'eq :shared :default)))
    (loop for
      x
      in
      *stobjs-out-invalid*
      do
      (mf-sethash x t ht))
    ht))
other
(defg *float-ticks/second* (float (expt 2 31)))
other
(defg *float-ticks/second-initialized* nil)
other
(declaim (float *float-ticks/second*))
other
(defg *pons-call-counter* 0)
other
(defg *pons-misses-counter* 0)
other
(declaim (type mfixnum *pons-call-counter*))
other
(declaim (type mfixnum *pons-misses-counter*))
other
(defg *mf-shorten-ht* (mf-mht :test 'eql :shared :default))
initial-memoize-info-htfunction
(defun initial-memoize-info-ht
  nil
  (if *enable-multithreaded-memoization*
    (mf-mht :shared :default)
    (mf-mht)))
other
(defg *memoize-info-ht* (initial-memoize-info-ht))
other
(declaim (hash-table *memoize-info-ht*))
other
(defparameter *memo-max-sizes* (mf-mht :shared :default))
initial-memoize-call-arrayfunction
(defun initial-memoize-call-array
  (n)
  (make-array n :element-type 'mfixnum :initial-element 0))
other
(defg *memoize-call-array* (initial-memoize-call-array 1))
other
(declaim (type (simple-array mfixnum (*)) *memoize-call-array*))
other
(defg *callers-array* (make-array 0))
other
(declaim (type (simple-array t (*)) *callers-array*))
other
(defconstant *ma-bytes-index* 0)
other
(defconstant *ma-hits-index* 1)
other
(defconstant *ma-mht-index* 2)
other
(defconstant *ma-pons-index* 4)
other
(declaim (type (and mfixnum fixnum)
    *max-symbol-to-fixnum*
    *initial-2max-memoize-fns*
    *2max-memoize-fns*))
other
(defconstant *initial-max-symbol-to-fixnum* 4)
other
(defg *max-symbol-to-fixnum* *initial-max-symbol-to-fixnum*)
other
(defv *initial-2max-memoize-fns* 1000)
other
(defg *2max-memoize-fns* *initial-2max-memoize-fns*)
other
(defg *memoize-init-done* nil)
other
(defg *hons-gentemp-counter* 0)
other
(defg *memoize-use-attachment-warning-p* t)
other
(defv *number-of-arguments-and-values-ht*
  (mf-mht :shared :default))
other
(declaim (hash-table *number-of-arguments-and-values-ht*))
our-syntaxmacro
(defmacro our-syntax
  (&rest args)
  `(our-with-standard-io-syntax (let ((*package* (find-package-fast (f-get-global 'current-package *the-live-state*))) (*readtable* *acl2-readtable*))
      ,@ARGS)))
our-syntax-nicemacro
(defmacro our-syntax-nice
  (&rest args)
  `(our-syntax (setq *print-case* :downcase)
    (setq *print-pretty* t)
    (setq *print-readably* nil)
    (setq *print-right-margin* ,*MF-PRINT-RIGHT-MARGIN*)
    (setq *print-miser-width* 100)
    ,@ARGS))
mf-note-arityfunction
(defun mf-note-arity
  (fn nargs nvals)
  (mf-sethash fn
    (cons nargs nvals)
    *number-of-arguments-and-values-ht*))
memoize-look-up-def-rawfunction
(defun memoize-look-up-def-raw
  (sym quiet-p)
  (let ((temp (get sym 'acl2-saved-def)))
    (cond (temp (cdr temp))
      (t (let* ((fn (symbol-function sym)) (lam (and fn (function-lambda-expression fn))))
          (cond (lam (assert (or (eq (car lam) 'lambda)
                  (eq (car lam) 'named-lambda)))
              lam)
            (quiet-p nil)
            (t (error "Lisp cannot find a definition for ~
                                ~s.~%Consider using ~s or supplying to ~
                                ~%memoize(-fn) an explicit :CL-DEFUN ~
                                argument.~a"
                sym
                'save-def
                ""))))))))
other
(defun-one-output mf-len-inputs
  (fn)
  (assert (symbolp fn))
  (assert (fboundp fn))
  (assert (not (macro-function fn)))
  (assert (not (special-operator-p fn)))
  (or (let ((pair (mf-gethash fn *number-of-arguments-and-values-ht*)))
      (and (consp pair) (integerp (car pair)) (car pair)))
    (let ((formals (getpropc fn 'formals t (w *the-live-state*))))
      (and (not (eq t formals)) (length formals)))
    (let ((def (memoize-look-up-def-raw fn t)))
      (and def (length (cadr def))))))
other
(defun-one-output mf-len-outputs
  (fn)
  (assert (symbolp fn))
  (assert (fboundp fn))
  (assert (not (macro-function fn)))
  (assert (not (special-operator-p fn)))
  (or (let ((pair (mf-gethash fn *number-of-arguments-and-values-ht*)))
      (and (consp pair) (integerp (cdr pair)) (cdr pair)))
    (let* ((state *the-live-state*) (w (w state)))
      (and (not (eq t (getpropc fn 'formals t w)))
        (len (stobjs-out fn w))))
    (and (get fn 'acl2-saved-def) 1)))
other
(defconstant *10-days-in-seconds* (* 10 24 60 60))
10-daysfunction
(defun 10-days
  nil
  (let ((n (* *10-days-in-seconds* (ceiling *float-ticks/second*))))
    n))
other
(defg *10-days* (10-days))
other
(declaim (type mfixnum *10-days*))
other
(defg *float-internal-time-units-per-second*
  (float internal-time-units-per-second))
other
(declaim (float *float-internal-time-units-per-second*))
internal-real-ticksmacro
(defmacro internal-real-ticks
  nil
  '(the-mfixnum (logand (the-mfixnum (get-internal-real-time))
      most-positive-mfixnum)))
other
(defun-one-output float-ticks/second-init
  nil
  (unless *float-ticks/second-initialized*
    (setq *float-ticks/second*
      *float-internal-time-units-per-second*)
    (setq *10-days* (10-days))
    (setq *float-ticks/second-initialized* t)
    (check-type *float-ticks/second*
      (and float (satisfies plusp)))))
safe-incf-aux-errormacro
(defmacro safe-incf-aux-error
  (x inc where)
  `(cond (',WHERE (error "~%; SAFE-INCF-AUX: ** Error: ~a."
        (list :x ,X :inc ,INC :where ',WHERE)))
    (t (progn (setf (the mfixnum ,X) most-positive-mfixnum) nil))))
safe-incf-auxmacro
(defmacro safe-incf-aux
  (x inc &optional where)
  (cond ((not (or (symbolp inc)
         (and (< inc most-positive-mfixnum) (> inc 0)))) (safe-incf-aux-error x inc where))
    ((and (true-listp x)
       (equal (len x) 3)
       (member (car x) '(aref svref))
       (symbolp (nth 1 x))
       (consp (nth 2 x))) (let ((idx (make-symbol "IDX")))
        `(let ((,IDX (the-mfixnum ,(NTH 2 X))))
          (declare (type mfixnum ,IDX))
          (safe-incf (,(NTH 0 X) ,(NTH 1 X) ,IDX) ,INC ,WHERE))))
    (t (let ((v (make-symbol "V")))
        `(let ((,V (the-mfixnum ,X)))
          (declare (type mfixnum ,V))
          (cond ((<= ,V
               (the-mfixnum (- most-positive-mfixnum (the-mfixnum ,INC)))) (setf (the mfixnum ,X)
                (the-mfixnum (+ ,V (the-mfixnum ,INC))))
              nil)
            (t (safe-incf-aux-error ,X ,INC ,WHERE))))))))
safe-incfmacro
(defmacro safe-incf
  (x inc &optional where)
  (cond ((integerp inc) (if (<= inc 0)
        nil
        `(safe-incf-aux ,X ,INC ,WHERE)))
    ((symbolp inc) `(if (>= 0 (the-mfixnum ,INC))
        nil
        (safe-incf-aux ,X ,INC ,WHERE)))
    (t (let ((incv (make-symbol "INCV")))
        `(let ((,INCV (the-mfixnum ,INC)))
          (declare (type mfixnum ,INCV))
          (if (>= 0 ,INCV)
            nil
            (safe-incf-aux ,X ,INCV ,WHERE)))))))
incf-pons-callsmacro
(defmacro incf-pons-calls
  nil
  '(safe-incf *pons-call-counter* 1))
incf-pons-missesmacro
(defmacro incf-pons-misses
  nil
  '(safe-incf *pons-misses-counter* 1))
ponsfunction
(defun pons
  (x y ht)
  (declare (hash-table ht))
  (incf-pons-calls)
  (let* ((flex-alist (mf-gethash y ht)) (entry (hl-flex-assoc x flex-alist)))
    (cond (entry)
      (t (incf-pons-misses)
        (let* ((was-alistp (listp flex-alist)) (new-cons (cons x y))
            (new-flex-alist (mf-flex-acons new-cons flex-alist)))
          (when was-alistp (mf-sethash y new-flex-alist ht))
          new-cons)))))
pist*macro
(defmacro pist*
  (table &rest x)
  (cond ((atom x) x)
    ((atom (cdr x)) (car x))
    (t (list 'pons
        (car x)
        (cons 'pist* (cons table (cdr x)))
        table))))
initialize-never-memoize-htfunction
(defun initialize-never-memoize-ht
  nil
  (let ((ht (mf-mht :test 'eq :shared :default)))
    (note-fns-in-file "hons-raw.lisp" ht)
    (note-fns-in-file "memoize-raw.lisp" ht)
    (flet ((update-nmht (fn)
         (when (and (fboundp fn) (not (macro-function fn)))
           (never-memoize-fn fn))))
      (mf-maphash (lambda (key val) (declare (ignore val)) (update-nmht key))
        ht)
      (loop for
        fn
        in
        *common-lisp-symbols-from-main-lisp-package*
        do
        (update-nmht fn))))
  nil)
never-memoize-fnfunction
(defun never-memoize-fn
  (fn)
  (mf-sethash fn t *never-memoize-ht*)
  nil)
never-memoize-pfunction
(defun never-memoize-p
  (fn)
  (mf-gethash fn *never-memoize-ht*))
other
(defrec memoize-info-ht-entry
  (ext-anc-attachments start-ticks
    num
    tablename
    ponstablename
    condition
    inline
    memoized-fn
    old-fn
    fn
    sts
    cl-defun
    formals
    commutative
    specials
    stobjs-in
    stobjs-out
    record-bytes
    record-calls
    record-hits
    record-mht-calls
    record-pons-calls
    record-time
    forget
    memo-table-init-size
    aokp
    invoke)
  t)
ma-indexmacro
(defmacro ma-index
  (col &optional (row 0) (2mmf '*2max-memoize-fns*))
  (let ((col-base `(* ,2MMF (the-mfixnum ,COL))))
    (if (eql row 0)
      `(the-mfixnum ,COL-BASE)
      `(ma-index-from-col-base ,COL-BASE ,ROW))))
ma-index-from-col-basemacro
(defmacro ma-index-from-col-base
  (col-base row)
  `(the-mfixnum (+ (the-mfixnum ,COL-BASE) (the-mfixnum ,ROW))))
ma-index-callsmacro
(defmacro ma-index-calls
  (child &optional (parent 0) (2mmf '*2max-memoize-fns*))
  (let ((2child `(the-mfixnum (* 2 (the-mfixnum ,CHILD)))))
    (if (eql parent 0)
      2child
      `(ma-index ,PARENT ,2CHILD ,2MMF))))
ma-index-ticksmacro
(defmacro ma-index-ticks
  (child &optional (parent 0) (2mmf '*2max-memoize-fns*))
  (let ((2child+1 `(the-mfixnum (1+ (the-mfixnum (* 2 (the-mfixnum ,CHILD)))))))
    (if (eql parent 0)
      2child+1
      `(ma-index ,PARENT ,2CHILD+1 ,2MMF))))
outside-caller-col-basefunction
(defun outside-caller-col-base
  nil
  (ma-index *initial-max-symbol-to-fixnum*))
other
(defvar *caller*
  (let ((val (outside-caller-col-base)))
    (check-type val mfixnum)
    val))
other
(declaim (type mfixnum *caller*))
other
(defrec memo-max-sizes-entry
  (num-clears max-pt-size max-mt-size avg-pt-size avg-mt-size)
  t)
other
(defparameter *memoize-verbose* nil)
memoize-table-desired-sizefunction
(defun memoize-table-desired-size
  (fn min-size)
  (let* ((max-sizes (mf-gethash fn *memo-max-sizes*)))
    (if (not max-sizes)
      min-size
      (let* ((nclears (access memo-max-sizes-entry max-sizes :num-clears)) (avg-mt-size (access memo-max-sizes-entry max-sizes :avg-mt-size))
          (our-guess (ceiling (* 1.2 avg-mt-size)))
          (capped-guess (min our-guess (* nclears 44000)))
          (final-guess (max *mht-default-size* min-size capped-guess)))
        (when (and (< (integer-length (- nclears 1)) (integer-length nclears))
            *memoize-verbose*)
          (format t
            "; ~s memo table: ~s clears, avg size ~s, guess ~s, final ~
                     ~s~%"
            fn
            nclears
            avg-mt-size
            our-guess
            final-guess))
        final-guess))))
pons-table-desired-sizefunction
(defun pons-table-desired-size
  (fn min-size)
  (let* ((max-sizes (mf-gethash fn *memo-max-sizes*)))
    (if (not max-sizes)
      *mht-default-size*
      (let* ((nclears (access memo-max-sizes-entry max-sizes :num-clears)) (avg-pt-size (access memo-max-sizes-entry max-sizes :avg-pt-size))
          (our-guess (ceiling (* 1.2 avg-pt-size)))
          (capped-guess (min our-guess (* nclears 44000)))
          (final-guess (max *mht-default-size* min-size capped-guess)))
        (when (and (< (integer-length (- nclears 1)) (integer-length nclears))
            *memoize-verbose*)
          (format t
            "; ~s pons table: ~s clears, avg size ~s, guess ~s, final ~
                     ~s~%"
            fn
            nclears
            avg-pt-size
            our-guess
            final-guess))
        final-guess))))
make-initial-memoize-hash-tablefunction
(defun make-initial-memoize-hash-table
  (fn init-size)
  (with-global-memoize-lock (mf-mht :size (memoize-table-desired-size fn init-size))))
make-initial-memoize-pons-tablefunction
(defun make-initial-memoize-pons-table
  (fn init-size)
  (with-global-memoize-lock (mf-mht :size (pons-table-desired-size fn init-size))))
update-memo-max-sizesfunction
(defun update-memo-max-sizes
  (fn pt-size mt-size)
  (when (or (< 0 mt-size) (< 0 pt-size))
    (with-global-memoize-lock (let ((old (mf-gethash fn *memo-max-sizes*)))
        (if (not old)
          (mf-sethash fn
            (make memo-max-sizes-entry
              :num-clears 1
              :max-pt-size pt-size
              :max-mt-size mt-size
              :avg-pt-size (coerce pt-size 'float)
              :avg-mt-size (coerce mt-size 'float))
            *memo-max-sizes*)
          (let* ((old.num-clears (access memo-max-sizes-entry old :num-clears)) (old.max-pt-size (access memo-max-sizes-entry old :max-pt-size))
              (old.max-mt-size (access memo-max-sizes-entry old :max-mt-size))
              (old.avg-pt-size (access memo-max-sizes-entry old :avg-pt-size))
              (old.avg-mt-size (access memo-max-sizes-entry old :avg-mt-size))
              (new.num-clears (+ 1 old.num-clears)))
            (mf-sethash fn
              (make memo-max-sizes-entry
                :num-clears new.num-clears
                :max-pt-size (max pt-size old.max-pt-size)
                :max-mt-size (max mt-size old.max-mt-size)
                :avg-pt-size (/ (+ pt-size (* old.avg-pt-size old.num-clears))
                  new.num-clears)
                :avg-mt-size (/ (+ mt-size (* old.avg-mt-size old.num-clears))
                  new.num-clears))
              *memo-max-sizes*))))))
  nil)
print-memo-max-sizesfunction
(defun print-memo-max-sizes
  nil
  (with-global-memoize-lock (when (equal (mf-hash-table-count *memo-max-sizes*) 0)
      (return-from print-memo-max-sizes nil))
    (format t
      "Memo table statistics gathered at each from when they were ~
             cleared:~%~%")
    (let ((indent 8) indent-str)
      (mf-maphash (lambda (fn entry)
          (declare (ignore entry))
          (setq indent (max indent (length (symbol-name fn)))))
        *memo-max-sizes*)
      (setq indent-str (format nil "~a" (+ 2 indent)))
      (format t
        (concatenate 'string "~" indent-str ":@a")
        "Function")
      (format t
        " ~10:@a | ~15:@a ~15:@a | ~15:@a ~15:@a~%"
        "Clears"
        "PT Max"
        "PT Avg"
        "MT Max"
        "MT Avg")
      (mf-maphash (lambda (fn entry)
          (let* ((num-clears (access memo-max-sizes-entry entry :num-clears)) (max-pt-size (access memo-max-sizes-entry entry :max-pt-size))
              (max-mt-size (access memo-max-sizes-entry entry :max-mt-size))
              (avg-pt-size (access memo-max-sizes-entry entry :avg-pt-size))
              (avg-mt-size (access memo-max-sizes-entry entry :avg-mt-size)))
            (format t
              (concatenate 'string
                "~"
                indent-str
                ":@a ~10:D | ~15:D ~15:D | ~15:D ~15:D~%")
              fn
              num-clears
              max-pt-size
              (floor avg-pt-size)
              max-mt-size
              (floor avg-mt-size))))
        *memo-max-sizes*)
      (format t "~%")))
  nil)
memoize-flush1function
(defun memoize-flush1
  (lst)
  (with-global-memoize-lock (loop for
      sym
      in
      lst
      do
      (when (boundp (the symbol sym))
        (let ((old (symbol-value (the symbol sym))))
          (unless (or (null old) (eql 0 (mf-hash-table-count old)))
            (setf (symbol-value (the symbol sym)) nil)))))))
memoize-flushmacro
(defmacro memoize-flush
  (st)
  (and st
    (let ((s (st-lst st)))
      `(when ,S (memoize-flush1 ,S)))))
sync-memoize-call-arrayfunction
(defun sync-memoize-call-array
  nil
  (with-global-memoize-lock (let ((n1 (ma-index *2max-memoize-fns*)) (n2 (1+ *max-symbol-to-fixnum*)))
      (declare (type (and fixnum mfixnum) n1 n2))
      (setq *memoize-call-array* (initial-memoize-call-array 1))
      (setq *callers-array* (make-array 0))
      (gc$)
      (setq *memoize-call-array* (initial-memoize-call-array n1))
      (setq *callers-array* (make-array n2 :initial-element nil))
      (setq *caller* (outside-caller-col-base)))))
memoize-call-array-growfunction
(defun memoize-call-array-grow
  (&optional (2nmax (* 2 (ceiling (* 3/2 (/ *2max-memoize-fns* 2))))))
  (with-global-memoize-lock (unless (integerp 2nmax)
      (error "(memoize-call-array-grow ~s).  Arg must be an integer."
        2nmax))
    (unless (evenp 2nmax)
      (error "(memoize-call-array-grow ~s).  Arg must be even."
        2nmax))
    (unless (> 2nmax 100)
      (error "(memoize-call-array-grow ~s).  Arg must be > 100."
        2nmax))
    (when (<= 2nmax *2max-memoize-fns*)
      (cw "; memoize-call-array-grow: *memoize-call-array* already big enough.~%")
      (return-from memoize-call-array-grow))
    (unless (<= (* 2nmax 2nmax) most-positive-mfixnum)
      (error "memoize-call-array-grow:  most-positive-mfixnum exceeded.  Too ~
             many memoized functions."))
    (unless (<= (* 2nmax 2nmax) most-positive-fixnum)
      (error "memoize-call-array-grow:  most-positive-fixnum exceeded.  Too ~
             many memoized functions."))
    (unless (< (* 2nmax 2nmax) array-total-size-limit)
      (error "memoize-call-array-grow: ARRAY-TOTAL-SIZE-LIMIT exceeded.  Too ~
             many memoized functions."))
    (unless (< (* 2nmax 2nmax) array-dimension-limit)
      (error "memoize-call-array-grow: ARRAY-DIMENSION-LIMIT exceeded.  Too ~
             many memoized functions."))
    (unless (eql *caller* (outside-caller-col-base))
      (cerror "Continue at your own risk."
        "MEMOIZE-CALL-ARRAY-GROW was called while a memoized function~%~
              was executing, so all bets are off.  Continue only at your own~%~
              risk.  That risk may be low, but at the least, memoization~%~
              reports (in particular, from memsum) will probably be~%~
              inaccurate."))
    (setq *2max-memoize-fns* 2nmax)
    (let ((state *the-live-state*))
      (observation 'memoize-call-array-grow
        "Now reinitializing memoization structures.  This will ~
                   erase saved values and statistics."))
    (sync-memoize-call-array)
    (rememoize-all))
  nil)
other
(defun-one-output symbol-to-fixnum-create
  (s)
  (check-type s symbol)
  (with-global-memoize-lock (let ((g (mf-gethash s *memoize-info-ht*)))
      (if g
        (access memoize-info-ht-entry g :num)
        (let (new)
          (loop for
            i
            fixnum
            from
            (1+ *initial-max-symbol-to-fixnum*)
            below
            (the fixnum (floor *2max-memoize-fns* 2))
            do
            (unless (mf-gethash i *memoize-info-ht*)
              (setq new i)
              (return)))
          (cond (new (setq *max-symbol-to-fixnum*
                (max *max-symbol-to-fixnum* new))
              new)
            (t (memoize-call-array-grow) (symbol-to-fixnum-create s))))))))
other
(defun-one-output symbol-to-fixnum
  (s)
  (check-type s symbol)
  (let ((g (mf-gethash s *memoize-info-ht*)))
    (if g
      (access memoize-info-ht-entry g :num)
      (error "(symbol-to-fixnum ~s).  Illegal symbol." s))))
other
(defun-one-output fixnum-to-symbol
  (n)
  (check-type n fixnum)
  (or (mf-gethash n *memoize-info-ht*)
    (error "(fixnum-to-symbol ~s). Illegal number." n)))
other
(defun-one-output hons-gentemp
  (root)
  (check-type root string)
  (loop (safe-incf *hons-gentemp-counter* 1 hons-gentemp)
    (let ((name (our-syntax (format nil "HONS-G-~s,~s" root *hons-gentemp-counter*))))
      (multiple-value-bind (sym status)
        (intern name (find-package "ACL2_INVISIBLE"))
        (if (null status)
          (return sym))))))
other
(defun-one-output st-lst
  (st)
  (check-type st symbol)
  (intern (our-syntax (format nil
        "HONS-S-~s,~s"
        (package-name (symbol-package st))
        (symbol-name st)))
    (find-package "ACL2_INVISIBLE")))
other
(defun-one-output mf-dcls
  (l)
  (loop for
    dec
    in
    l
    nconc
    (let ((temp (if (consp dec)
           (loop for
             d
             in
             (cdr dec)
             nconc
             (if (and (consp d) (eq (car d) 'ignore))
               nil
               (cons d nil))))))
      (if temp
        (cons (cons 'declare temp) nil)))))
memoize-use-attachment-warningfunction
(defun memoize-use-attachment-warning
  (fn at-fn)
  (when *memoize-use-attachment-warning-p*
    (let ((state *the-live-state*))
      (warning$ 'top-level
        "Attachment"
        "Although the function ~x0 is memoized, a result is not being ~
                 stored because ~@1.  Warnings such as this one, about not ~
                 storing results, will remain off for all functions for the ~
                 remainder of the session unless the variable ~x2 is set to a ~
                 non-nil value in raw Lisp."
        fn
        (mv-let (lookup-p at-fn)
          (if (consp at-fn)
            (assert$ (eq (car at-fn) :lookup) (mv t (cdr at-fn)))
            (mv nil at-fn))
          (cond (lookup-p (msg "a stored result was used from a call of ~
                                     memoized function ~x0, which may have ~
                                     been computed using attachments"
                at-fn))
            ((eq at-fn :|{APPLY$-OR-BADGE}-USERFN|) (msg "one of the functions ~v0, which depend ~
                                     on warrants for the result, was called ~
                                     during evaluation of a call of ~x1"
                '(apply$-userfn badge-userfn)
                fn))
            (t (msg "an attachment to function ~x0 was used ~
                                     during evaluation of one of its calls"
                at-fn))))
        '*memoize-use-attachment-warning-p*))
    (setq *memoize-use-attachment-warning-p* nil)))
other
(defun-one-output memoize-fn-suffix
  (str sym)
  (check-type str string)
  (check-type sym symbol)
  (let ((spkn (package-name (symbol-package sym))) (sn (symbol-name sym)))
    (format nil "~s,~s,~s" str spkn sn)))
mf-indexmacro
(defmacro mf-index
  (x &optional known-not-rational)
  (assert (symbolp x))
  `(cond ,@(UNLESS KNOWN-NOT-RATIONAL `(((TYPEP ,X 'FIXNUM) ,X)))))
other
(defun-one-output mis-ordered-commutative-args
  (x y)
  (cond ((eql x y) nil)
    (t (let ((idx (mf-index x)))
        (declare (type (or null fixnum) idx))
        (cond (idx (let ((idy (mf-index y)))
              (declare (type (or null fixnum) idy))
              (cond (idy (< (the fixnum idy) (the fixnum idx)))
                ((rationalp y) (< y (the fixnum idx))))))
          ((rationalp x) (let ((idy (mf-index y)))
              (declare (type (or null fixnum) idy))
              (cond (idy (< (the fixnum idy) x)) ((rationalp y) (< y x)))))
          ((or (rationalp y) (mf-index y t))))))))
memoize-look-up-deffunction
(defun memoize-look-up-def
  (fn cl-defun inline wrld &key quiet-p)
  (cond ((eq cl-defun :default) (cond ((null inline) nil)
        ((not (fboundp fn)) (error "MEMOIZE-LOOK-UP-DEF: ** ~a is undefined." fn))
        ((let ((def (cltl-def-from-name fn wrld)))
           (cond (def (assert (eq (car def) 'defun)) (cdr def)))))
        (t (memoize-look-up-def-raw fn quiet-p))))
    ((eq (car cl-defun) 'defun) (cdr cl-defun))
    (t cl-defun)))
other
(defg *memoize-timing-bugs* 0)
fix-ticksmacro
(defmacro fix-ticks
  (ticks ctx)
  `(let ((ticks ,TICKS) (ctx ,CTX))
    (declare (type mfixnum ticks))
    (the-mfixnum (cond ((and (<= 0 (the-mfixnum ticks))
           (< (the-mfixnum ticks) (the-mfixnum *10-days*))) (the-mfixnum ticks))
        (t (incf *memoize-timing-bugs*)
          (when (<= *memoize-timing-bugs* 10)
            (format t
              "Ignoring time increment of ~a sec for ~a~%"
              (/ ticks *float-ticks/second*)
              ctx)
            (when (eql *memoize-timing-bugs* 10)
              (format t
                "Timing is very dubious.  Suppressing further messages.~%")))
          0)))))
other
(defun-one-output memoizedp-raw
  (fn)
  (and (symbolp fn)
    (values (mf-gethash fn *memoize-info-ht*))))
mf-make-symbolmacro
(defmacro mf-make-symbol
  (&rest r)
  `(our-syntax (intern (format nil ,@R) *acl2-package*)))
memoize-fn-initfunction
(defun memoize-fn-init
  (fn inline wrld &aux (state *the-live-state*))
  (with-global-memoize-lock (unless (symbolp fn)
      (error "Memoize-fn: ~s is not a symbol." fn))
    (maybe-untrace! fn)
    (unless *memoize-init-done*
      (error "Memoize-fn:  *MEMOIZE-INIT-DONE* is still nil."))
    (unless (fboundp fn)
      (error "Memoize-fn: ~s is not fboundp." fn))
    (when (or (macro-function fn)
        (special-operator-p fn)
        (and (fboundp 'compiler-macro-function)
          (compiler-macro-function fn)))
      (error "Memoize-fn: ~s is a macro or a special operator or has a ~
             compiler macro."
        fn))
    (when (never-memoize-p fn)
      (error "Memoize-fn: ~s must never be memoized" fn))
    (when (and inline
        (or (member-eq fn (f-get-global 'logic-fns-with-raw-code state))
          (member-eq fn
            (f-get-global 'program-fns-with-raw-code state))))
      (error "Memoize-fn: ~s must never be memoized with :inline t,~%~
             because it belongs to the list stored in state global~%~
             variable ~s and thus runs code different~%~
             than that stored in the ACL2 logical world, as is typically~%~
             used when inserting inlined code for memoization."
        fn
        (if (member-eq fn (f-get-global 'logic-fns-with-raw-code state))
          'logic-fns-with-raw-code
          'program-fns-with-raw-code)))
    (when (memoizedp-raw fn)
      (observation 'memoize
        "~s0 is currently memoized. We will first unmemoize it, ~
                   then memoize it again."
        fn)
      (unmemoize-fn fn))
    (when (member fn (eval '(trace)))
      (observation 'memoize
        "Untracing ~s before memoizing it."
        fn)
      (eval `(untrace ,FN)))
    (when (and (fboundp 'old-trace) (member fn (eval '(old-trace))))
      (observation 'memoize
        "Old-untracing ~s before memoizing it."
        fn)
      (eval `(old-untrace ,FN)))
    (when (getpropc fn 'constrainedp nil wrld)
      (error "Memoize-fn: ~s is constrained; you may instead wish to memoize a ~
             caller or to memoize its attachment (see :DOC defattach)."
        fn))))
memoize-fn-init-2function
(defun memoize-fn-init-2
  (fn formals condition stobjs-in stobjs-out)
  (unless (and (symbol-listp formals)
      (no-duplicatesp formals)
      (loop for
        x
        in
        formals
        never
        (constantp x)))
    (error "Memoize-fn: FORMALS, ~a, must be a true list of distinct, ~
            nonconstant symbols."
      formals))
  (when (intersection lambda-list-keywords formals)
    (error "Memoize-fn: FORMALS, ~a, may not intersect LAMBDA-LIST-KEYWORDS."
      formals))
  (when (and condition
      (or (member 'state stobjs-in) (member 'state stobjs-out)))
    (error "Memoize-fn:  ~s uses STATE." fn)))
memoize-fn-inner-bodyfunction
(defun memoize-fn-inner-body
  (fn condition
    body
    fn-col-base
    tablename
    localtablename
    ponstablename
    localponstablename
    memo-table-init-size
    formals
    specials
    stobjs-out
    number-of-args
    commutative
    aokp
    prog1-fn)
  (let ((mf-record-mht (and *record-mht-calls*
         `((safe-incf (aref ,*MF-MA*
              ,(MA-INDEX-FROM-COL-BASE FN-COL-BASE *MA-MHT-INDEX*))
            1)))) (mf-record-hit (and *record-hits*
          condition
          `((safe-incf (aref ,*MF-MA*
               ,(MA-INDEX-FROM-COL-BASE FN-COL-BASE *MA-HITS-INDEX*))
             1)))))
    `(cond ,@(AND (NOT (MEMBER-EQUAL CONDITION '('T T)))
       `(((NOT ,CONDITION) ,@(AND *CONDITION-NIL-AS-HIT* MF-RECORD-HIT) ,BODY)))
      ,@(AND CONDITION
       `((T
          (LET (,*MF-ANS* ,*MF-ARGS* ,*MF-ANS-P*)
            (DECLARE (IGNORABLE ,*MF-ANS* ,*MF-ARGS* ,*MF-ANS-P*))
            (WHEN (NULL ,TABLENAME)
              ,@MF-RECORD-MHT
              (SETQ ,TABLENAME
                      (MAKE-INITIAL-MEMOIZE-HASH-TABLE ',FN
                                                       ,MEMO-TABLE-INIT-SIZE)))
            (SETQ ,LOCALTABLENAME ,TABLENAME)
            ,@(AND (> NUMBER-OF-ARGS 1)
                   `((WHEN (NULL ,PONSTABLENAME)
                       (SETQ ,PONSTABLENAME
                               (MAKE-INITIAL-MEMOIZE-PONS-TABLE ',FN
                                                                ,MEMO-TABLE-INIT-SIZE)))
                     (SETQ ,LOCALPONSTABLENAME ,PONSTABLENAME)))
            (SETQ ,*MF-ARGS*
                    ,(COND
                      (COMMUTATIVE
                       `(COND
                         ((MIS-ORDERED-COMMUTATIVE-ARGS ,(CAR FORMALS)
                                                        ,(CADR FORMALS))
                          (PIST* ,LOCALPONSTABLENAME ,(CADR FORMALS)
                                 ,(CAR FORMALS) ,@SPECIALS))
                         (T
                          (PIST* ,LOCALPONSTABLENAME ,(CAR FORMALS)
                                 ,(CADR FORMALS) ,@SPECIALS))))
                      (T `(PIST* ,LOCALPONSTABLENAME ,@FORMALS ,@SPECIALS))))
            (MULTIPLE-VALUE-SETQ (,*MF-ANS* ,*MF-ANS-P*)
              ,(LET ((GETHASH-FORM `(MF-GETHASH ,*MF-ARGS* ,LOCALTABLENAME)))
                 (COND
                  (AOKP `(COND (*AOKP* ,GETHASH-FORM) (T (VALUES NIL NIL))))
                  (T GETHASH-FORM))))
            (COND
             (,*MF-ANS-P*
              ,@(AND AOKP `((UPDATE-ATTACHED-FN-CALLED ',(CONS :LOOKUP FN))))
              ,@MF-RECORD-HIT
              ,@(COND ((NULL (CDR STOBJS-OUT)) `(,*MF-ANS*))
                      (T
                       (LET ((LEN-1 (1- (LENGTH STOBJS-OUT))))
                         `(,(CONS 'MV
                                  (NCONC
                                   (LOOP FOR I FIXNUM BELOW LEN-1
                                         COLLECT `(POP ,*MF-ANS*))
                                   (LIST *MF-ANS*))))))))
             (T
              ,(LET* ((VARS
                       (LOOP FOR I FIXNUM BELOW (IF (CDR STOBJS-OUT)
                                                    (LENGTH STOBJS-OUT)
                                                    1)
                             COLLECT (MF-MAKE-SYMBOL "O~a" I))))
                 (COND
                  (AOKP
                   `(MV?-LET ,VARS ,BODY
                             (PROGN
                              (MF-SETHASH ,*MF-ARGS* (LIST* ,@VARS)
                                          ,LOCALTABLENAME)
                              (MV? ,@VARS))))
                  (T
                   `(LET (,*ATTACHED-FN-TEMP*)
                      (MV?-LET ,VARS
                               (LET ((*AOKP* (AND *AOKP* T))
                                     (SAVED-WARRANT-REQS *WARRANT-REQS*))
                                 (WHEN (CONSP SAVED-WARRANT-REQS)
                                   (SETQ *WARRANT-REQS*
                                           (AND SAVED-WARRANT-REQS T)))
                                 (,PROG1-FN ,BODY
                                  (COND
                                   ((NOT (MEMBER *AOKP* '(T NIL) :TEST #'EQ))
                                    (SETQ ,*ATTACHED-FN-TEMP* *AOKP*))
                                   ((CONSP *WARRANT-REQS*)
                                    (SETQ ,*ATTACHED-FN-TEMP*
                                            :{APPLY$-OR-BADGE}-USERFN)
                                    (WHEN (CONSP SAVED-WARRANT-REQS)
                                      (SETQ *WARRANT-REQS*
                                              (UNION-EQ *WARRANT-REQS*
                                                        SAVED-WARRANT-REQS))))
                                   ((EQ SAVED-WARRANT-REQS T)
                                    (SETQ *WARRANT-REQS* T)))))
                               (PROGN
                                (COND
                                 (,*ATTACHED-FN-TEMP*
                                  (MEMOIZE-USE-ATTACHMENT-WARNING ',FN
                                                                  ,*ATTACHED-FN-TEMP*))
                                 (T
                                  (MF-SETHASH ,*MF-ARGS* (LIST* ,@VARS)
                                              ,LOCALTABLENAME)))
                                (WHEN ,*ATTACHED-FN-TEMP*
                                  (ASSERT
                                   (OR *AOKP*
                                       (EQ ,*ATTACHED-FN-TEMP*
                                           :{APPLY$-OR-BADGE}-USERFN)))
                                  (UPDATE-ATTACHED-FN-CALLED
                                   ,*ATTACHED-FN-TEMP*))
                                (MV? ,@VARS))))))))))))))))
memoize-fn-outer-bodyfunction
(defun memoize-fn-outer-body
  (inner-body fn fn-col-base start-ticks forget prog1-fn)
  `(let (,@(AND *RECORD-BYTES* `((,*MF-START-BYTES* (HEAP-BYTES-ALLOCATED)))) ,@(AND *RECORD-PONS-CALLS* `((,*MF-START-PONS* *PONS-CALL-COUNTER*)))
      (,START-TICKS ,(IF *RECORD-TIME*
     '(INTERNAL-REAL-TICKS)
     '0)))
    (declare (ignorable ,@(AND *RECORD-BYTES* `(,*MF-START-BYTES*))
        ,@(AND *RECORD-PONS-CALLS* `(,*MF-START-PONS*)))
      (type mfixnum
        ,START-TICKS
        ,@(AND *RECORD-PONS-CALLS* `(,*MF-START-PONS*))
        ,@(AND *RECORD-BYTES* `(,*MF-START-BYTES*))))
    (,(COND
  ((OR *RECORD-PONS-CALLS* *RECORD-BYTES* *RECORD-TIME* FORGET)
   (IF (F-GET-GLOBAL 'PROTECT-MEMOIZE-STATISTICS *THE-LIVE-STATE*)
       'UNWIND-PROTECT-DISABLE-INTERRUPTS-DURING-CLEANUP
       PROG1-FN))
  (T 'PROGN)) ,(COND
  ((OR *RECORD-BYTES* *RECORD-CALLS* *RECORD-HITS* *RECORD-MHT-CALLS*
       *RECORD-PONS-CALLS* *RECORD-TIME*)
   `(LET ((*CALLER* ,FN-COL-BASE))
      ,INNER-BODY))
  (T INNER-BODY))
      ,@(AND *RECORD-PONS-CALLS*
       `((SAFE-INCF
          (AREF ,*MF-MA* ,(MA-INDEX-FROM-COL-BASE FN-COL-BASE *MA-PONS-INDEX*))
          (THE-MFIXNUM (- *PONS-CALL-COUNTER* ,*MF-START-PONS*)))))
      ,@(AND *RECORD-BYTES*
       `((SAFE-INCF
          (AREF ,*MF-MA*
                ,(MA-INDEX-FROM-COL-BASE FN-COL-BASE *MA-BYTES-INDEX*))
          (THE-MFIXNUM (- (HEAP-BYTES-ALLOCATED) ,*MF-START-BYTES*)))))
      ,@(AND *RECORD-TIME*
       `((SAFE-INCF
          (THE MFIXNUM (AREF ,*MF-MA* (THE-MFIXNUM (1+ ,*MF-COUNT-LOC*))))
          (THE-MFIXNUM
           (FIX-TICKS (THE-MFIXNUM (- (INTERNAL-REAL-TICKS) ,START-TICKS))
                      ',FN)))))
      ,@(AND FORGET `((CLEAR-MEMOIZE-TABLE ',FN))))))
memoize-fn-deffunction
(defun memoize-fn-def
  (inner-body outer-body
    fn
    formals
    specials
    dcls
    fnn
    start-ticks
    localtablename
    localponstablename)
  `(defun ,FN
    ,FORMALS
    ,@DCLS
    (declare (ignorable ,@FORMALS ,@SPECIALS))
    (with-global-memoize-lock-static (let* ((,*MF-COUNT-LOC* ,(IF (OR *RECORD-CALLS* *RECORD-TIME*)
     `(THE-MFIXNUM (+ *CALLER* ,(* 2 FNN)))
     0)) (,*MF-MA* *memoize-call-array*)
          ,LOCALTABLENAME
          ,LOCALPONSTABLENAME)
        (declare (type mfixnum ,*MF-COUNT-LOC*)
          (ignorable ,*MF-COUNT-LOC*
            ,*MF-MA*
            ,LOCALPONSTABLENAME
            ,LOCALTABLENAME)
          (type (simple-array mfixnum (*)) ,*MF-MA*))
        ,@(AND *RECORD-CALLS* `((SAFE-INCF (AREF ,*MF-MA* ,*MF-COUNT-LOC*) 1)))
        (if (eql -1 ,START-TICKS)
          ,OUTER-BODY
          ,INNER-BODY)))))
other
(defun-one-output memoize-eval-compile
  (def old-fn)
  (declare (ignore old-fn))
  (unless (and (consp def)
      (eq 'defun (car def))
      (consp (cdr def))
      (symbolp (cadr def)))
    (error "MEMOIZE-EVAL-COMPILE:  Bad input:~%~s." def))
  (compile (eval def))
  nil)
memoize-fn-formalsfunction
(defun memoize-fn-formals
  (fn wrld inline &key (cl-defun :default cl-defun-p))
  (let ((formals (getpropc fn 'formals t wrld)))
    (if (eq formals t)
      (let ((cl-defun (if cl-defun-p
             cl-defun
             (memoize-look-up-def fn cl-defun inline wrld :quiet-p t))))
        (if (consp cl-defun)
          (cadr cl-defun)
          (let ((n (mf-len-inputs fn)))
            (if n
              (loop for
                i
                fixnum
                below
                n
                collect
                (mf-make-symbol "X~a" i))
              t))))
      formals)))
cltl-def-memoize-invokefunction
(defun cltl-def-memoize-invoke
  (fn-def old-fn invoke)
  (let ((gsym (gensym)) (fn (car fn-def))
      (formals (cadr fn-def))
      (decls (butlast (cddr fn-def) 1)))
    (eval `(defvar ,GSYM nil))
    `(,FN ,FORMALS
      ,@DECLS
      (if ,GSYM
        (funcall ,OLD-FN ,@FORMALS)
        (let ((,GSYM t))
          (,INVOKE ,@FORMALS))))))
memoize-fnfunction
(defun memoize-fn
  (fn &key
    (condition t)
    (inline t)
    (cl-defun :default)
    (formals :default)
    (stobjs-in :default)
    (specials nil)
    (commutative nil)
    (stobjs-out :default)
    (forget nil)
    (memo-table-init-size *mht-default-size*)
    (aokp nil)
    (invoke nil)
    &aux
    (wrld (w *the-live-state*))
    (memoize-fn-signature-error "Memoize-fn: could not determine a signature for ~a.~%~
  To assert the signature of ~:*~a, use (mf-note-arity '~:*~a nargs nvals),~%~
  for example, (mf-note-arity '~:*~a 3 1).)  If there are stobjs arguments~%~
  then do not use that mechanism; instead, pass suitable arguments to~%~
  memoize-fn."))
  "The documentation for MEMOIZE-FN is very incomplete.  One may invoke
  (MEMOIZE-FN fn) on the name of a Common Lisp function FN from outside the
  ACL2 loop to get results of possible interest in terms of memoization
  activity and profiling information.  MEMOIZE-FN already has a dozen
  parameters.

  MEMOIZE-FN replaces the SYMBOL-FUNCTION for the symbol FN with 'enhanced'
  raw Common Lisp code that, supposedly, does not affect the value returned by
  FN but may make some notes and may even obtain some return values by
  remembering them from a previous call.

  If the CONDITION parameter is not NIL or 'NIL, then whenever FN is called,
  and there is not as yet any value remembered for a call of FN on the given
  arguments, then if the evaluation of the CONDITION parameter (where the
  formals of FN are bound to its actuals) is not NIL or 'NIL, the values that
  are computed for FN on the given arguments will be saved under the given
  arguments.

  If the INLINE parameter is T, then when MEMOIZE-FN creates a new body for FN,
  we place the old body of FN within the new body, i.e., 'in line'.  However,
  if the INLINE parameter is NIL, then we place code that calls the existing
  SYMBOL-FUNCTION for FN within the new body.  One might well argue that our
  parity for the INLINE parameter to MEMOIZE-fn is backwards, but we don't
  think so.

  One may lie to MEMOIZE-FN to force the memoization of a function that has
  ACL2's state as an explicit parameter by using fraudulent FORMALS, STOBJS-IN,
  and STOBJS-OUT parameters to MEMOIZE-FN.

  If the COMMUTATIVE parameter is not NIL, then the two arguments may be
  swapped before further processing.  We hope/presume that ACL2 will have been
  used first to prove that commutativity.

  If the CL-DEFUN parameter is not NIL, we pretend that the current body of FN
  is that parameter, and similarly for FORMALS, STOBJS-IN, and STOBJS-OUT.

  If FN is a raw Common Lisp function and not an ACL2-approved function, it may
  make reference to a variable, say S, that has a SPECIAL binding, in which
  case one needs to consider what in the world the meaning is for memoizing
  such a function at all.  If S is a member of the SPECIALS parameter, then it
  is assumed that FN does not alter but only refers to S.  MEMOIZE-FN acts as
  though FN had S as an extra argument for purposes of memoization.

  If the FORGET parameter is not NIL, the pons and memo tables of FN are
  discarded at the end of every outermost call of FN."
  (when (equal condition *nil*) (setq condition nil))
  (with-global-memoize-lock (with-warnings-suppressed (memoize-fn-init fn inline wrld)
      (let* ((cl-defun0 (memoize-look-up-def fn cl-defun inline wrld)) (old-fn (symbol-function fn))
          (cl-defun (if invoke
              (cltl-def-memoize-invoke cl-defun0 old-fn invoke)
              cl-defun0))
          (formals (cond ((eq formals :default) (let ((formals (memoize-fn-formals fn wrld inline :cl-defun cl-defun)))
                  (if (eq formals t)
                    (error memoize-fn-signature-error fn)
                    formals)))
              (t formals)))
          (stobjs-in (if (eq stobjs-in :default)
              (let ((s (getpropc fn 'stobjs-in t wrld)))
                (if (eq s t)
                  (make-list (len formals))
                  s))
              stobjs-in))
          (stobjs-out (if (eq stobjs-out :default)
              (let ((s (getpropc fn 'stobjs-out t wrld)))
                (if (eq s t)
                  (let ((n (mf-len-outputs fn)))
                    (cond (n (make-list n))
                      ((null condition) (list nil))
                      (t (error memoize-fn-signature-error fn))))
                  s))
              stobjs-out)))
        (memoize-fn-init-2 fn
          formals
          condition
          stobjs-in
          stobjs-out)
        (mf-sethash fn
          (cons (length stobjs-in) (length stobjs-out))
          *number-of-arguments-and-values-ht*)
        (let* ((fnn (symbol-to-fixnum-create fn)) (fn-col-base (ma-index fnn))
            (body (progn (assert old-fn)
                (cond (invoke (car (last cl-defun)))
                  (inline (assert (consp cl-defun)) (car (last cl-defun)))
                  (t `(funcall ,OLD-FN ,@FORMALS)))))
            (dcls (mf-dcls (cddr (butlast cl-defun))))
            (start-ticks (let ((v (hons-gentemp (memoize-fn-suffix "START-TICKS-" fn))))
                (eval `(prog1 (defparameter ,V -1) (declaim (type mfixnum ,V))))))
            (tablename (eval `(defg ,(HONS-GENTEMP (MEMOIZE-FN-SUFFIX "MEMOIZE-HT-FOR-" FN))
                  nil)))
            (ponstablename (eval `(defg ,(HONS-GENTEMP (MEMOIZE-FN-SUFFIX "PONS-HT-FOR-" FN))
                  nil)))
            (localtablename (make-symbol "TABLENAME"))
            (localponstablename (make-symbol "PONSTABLENAME"))
            (sts (and condition
                (remove-duplicates-eq (loop for
                    st
                    in
                    (union stobjs-in stobjs-out)
                    when
                    (and st (not (eq st :df)))
                    collect
                    (assert$ (not (eq st 'state))
                      (st-lst (congruent-stobj-rep (or (concrete-stobj st wrld) st) wrld)))))))
            (number-of-args (+ (len formals) (len specials)))
            (prog1-fn (if (cdr stobjs-out)
                'multiple-value-prog1
                'prog1))
            (inner-body (memoize-fn-inner-body fn
                condition
                body
                fn-col-base
                tablename
                localtablename
                ponstablename
                localponstablename
                memo-table-init-size
                formals
                specials
                stobjs-out
                number-of-args
                commutative
                aokp
                prog1-fn))
            (outer-body (memoize-fn-outer-body inner-body
                fn
                fn-col-base
                start-ticks
                forget
                prog1-fn))
            (def (memoize-fn-def inner-body
                outer-body
                fn
                formals
                specials
                dcls
                fnn
                start-ticks
                localtablename
                localponstablename))
            (success nil))
          (unwind-protect (progn (let ((ma *memoize-call-array*))
                (declare (type (simple-array mfixnum (*)) ma))
                (loop for
                  i
                  of-type
                  mfixnum
                  from
                  fn-col-base
                  below
                  (ma-index-from-col-base fn-col-base *2max-memoize-fns*)
                  unless
                  (eql (aref ma i) 0)
                  do
                  (setf (aref ma i) 0)))
              (memoize-eval-compile def old-fn)
              (mf-sethash fn
                (make memoize-info-ht-entry
                  :ext-anc-attachments (and aokp (ext-ancestors-attachments fn wrld))
                  :start-ticks start-ticks
                  :num fnn
                  :tablename tablename
                  :ponstablename ponstablename
                  :condition condition
                  :inline inline
                  :memoized-fn (symbol-function fn)
                  :old-fn old-fn
                  :fn fn
                  :sts sts
                  :cl-defun cl-defun
                  :formals formals
                  :commutative commutative
                  :specials specials
                  :stobjs-in stobjs-in
                  :stobjs-out stobjs-out
                  :record-bytes *record-bytes*
                  :record-calls *record-calls*
                  :record-hits *record-hits*
                  :record-mht-calls *record-mht-calls*
                  :record-pons-calls *record-pons-calls*
                  :record-time *record-time*
                  :forget forget
                  :memo-table-init-size memo-table-init-size
                  :aokp aokp
                  :invoke invoke)
                *memoize-info-ht*)
              (mf-sethash fnn fn *memoize-info-ht*)
              (and condition
                (loop for
                  s
                  in
                  sts
                  do
                  (push tablename (symbol-value (the symbol s)))))
              (setq success t))
            (unless success
              (without-interrupts (setf (symbol-function fn) old-fn)
                (remhash fn *memoize-info-ht*)
                (remhash fnn *memoize-info-ht*)
                (and condition
                  (loop for
                    s
                    in
                    sts
                    when
                    (eq tablename (car (symbol-value (the symbol s))))
                    do
                    (pop (symbol-value (the symbol s)))))
                (setq fn nil)
                (error "Memoize-fn:  Failed to memoize ~s." fn))))))))
  fn)
other
(defun-one-output unmemoize-fn
  (fn)
  (with-global-memoize-lock (maybe-untrace! fn)
    (let ((rec (memoizedp-raw fn)))
      (unless rec (error "Unmemoize-fn: ~s is not memoized." fn))
      (let* ((num (the-mfixnum (access memoize-info-ht-entry rec :num))) (tablename (access memoize-info-ht-entry rec :tablename))
          (ponstablename (access memoize-info-ht-entry rec :ponstablename))
          (sts (access memoize-info-ht-entry rec :sts))
          (col-base (ma-index num))
          (saved-table (symbol-value (the symbol tablename)))
          (saved-ponstable (symbol-value (the symbol ponstablename)))
          (saved-fn-entry (mf-gethash fn *memoize-info-ht*))
          (saved-num-entry (mf-gethash num *memoize-info-ht*))
          (ma *memoize-call-array*)
          (success nil))
        (declare (type mfixnum num col-base)
          (type (simple-array mfixnum (*)) ma))
        (unwind-protect (progn (format nil "unmemoizing ~s" fn)
            (let nil
              (let ((old-fn (access memoize-info-ht-entry rec :old-fn)))
                (assert old-fn)
                (setf (symbol-function (the symbol fn)) old-fn)))
            (loop for
              i
              of-type
              mfixnum
              from
              col-base
              below
              (ma-index-from-col-base col-base *2max-memoize-fns*)
              unless
              (eql (aref ma i) 0)
              do
              (setf (aref ma i) 0))
            (remhash fn *memoize-info-ht*)
            (remhash num *memoize-info-ht*)
            (setf (symbol-value (the symbol tablename)) nil)
            (setf (symbol-value (the symbol ponstablename)) nil)
            (loop for
              s
              in
              sts
              do
              (when (boundp s)
                (setf (symbol-value (the symbol s))
                  (remove tablename (symbol-value (the symbol s))))))
            (setq success t))
          (unless success
            (without-interrupts (setf (symbol-value (the symbol tablename)) saved-table)
              (setf (symbol-value (the symbol ponstablename))
                saved-ponstable)
              (mf-sethash fn saved-fn-entry *memoize-info-ht*)
              (mf-sethash num saved-num-entry *memoize-info-ht*)
              (loop for
                s
                in
                sts
                do
                (when (boundp s)
                  (push tablename (symbol-value (the symbol s)))))))))))
  fn)
other
(defun-one-output maybe-unmemoize
  (fn)
  (with-global-memoize-lock (when (and (memoizedp-raw fn)
        (not (cdr (assoc-eq fn
              (table-alist 'memoize-table (w *the-live-state*))))))
      (unmemoize-fn fn))))
other
(defun-one-output memoized-functions
  nil
  (with-global-memoize-lock (let (ans)
      (mf-maphash (lambda (fn info)
          (declare (ignore info))
          (when (symbolp fn) (push fn ans)))
        *memoize-info-ht*)
      ans)))
other
(defun-one-output length-memoized-functions
  nil
  (with-global-memoize-lock (values (floor (1- (mf-hash-table-count *memoize-info-ht*)) 2))))
other
(defun-one-output unmemoize-all
  nil
  (loop for
    x
    in
    (memoized-functions)
    do
    (unmemoize-fn x)))
other
(defun-one-output memoize-info
  (k)
  (with-global-memoize-lock (let ((v (mf-gethash k *memoize-info-ht*)))
      (and v
        (list (list (access memoize-info-ht-entry v :fn)
            :condition (access memoize-info-ht-entry v :condition)
            :inline (access memoize-info-ht-entry v :inline)
            :cl-defun (access memoize-info-ht-entry v :cl-defun)
            :formals (access memoize-info-ht-entry v :formals)
            :stobjs-in (access memoize-info-ht-entry v :stobjs-in)
            :specials (access memoize-info-ht-entry v :specials)
            :commutative (access memoize-info-ht-entry v :commutative)
            :stobjs-out (access memoize-info-ht-entry v :stobjs-out)
            :forget (access memoize-info-ht-entry v :forget)
            :memo-table-init-size (access memoize-info-ht-entry v :memo-table-init-size)
            :aokp (access memoize-info-ht-entry v :aokp)
            :invoke (access memoize-info-ht-entry v :invoke))
          (list (access memoize-info-ht-entry v :record-bytes)
            (access memoize-info-ht-entry v :record-calls)
            (access memoize-info-ht-entry v :record-hits)
            (access memoize-info-ht-entry v :record-mht-calls)
            (access memoize-info-ht-entry v :record-pons-calls)
            (access memoize-info-ht-entry v :record-time)))))))
other
(defun-one-output rememoize-all
  (&optional light)
  (with-global-memoize-lock (cond (light (let ((new-memoize-info-ht (initial-memoize-info-ht)))
          (unwind-protect (progn (mf-maphash (lambda (k v) (setf (gethash k new-memoize-info-ht) v))
                *memoize-info-ht*)
              (setq *memoize-info-ht* new-memoize-info-ht))
            (when (not (eq *memoize-info-ht* new-memoize-info-ht))
              (cond ((eq light :done) (error "Fatal error in rememoize-all!~%Consider evaluating ~
                         ~s before continuing.~%"
                    '(unmemoize-all)))
                (t (format t "Error in rememoize-all; about to try again.~%")
                  (rememoize-all :done)))))))
      (t (let (lst)
          (mf-maphash (lambda (k v)
              (declare (ignore v))
              (when (symbolp k) (push (memoize-info k) lst)))
            *memoize-info-ht*)
          (loop for
            x
            in
            lst
            do
            (unmemoize-fn (caar x)))
          (setq *memoize-info-ht* (initial-memoize-info-ht))
          (gc$)
          (setq *max-symbol-to-fixnum* *initial-max-symbol-to-fixnum*)
          (loop for
            x
            in
            lst
            do
            (progv '(*record-bytes* *record-calls*
                *record-hits*
                *record-mht-calls*
                *record-pons-calls*
                *record-time*)
              (cadr x)
              (apply 'memoize-fn (car x)))))))))
profile-fnfunction
(defun profile-fn
  (fn &rest
    r
    &key
    (condition nil)
    (inline nil)
    &allow-other-keys)
  (apply (function memoize-fn)
    fn
    :condition condition
    :inline inline
    r))
other
(defun-one-output profiled-functions
  nil
  (with-global-memoize-lock (let (lst)
      (mf-maphash (lambda (k v)
          (when (and (symbolp k)
              (null (access memoize-info-ht-entry v :condition))
              (null (access memoize-info-ht-entry v :inline))
              (null (access memoize-info-ht-entry v :invoke)))
            (push k lst)))
        *memoize-info-ht*)
      lst)))
other
(defun-one-output unmemoize-profiled
  nil
  (loop for
    x
    in
    (profiled-functions)
    do
    (unmemoize-fn (car x))))
other
(defun-one-output coerce-index
  (x)
  (cond ((typep x 'fixnum) (assert (and (>= (the fixnum x) 0)
          (< (the fixnum x)
            (the fixnum (ash (length *memoize-call-array*) -1)))))
      x)
    (t (symbol-to-fixnum x))))
other
(defun-one-output mf-num-to-string
  (n)
  (check-type n number)
  (if (= n 0)
    (setq n 0))
  (cond ((typep n '(integer -99 999)) (format nil "~8d" n))
    ((or (< -1000 n -1/100) (< 1/100 n 1000)) (format nil "~8,2f" n))
    (t (format nil "~8,2e" n))))
mf-shortenfunction
(defun mf-shorten
  (x n)
  (cond ((and (stringp x) (<= (length x) n)) x)
    (t (let ((x (if (stringp x)
             (hons-copy x)
             x)))
        (cond ((mf-gethash x *mf-shorten-ht*))
          (t (let ((*print-pretty* nil) (*print-length* 10)
                (*print-level* 5)
                (*print-lines* 2))
              (let ((str (with-output-to-string (s)
                     (cond ((stringp x) (princ x s)) (t (prin1 x s))))))
                (mf-sethash x
                  (cond ((<= (length str) n) str)
                    (t (concatenate 'string (subseq str 0 (max 0 n)) "///")))
                  *mf-shorten-ht*)))))))))
other
(defun-one-output mf-print-alist
  (alist separation)
  (check-type separation (integer 0))
  (setq alist
    (loop for
      x
      in
      alist
      collect
      (progn (check-type x
          (cons (or string symbol)
            (cons (or string (integer 0)) null)))
        (list (mf-shorten (car x) *mf-print-alist-width*)
          (if (integerp (cadr x))
            (mf-num-to-string (cadr x))
            (cadr x))))))
  (let* ((max1 (loop for
         x
         in
         alist
         maximize
         (length (car x)))) (max2 (loop for
          x
          in
          alist
          maximize
          (length (cadr x))))
      (width (max (or *print-right-margin* *mf-print-right-margin*)
          (+ separation max1 max2))))
    (loop for
      x
      in
      alist
      do
      (fresh-line)
      (princ (car x))
      (loop for
        i
        below
        (- width (+ (length (car x)) (length (cadr x))))
        do
        (write-char #\ ))
      (princ (cadr x))))
  nil)
safe-incf-ponsmacro
(defmacro safe-incf-pons (x inc) `(safe-incf ,X ,INC))
other
(defun-one-output pons-summary
  nil
  (our-syntax (let ((sssub 0) (nponses 0) (nsubs 0) (nponstab 0))
      (declare (type mfixnum sssub nponses nsubs))
      (format t "Pons-summary:~%")
      (with-global-memoize-lock (mf-maphash (lambda (k v)
            (when (symbolp k)
              (let ((tab (symbol-value (access memoize-info-ht-entry v :ponstablename))))
                (when tab
                  (safe-incf-pons nponstab 1)
                  (mf-maphash (lambda (k v)
                      (declare (ignore k))
                      (cond ((not (listp v)) (safe-incf-pons sssub (mf-hash-table-size v))
                          (safe-incf-pons nponses (mf-hash-table-count v))
                          (safe-incf-pons nsubs 1))
                        (t (safe-incf-pons nponses (length v)))))
                    tab)))))
          *memoize-info-ht*))
      (mf-print-alist `((" Pons hits/calls" ,(LET* ((C *PONS-CALL-COUNTER*) (M *PONS-MISSES-COUNTER*) (H (- C M)))
   (FORMAT NIL "~,1e / ~,1e = ~,2f" H C
           (IF (EQL C 0)
               0
               (/ H C))))) (" Number of pons tables" ,(MF-NUM-TO-STRING NPONSTAB))
          (" Number of pons sub tables" ,(MF-NUM-TO-STRING NSUBS))
          (" Sum of pons sub table sizes" ,(MF-NUM-TO-STRING SSSUB))
          (" Number of ponses" ,(MF-NUM-TO-STRING NPONSES)))
        5)
      (format t ")")
      (force-output *standard-output*)
      nil)))
memoized-valuesfunction
(defun memoized-values
  (&optional (fn (memoized-functions)))
  (with-global-memoize-lock (cond ((listp fn) (mapc (function memoized-values) fn))
      ((not (memoizedp-raw fn)) (format t "~%; Memoized-values:  ~s is not memoized." fn))
      (t (let ((tb (symbol-value (access memoize-info-ht-entry
                 (mf-gethash fn *memoize-info-ht*)
                 :tablename))))
          (cond ((and tb (not (eql 0 (mf-hash-table-count tb)))) (format t "~%; Memoized values for ~s." fn)
              (mf-maphash (lambda (key v) (format t "~%~s~%=>~%~s" key v))
                tb)))))))
  (force-output *standard-output*)
  nil)
print-call-stackfunction
(defun print-call-stack
  nil
  (float-ticks/second-init)
  (our-syntax (let (lst (ticks (internal-real-ticks)) (*print-case* :downcase))
      (with-global-memoize-lock (mf-maphash (lambda (k v)
            (when (symbolp k)
              (let ((x (symbol-value (the symbol (access memoize-info-ht-entry v :start-ticks)))))
                (declare (type mfixnum x))
                (when (> x 0) (push (cons k x) lst)))))
          *memoize-info-ht*))
      (setq lst (sort lst (function <) :key (function cdr)))
      (setq lst
        (loop for
          pair
          in
          lst
          collect
          (list (car pair)
            (mf-num-to-string (/ (the-mfixnum (- ticks (cdr pair))) *float-ticks/second*)))))
      (when lst
        (terpri *standard-output*)
        (mf-print-alist (cons '("Stack of monitored function calls." "Time since outermost call.")
            lst)
          5))))
  (force-output *standard-output*)
  nil)
other
(defun-one-output pons-calls
  (x)
  (setq x (coerce-index x))
  (aref *memoize-call-array* (ma-index x *ma-pons-index*)))
other
(defun-one-output bytes-allocated
  (x)
  (setq x (coerce-index x))
  (aref *memoize-call-array* (ma-index x *ma-bytes-index*)))
other
(defun-one-output number-of-hits
  (x)
  (setq x (coerce-index x))
  (aref *memoize-call-array* (ma-index x *ma-hits-index*)))
other
(defun-one-output number-of-memoized-entries
  (x)
  (setq x (coerce-index x))
  (with-global-memoize-lock (let ((h (mf-gethash x *memoize-info-ht*)))
      (unless h (error "~a is not memoized." x))
      (let* ((sym (access memoize-info-ht-entry h :tablename)) (val (symbol-value sym)))
        (if (hash-table-p val)
          (mf-hash-table-count val)
          0)))))
other
(defun-one-output number-of-mht-calls
  (x)
  (setq x (coerce-index x))
  (aref *memoize-call-array* (ma-index x *ma-mht-index*)))
other
(defun-one-output total-time
  (x)
  (setq x (coerce-index x))
  (float-ticks/second-init)
  (/ (aref *memoize-call-array* (ma-index-ticks x))
    *float-ticks/second*))
other
(defun-one-output number-of-calls
  (x)
  (setq x (coerce-index x))
  (aref *memoize-call-array* (ma-index-calls x)))
other
(defun-one-output time-for-non-hits/call
  (x)
  (setq x (coerce-index x))
  (let ((n (- (number-of-calls x) (number-of-hits x))))
    (if (zerop n)
      0
      (/ (total-time x) n))))
other
(defun-one-output time/call
  (x)
  (setq x (coerce-index x))
  (let ((n (number-of-calls x)))
    (if (zerop n)
      0
      (/ (total-time x) n))))
other
(defun-one-output hits/calls
  (x)
  (setq x (coerce-index x))
  (let ((n (number-of-calls x)))
    (if (zerop n)
      0
      (/ (number-of-hits x) (float n)))))
other
(defun-one-output bytes-allocated/call
  (x)
  (setq x (coerce-index x))
  (let ((n (number-of-calls x)))
    (if (zerop n)
      0
      (/ (bytes-allocated x) n))))
char-list-fractionfunction
(defun char-list-fraction
  (l)
  (if (atom l)
    0
    (+ (char-code (car l)) (/ (char-list-fraction (cdr l)) 256))))
symbol-name-orderfunction
(defun symbol-name-order
  (s)
  (unless (symbolp s) (setq s (fixnum-to-symbol s)))
  (- (char-list-fraction (coerce (symbol-name s) 'list))))
other
(defun-one-output execution-order
  (s)
  (unless (symbolp s) (setq s (fixnum-to-symbol s)))
  (the-mfixnum (symbol-value (the symbol
        (access memoize-info-ht-entry
          (mf-gethash s *memoize-info-ht*)
          :start-ticks)))))
compute-calls-and-timesfunction
(defun compute-calls-and-times
  nil
  (with-global-memoize-lock (let ((ma *memoize-call-array*) (2m *2max-memoize-fns*)
        (ca *callers-array*)
        (n (the fixnum (1+ *max-symbol-to-fixnum*))))
      (declare (type (simple-array mfixnum (*)) ma)
        (type (simple-array t (*)) ca)
        (type fixnum 2m n))
      (cond ((eql (length ca) n) (loop for
            i
            fixnum
            below
            n
            do
            (setf (aref ca i) nil)))
        (t (setq *callers-array* (make-array n :initial-element nil))
          (setq ca *callers-array*)))
      (loop for
        i
        fixnum
        below
        (ma-index-calls n 0 2m)
        do
        (setf (aref ma i) 0))
      (loop for
        i
        fixnum
        from
        *initial-max-symbol-to-fixnum*
        to
        *max-symbol-to-fixnum*
        do
        (let ((col-base (ma-index i 0 2m)))
          (declare (type mfixnum col-base))
          (loop for
            j
            fixnum
            from
            *initial-max-symbol-to-fixnum*
            to
            *max-symbol-to-fixnum*
            do
            (let* ((calls-row (ma-index-calls j)) (index (ma-index-from-col-base col-base calls-row))
                (calls (the-mfixnum (aref ma index))))
              (declare (type mfixnum calls-row index calls))
              (when (> calls 0)
                (let* ((ticks-index (the-mfixnum (1+ index))) (ticks (aref ma ticks-index))
                    (ticks-row (the-mfixnum (1+ calls-row))))
                  (declare (type mfixnum ticks-index ticks ticks-row))
                  (safe-incf (aref ma calls-row)
                    calls
                    compute-calls-and-times)
                  (safe-incf (aref ma ticks-row)
                    ticks
                    compute-calls-and-times)
                  (push i (aref ca j)))))))))))
other
(defun-one-output print-not-called
  nil
  (with-global-memoize-lock (compute-calls-and-times)
    (let ((ans nil))
      (mf-maphash (lambda (k v)
          (declare (ignore v))
          (when (and (symbolp k) (eql 0 (number-of-calls k)))
            (push k ans)))
        *memoize-info-ht*)
      (loop for
        x
        in
        (sort ans 'alphorder)
        do
        (print x)))))
other
(defun-one-output memoize-summary-sort
  nil
  (labels ((lex-> (l1 l2)
       (cond ((or (atom l1) (atom l2)) nil)
         ((> (car l1) (car l2)) t)
         ((< (car l1) (car l2)) nil)
         (t (lex-> (cdr l1) (cdr l2))))))
    (let (pairs)
      (with-global-memoize-lock (mf-maphash (lambda (fn v)
            (when (symbolp fn)
              (let ((num (access memoize-info-ht-entry v :num)))
                (declare (type mfixnum num))
                (when (< 0 (number-of-calls num))
                  (push (cons fn
                      (loop for
                        order
                        in
                        *memoize-summary-order-list*
                        collect
                        (funcall order fn)))
                    pairs)))))
          *memoize-info-ht*)
        (sort pairs
          (if *memoize-summary-order-reversed*
            (lambda (x y) (lex-> y x))
            (function lex->))
          :key (function cdr))))))
other
(defun-one-output outside-caller-p
  (x)
  (with-global-memoize-lock (or (<= x *initial-max-symbol-to-fixnum*)
      (null (mf-gethash x *memoize-info-ht*)))))
other
(defun-one-output memoize-condition
  (fn)
  (with-global-memoize-lock (let ((x (mf-gethash fn *memoize-info-ht*)))
      (and x (access memoize-info-ht-entry x :condition)))))
other
(defun-one-output memoize-summary-after-compute-calls-and-times
  nil
  (with-global-memoize-lock (float-ticks/second-init)
    (our-syntax (let* ((fn-pairs (memoize-summary-sort)) (ma *memoize-call-array*)
          (len-orig-fn-pairs (len fn-pairs))
          (len-fn-pairs 0)
          (global-bytes-allocated 0)
          (global-pons-calls 0))
        (declare (type (simple-array mfixnum (*)) ma)
          (type fixnum len-orig-fn-pairs len-fn-pairs))
        (when (and *memoize-summary-limit*
            (> len-orig-fn-pairs *memoize-summary-limit*))
          (setq fn-pairs (take *memoize-summary-limit* fn-pairs)))
        (setq len-fn-pairs (len fn-pairs))
        (when (> len-fn-pairs 0)
          (format t
            "~%Sorted by *memoize-summary-order-list* = ~s."
            *memoize-summary-order-list*)
          (when (< len-fn-pairs len-orig-fn-pairs)
            (format t
              "~%Reporting on ~:d of ~:d functions because ~
                   *memoize-summary-limit* = ~a."
              len-fn-pairs
              len-orig-fn-pairs
              *memoize-summary-limit*)))
        (setq global-bytes-allocated
          (loop for
            pair
            in
            fn-pairs
            sum
            (bytes-allocated (car pair))))
        (setq global-pons-calls
          (loop for
            pair
            in
            fn-pairs
            sum
            (pons-calls (car pair))))
        (when (null fn-pairs)
          (format t "~%(memoize-summary) has nothing to report.~%"))
        (loop for
          pair
          in
          fn-pairs
          do
          (let* ((fn (car pair)) (entry (mf-gethash fn *memoize-info-ht*))
              (tablename (symbol-value (access memoize-info-ht-entry entry :tablename)))
              (ponstablename (symbol-value (access memoize-info-ht-entry entry :ponstablename)))
              (start-ticks (the-mfixnum (symbol-value (the symbol
                      (access memoize-info-ht-entry entry :start-ticks)))))
              (num (the-mfixnum (access memoize-info-ht-entry entry :num)))
              (nhits (the-mfixnum (number-of-hits num)))
              (nmht (the-mfixnum (number-of-mht-calls num)))
              (ncalls (the-mfixnum (number-of-calls num)))
              (pons-calls (the-mfixnum (pons-calls num)))
              (no-hits (or (not *report-hits*) (null (memoize-condition fn))))
              (bytes-allocated (bytes-allocated num))
              (tt (max 1.0e-6 (total-time num)))
              (t/c (time/call num))
              (in-progress-str (if (eql start-ticks -1)
                  ""
                  " (running)"))
              (selftime tt))
            (declare (type integer start-ticks)
              (type mfixnum
                num
                nhits
                nmht
                ncalls
                pons-calls
                bytes-allocated))
            (format t "~%(~s~%" fn)
            (mf-print-alist `(,@(WHEN (OR *REPORT-CALLS* *REPORT-HITS*)
    `((,(FORMAT NIL " ~a~a"
                (IF NO-HITS
                    "Calls"
                    "Hits/calls")
                IN-PROGRESS-STR)
       ,(COND (NO-HITS (FORMAT NIL "~a" (MF-NUM-TO-STRING NCALLS)))
              ((ZEROP NCALLS) (FORMAT NIL "~8,2e/~8,2e = ????%" NHITS 0))
              (T
               (FORMAT NIL "~8,2e/~8,2e = ~4,1f%" NHITS NCALLS
                       (* 100 (/ NHITS (FLOAT NCALLS))))))))) ,@(WHEN (AND *REPORT-MHT-CALLS* (>= NMHT 2))
    `((" Number of calls to mht" ,(MF-NUM-TO-STRING NMHT))))
                ,@(WHEN *REPORT-TIME*
    `((" Time of all outermost calls" ,(FORMAT NIL "~a" (MF-NUM-TO-STRING TT)))
      (" Time per call" ,(MF-NUM-TO-STRING T/C))))
                ,@(WHEN (AND (> BYTES-ALLOCATED 0) *REPORT-BYTES*)
    (ASSERT (> GLOBAL-BYTES-ALLOCATED 0))
    `((" Heap bytes allocated"
       ,(FORMAT NIL "~a; ~4,1f%" (MF-NUM-TO-STRING BYTES-ALLOCATED)
                (* 100 (/ BYTES-ALLOCATED GLOBAL-BYTES-ALLOCATED))))
      (" Heap bytes allocated per call"
       ,(MF-NUM-TO-STRING (/ BYTES-ALLOCATED NCALLS)))))
                ,@(WHEN (AND (> PONS-CALLS 0) *REPORT-PONS-CALLS*)
    (ASSERT (> GLOBAL-PONS-CALLS 0))
    `((" Pons calls"
       ,(FORMAT NIL "~a; ~4,1f%" (MF-NUM-TO-STRING PONS-CALLS)
                (* 100 (/ PONS-CALLS GLOBAL-PONS-CALLS))))))
                ,@(WHEN (AND *REPORT-HITS* *REPORT-TIME* (NOT (EQL 0 NHITS)))
    `((" Time per missed call"
       ,(MF-NUM-TO-STRING (TIME-FOR-NON-HITS/CALL NUM)))))
                ,@(WHEN *REPORT-CALLS-TO*
    (LET ((LST NIL) (OUTSIDE-FN-TIME 0) (OUTSIDE-FN-COUNT 0))
      (DECLARE (TYPE MFIXNUM OUTSIDE-FN-COUNT))
      (LOOP FOR CALLERN IN (LOOP FOR I BELOW (LENGTH *CALLERS-ARRAY*)
                                 WHEN (MEMBER NUM (AREF *CALLERS-ARRAY* I))
                                 COLLECT I)
            DO (LET* ((CALL-LOC (MA-INDEX-CALLS CALLERN NUM))
                      (CALLS (AREF MA CALL-LOC))
                      (TICKS-LOC (THE-MFIXNUM (1+ CALL-LOC)))
                      (TICKS (AREF MA TICKS-LOC))
                      (LOCAL-TT (/ TICKS *FLOAT-TICKS/SECOND*)))
                 (DECLARE (TYPE MFIXNUM CALL-LOC CALLS TICKS-LOC TICKS))
                 (DECF SELFTIME LOCAL-TT)
                 (COND
                  ((OR (OUTSIDE-CALLER-P CALLERN) (< (* 100 LOCAL-TT) TT))
                   (INCF OUTSIDE-FN-TIME LOCAL-TT)
                   (SAFE-INCF OUTSIDE-FN-COUNT CALLS
                              MEMOIZE-SUMMARY-AFTER-COMPUTE-CALLS-AND-TIMES))
                  (T
                   (PUSH
                    `((,(FORMAT NIL " To ~s" (FIXNUM-TO-SYMBOL CALLERN))
                       ,(FORMAT NIL "~8,2e calls took~8,2e; ~a%" CALLS LOCAL-TT
                                (COND
                                 ((> (* 10000 LOCAL-TT) TT) (ASSERT (< 0 TT))
                                  (FORMAT NIL "~4,1f" (* 100 (/ LOCAL-TT TT))))
                                 (T "<0.01"))))
                      . ,(IF *SORT-TO-FROM-BY-CALLS*
                             CALLS
                             LOCAL-TT))
                    LST)))))
      (WHEN (> OUTSIDE-FN-TIME 0)
        (ASSERT (< 0 TT))
        (PUSH
         `((,(FORMAT NIL " To other functions")
            ,(FORMAT NIL "~8,2e calls took~8,2e; ~a%" OUTSIDE-FN-COUNT
                     OUTSIDE-FN-TIME
                     (IF (> (* 10000 OUTSIDE-FN-TIME) TT)
                         (FORMAT NIL "~4,1f" (* 100 (/ OUTSIDE-FN-TIME TT)))
                         "<0.01")))
           . ,(IF *SORT-TO-FROM-BY-CALLS*
                  OUTSIDE-FN-COUNT
                  OUTSIDE-FN-TIME))
         LST))
      (WHEN (AND (> SELFTIME 0) (NOT (= SELFTIME TT)))
        (ASSERT (< 0 TT))
        (PUSH
         `((" To self/unprofiled functions"
            ,(FORMAT NIL "~8,2e; ~a%" SELFTIME
                     (IF (> (* 10000 SELFTIME) TT)
                         (FORMAT NIL "~4,1f" (* 100 (/ SELFTIME TT)))
                         "<0.01")))
           . ,(IF *SORT-TO-FROM-BY-CALLS*
                  0
                  SELFTIME))
         LST))
      (SETQ LST (SORT LST #'> :KEY #'CDR))
      (STRIP-CARS LST)))
                ,@(WHEN *REPORT-CALLS-FROM*
    (LET ((LST NIL) (OUTSIDE-CALLER-TIME 0) (OUTSIDE-CALLER-COUNT 0))
      (LOOP FOR CALLERN IN (AREF *CALLERS-ARRAY* NUM)
            DO (LET* ((CALL-LOC (MA-INDEX-CALLS NUM CALLERN))
                      (CALLS (AREF MA CALL-LOC))
                      (TICKS-LOC (THE-MFIXNUM (1+ CALL-LOC)))
                      (TICKS (AREF MA TICKS-LOC))
                      (LOCAL-TT (/ TICKS *FLOAT-TICKS/SECOND*)))
                 (DECLARE (TYPE MFIXNUM CALL-LOC CALLS TICKS-LOC TICKS))
                 (COND
                  ((OR (OUTSIDE-CALLER-P CALLERN) (< (* 100 LOCAL-TT) TT))
                   (INCF OUTSIDE-CALLER-TIME LOCAL-TT)
                   (INCF OUTSIDE-CALLER-COUNT CALLS))
                  (T
                   (PUSH
                    `((,(FORMAT NIL " From ~s" (FIXNUM-TO-SYMBOL CALLERN))
                       ,(FORMAT NIL "~8,2e calls took~8,2e; ~a%" CALLS LOCAL-TT
                                (IF (AND (<= 0.001 LOCAL-TT) (<= LOCAL-TT TT))
                                    (FORMAT NIL "~4,1f"
                                            (* 100 (/ LOCAL-TT TT)))
                                    "?")))
                      . ,(IF *SORT-TO-FROM-BY-CALLS*
                             CALLS
                             LOCAL-TT))
                    LST)))))
      (WHEN (> OUTSIDE-CALLER-TIME 0)
        (PUSH
         `((,(FORMAT NIL " From other functions")
            ,(FORMAT NIL "~8,2e calls took~8,2e; ~a%" OUTSIDE-CALLER-COUNT
                     OUTSIDE-CALLER-TIME
                     (IF (AND (<= 0.001 OUTSIDE-CALLER-TIME)
                              (<= OUTSIDE-CALLER-TIME TT))
                         (FORMAT NIL "~4,1f"
                                 (* 100 (/ OUTSIDE-CALLER-TIME TT)))
                         "?")))
           . ,(IF *SORT-TO-FROM-BY-CALLS*
                  OUTSIDE-CALLER-COUNT
                  OUTSIDE-CALLER-TIME))
         LST))
      (SETQ LST (SORT LST #'> :KEY #'CDR))
      (STRIP-CARS LST)))
                ,@(WHEN (OR *REPORT-ON-MEMO-TABLES* *REPORT-ON-PONS-TABLES*)
    (LET ((SUM-PONS-SUB-SIZES 0) (NPONSES 0) (NPONSSUBS 0))
      (DECLARE (TYPE MFIXNUM SUM-PONS-SUB-SIZES NPONSES NPONSSUBS))
      (AND PONSTABLENAME *REPORT-ON-PONS-TABLES*
           (MF-MAPHASH
            (LAMBDA (KEY VALUE)
              (DECLARE (IGNORE KEY))
              (COND
               ((NOT (LISTP VALUE))
                (SAFE-INCF-PONS SUM-PONS-SUB-SIZES (MF-HASH-TABLE-SIZE VALUE))
                (SAFE-INCF-PONS NPONSES (MF-HASH-TABLE-COUNT VALUE))
                (SAFE-INCF-PONS NPONSSUBS 1))
               (T (SAFE-INCF-PONS NPONSES (LENGTH VALUE)))))
            PONSTABLENAME))
      `(,@(AND TABLENAME *REPORT-ON-MEMO-TABLES*
               (LET ((COUNT (MF-HASH-TABLE-COUNT TABLENAME))
                     (SIZE (MF-HASH-TABLE-SIZE TABLENAME)))
                 `((,(FORMAT NIL " Memoize table count/size")
                    ,(FORMAT NIL "~8,2e/~8,2e = ~4,1f%" COUNT SIZE
                             (* 100 (/ COUNT SIZE)))))))
        ,@(AND PONSTABLENAME *REPORT-ON-PONS-TABLES*
               (LET ((COUNT (MF-HASH-TABLE-COUNT PONSTABLENAME))
                     (SIZE (MF-HASH-TABLE-SIZE PONSTABLENAME)))
                 `((" (Pons table count/size"
                    ,(FORMAT NIL "~:d/~:d = ~4,1f%)" COUNT SIZE
                             (* 100 (/ COUNT SIZE))))
                   (" (Number of pons sub tables"
                    ,(FORMAT NIL "~a)" (MF-NUM-TO-STRING NPONSSUBS)))
                   (" (Sum of pons sub table sizes"
                    ,(FORMAT NIL "~a)" (MF-NUM-TO-STRING SUM-PONS-SUB-SIZES)))
                   (" (Number of ponses"
                    ,(FORMAT NIL "~a)" (MF-NUM-TO-STRING NPONSES))))))))))
              5))
          (format t ")"))))
    (terpri *standard-output*)
    (force-output *standard-output*))
  nil)
other
(defun-one-output memoize-summary
  nil
  (compute-calls-and-times)
  (memoize-summary-after-compute-calls-and-times)
  nil)
clear-one-memo-and-pons-hashfunction
(defun clear-one-memo-and-pons-hash
  (l strategy)
  (with-global-memoize-lock (let* ((fn (access memoize-info-ht-entry l :fn)) (mt (symbol-value (access memoize-info-ht-entry l :tablename)))
        (pt (symbol-value (access memoize-info-ht-entry l :ponstablename)))
        (mt-count (and mt (mf-hash-table-count mt)))
        (pt-count (and pt (mf-hash-table-count pt))))
      (when mt
        (let* ((mt-target-size (memoize-table-desired-size fn 0)))
          (if (or (eq strategy :clear)
              (and (eq strategy :auto) (< mt-count mt-target-size)))
            (unless (eql 0 mt-count) (clrhash mt))
            (setf (symbol-value (access memoize-info-ht-entry l :tablename))
              nil))))
      (when pt
        (let* ((pt-target-size (pons-table-desired-size fn 0)))
          (if (or (eq strategy :clear)
              (and (eq strategy :auto) (< pt-count pt-target-size)))
            (unless (eql 0 pt-count) (clrhash pt))
            (setf (symbol-value (access memoize-info-ht-entry l :ponstablename))
              nil))))
      (when (or mt-count pt-count)
        (update-memo-max-sizes fn (or pt-count 1) (or mt-count 1)))))
  nil)
other
(defun-one-output clear-memoize-table
  (k)
  (with-global-memoize-lock (when (symbolp k)
      (let ((l (mf-gethash k *memoize-info-ht*)))
        (when l (clear-one-memo-and-pons-hash l :auto)))))
  k)
other
(defun-one-output clear-memoize-tables
  nil
  (with-global-memoize-lock (let (success)
      (unwind-protect (progn (mf-maphash (lambda (k l)
              (when (symbolp k) (clear-one-memo-and-pons-hash l :null)))
            *memoize-info-ht*)
          (setq success t))
        (or success (error "clear-memoize-tables failed."))))
    (setq *pons-call-counter* 0)
    (setq *pons-misses-counter* 0))
  nil)
clear-memoize-call-arrayfunction
(defun clear-memoize-call-array
  nil
  (with-global-memoize-lock (let ((ma *memoize-call-array*))
      (declare (type (simple-array mfixnum (*)) ma))
      (let ((len (length ma)))
        (cond ((typep len 'fixnum) (loop for
              i
              fixnum
              below
              len
              do
              (setf (aref ma i) 0)))
          (t (loop for
              i
              of-type
              integer
              below
              len
              do
              (setf (aref ma i) 0))))))))
clear-memoize-statisticsfunction
(defun clear-memoize-statistics
  nil
  (with-global-memoize-lock (setq *pons-call-counter* 0)
    (setq *pons-misses-counter* 0)
    (clear-memoize-call-array))
  nil)
other
(defun-one-output memoize-init
  nil
  (with-global-memoize-lock (when *memoize-init-done* (return-from memoize-init nil))
    (unless (eql *caller* (the-mfixnum (outside-caller-col-base)))
      (error "memoize-init:  A memoized function is running."))
    (let (success)
      (unwind-protect (progn (setq *pons-call-counter* 0)
          (setq *pons-misses-counter* 0)
          (setq *memoize-info-ht* (initial-memoize-info-ht))
          (mf-sethash *initial-max-symbol-to-fixnum*
            "outside-caller"
            *memoize-info-ht*)
          (setq *max-symbol-to-fixnum* *initial-max-symbol-to-fixnum*)
          (setq *2max-memoize-fns* *initial-2max-memoize-fns*)
          (sync-memoize-call-array)
          (setq *memo-max-sizes* (mf-mht :shared :default))
          (setq success t))
        (if success
          (setq *memoize-init-done* t)
          (error "memoize-init failed.")))))
  nil)
with-lower-overheadmacro
(defmacro with-lower-overhead
  (&rest r)
  `(let ((*record-bytes* nil) (*record-calls* nil)
      (*record-hits* nil)
      (*record-mht-calls* nil)
      (*record-pons-calls* nil)
      (*record-time* nil))
    ,@R))
with-higher-overheadmacro
(defmacro with-higher-overhead
  (&rest r)
  `(let ((*record-bytes* t) (*record-calls* t)
      (*record-hits* t)
      (*record-mht-calls* t)
      (*record-pons-calls* t)
      (*record-time* t))
    ,@R))
with-overheadmacro
(defmacro with-overhead
  (val form)
  (let ((v (gensym)))
    `(let ((,V ,VAL))
      (cond ((eq ,V :default) ,FORM)
        ((null ,V) (with-lower-overhead ,FORM))
        (t (with-higher-overhead ,FORM))))))
acl2h-init-memoizationsfunction
(defun acl2h-init-memoizations
  nil
  (loop for
    entry
    in
    *thread-unsafe-builtin-memoizations*
    when
    (not (memoizedp-raw (car entry)))
    do
    (with-lower-overhead (apply 'memoize-fn entry))))
set-bad-lisp-consp-memoizefunction
(defun set-bad-lisp-consp-memoize
  (arg)
  (cond (arg (when (not (memoizedp-raw 'bad-lisp-consp))
        (with-lower-overhead (apply 'memoize-fn *bad-lisp-consp-memoization*))))
    (t (when (memoizedp-raw 'bad-lisp-consp)
        (unmemoize-fn 'bad-lisp-consp)))))
other
(defun-one-output acl2h-init nil nil)
memstatfunction
(defun memstat (&rest r) (apply (function memoized-values) r))
clear-memo-tablesfunction
(defun clear-memo-tables nil (clear-memoize-tables))
lower-overheadfunction
(defun lower-overhead
  nil
  (setq *record-bytes* nil)
  (setq *record-calls* nil)
  (setq *record-hits* nil)
  (setq *record-mht-calls* nil)
  (setq *record-pons-calls* nil)
  (setq *record-time* nil))
update-memo-entry-for-attachmentsfunction
(defun update-memo-entry-for-attachments
  (fns entry special-name wrld)
  (let* ((ext-anc-attachments (access memoize-info-ht-entry entry :ext-anc-attachments)) (valid-p (if (eq fns :clear)
          :clear (or (null ext-anc-attachments)
            (ext-anc-attachments-valid-p fns
              ext-anc-attachments
              special-name
              wrld
              t)))))
    (cond ((eq valid-p t) (mv nil entry))
      (t (mv (if (eq valid-p nil)
            t
            valid-p)
          (change memoize-info-ht-entry
            entry
            :ext-anc-attachments (ext-ancestors-attachments (access memoize-info-ht-entry entry :fn)
              wrld)))))))
update-memo-entries-for-attachmentsfunction
(defun update-memo-entries-for-attachments
  (fns wrld state)
  (let ((ctx 'top-level) (fns (if (eq fns :clear)
          :clear (strict-merge-sort-symbol< (loop for
              fn
              in
              fns
              collect
              (canonical-sibling fn wrld)))))
      (special-name *special-cltl-cmd-attachment-mark-name*))
    (when (eq fns :clear)
      (observation ctx
        "Memoization tables for functions memoized with :AOKP T ~
                    are being cleared."))
    (when fns
      (with-global-memoize-lock (mf-maphash (lambda (k entry)
            (when (symbolp k)
              (mv-let (changedp new-entry)
                (update-memo-entry-for-attachments fns
                  entry
                  special-name
                  wrld)
                (when changedp
                  (when (not (or (eq changedp t) (eq fns :clear)))
                    (observation ctx
                      "Memoization table for function ~x0 is ~
                                      being cleared because ~@1."
                      k
                      (if (eq changedp special-name)
                        "it depends on apply$-userfn or ~
                                          badge-userfn and at least one badge ~
                                          has changed"
                        (msg "the attachment to function ~x0 ~
                                             has changed"
                          changedp)))
                    (clear-one-memo-and-pons-hash entry :auto))
                  (mf-sethash k new-entry *memoize-info-ht*)))))
          *memoize-info-ht*))))
  (clear-memoize-table 'canonical-ancestors-rec)
  (clear-memoize-table 'immediate-canonical-ancestors)
  (clear-memoize-table 'canonical-ancestors-tr-rec)
  (clear-memoize-table 'immediate-canonical-ancestors-tr)
  (clear-memoize-table 'canonical-ancestors-path)
  (clear-memoize-table 'canonical-ancestors-tr-path))