Included Books
other
(in-package "ACL2")
include-book
(include-book "gentle")
include-book
(include-book "std/alists/worth-hashing" :dir :system)
other
(set-state-ok t)
all-memoized-fnsmacro
(defmacro all-memoized-fns (&optional show-conditions) (if show-conditions '(table-alist 'memoize-table (w state)) '(strip-cars (table-alist 'memoize-table (w state)))))
other
(defsection make-fal :parents (fast-alists) :short "Make a fast alist out of an alist." :long "<p>Note: it is usually better to use @(see make-fast-alist).</p> <p>@('(make-fal al name)') copies the alist AL with @(see hons-acons) to make a fast alist that ends with NAME.</p> <p>Typically @('name') is an atom, and it becomes the final @(see cdr) of the new fast alist. Some atoms have special meanings, e.g., they act as size hints; see @(see hons-acons) for details.</p> <p>However, @('name') can also be an existing fast alist. In this case, this fast alist is extended with the new pairs from @('al'), using @(see hons-acons). Note that @('name') will no longer be fast after the call of @('make-fal').</p> <p>There's nothing under-the-hood about @('make-fal'); it just repeatedly calls @('hons-acons'). The built-in function @(see make-fast-alist) is generally more efficient and can be nicer to reason about because logically it is just the identity. On the other hand, @('make-fast-alist') can't be used to extend an existing fast alist like @('make-fal').</p>" (defn make-fal (al name) (cond ((atom al) name) ((atom (car al)) (make-fal (cdr al) name)) (t (hons-acons (caar al) (cdar al) (make-fal (cdr al) name))))))
other
(defsection ansfl :parents (fast-alists) :short "@('(ANSFL X Y)') returns the single value @('X') after first flushing the fast hash table backing for @('Y'), if @('Y') is a fast alist." :long "<p>Thus</p> @({(ANSFL X Y) = X}) <p>@('X') must be a form that returns a single value.</p>" (defmacro ansfl (x y) `((lambda (ansfl-do-not-use-elsewhere1 ansfl-do-not-use-elsewhere2) (declare (ignore ansfl-do-not-use-elsewhere2)) ansfl-do-not-use-elsewhere1) ,X (flush-hons-get-hash-table-link ,Y))))
ansfl-listmacro
(defmacro ansfl-list (l x) (if (atom l) x `(ansfl (ansfl-list ,(CDR L) ,X) ,(CAR L))))
other
(defn ansfl-last-list (r bindings) (if (atom bindings) r `(ansfl ,(ANSFL-LAST-LIST R (GENTLE-CDR BINDINGS)) ,(GENTLE-CAAR BINDINGS))))
het*macro
(defmacro het* (bindings &rest r) `(let* ,BINDINGS ,@(BUTLAST R 1) ,(ANSFL-LAST-LIST (CAR (LAST R)) BINDINGS)))
with-fast-listmacro
(defmacro with-fast-list (var term name form) `(let ((,VAR (hons-put-list ,TERM t ,NAME))) (ansfl ,FORM ,VAR)))
other
(defn hons-put-list (keys values l) (if (atom keys) l (let* ((cp (consp values)) (val (if cp (car values) values)) (next-values (if cp (cdr values) values)) (old-pair (hons-get (car keys) l)) (redundant (and old-pair (hons-equal val (cdr old-pair)))) (next-l (if redundant l (hons-acons (car keys) val l)))) (hons-put-list (cdr keys) next-values next-l))))
alist-keysfunction
(defund alist-keys (x) (declare (xargs :guard t)) (cond ((atom x) nil) ((atom (car x)) (alist-keys (cdr x))) (t (cons (caar x) (alist-keys (cdr x))))))
alist-valsfunction
(defund alist-vals (x) (declare (xargs :guard t)) (cond ((atom x) nil) ((atom (car x)) (alist-vals (cdr x))) (t (cons (cdar x) (alist-vals (cdr x))))))
other
(defn hons-binary-append (x y) (mbe :logic (append x y) :exec (if (atom x) y (hons (car x) (hons-binary-append (cdr x) y)))))
other
(defsection hons-append :parents (fast-alists append) :short "APPEND using HONS instead of CONS" (defmacro hons-append (x y &rest rst) (xxxjoin 'hons-binary-append (cons x (cons y rst)))))
other
(defsection hons-revappend :parents (fast-alists revappend) :short "REVAPPEND using HONS instead of CONS" (defn hons-revappend (x y) (mbe :logic (revappend x y) :exec (if (atom x) y (hons-revappend (cdr x) (hons (car x) y))))))
other
(defsection hons-reverse :parents (fast-alists reverse) :short "REVERSE using HONS instead of CONS" (defn hons-reverse (x) (mbe :logic (reverse x) :exec (if (stringp x) (reverse x) (hons-revappend x nil)))))
other
(defsection hons-list :parents (fast-alists list) :short "(LIST ...) using HONS instead of CONS" (defmacro hons-list (&rest x) (if (atom x) nil (list 'hons (car x) (cons 'hons-list (cdr x))))))
other
(defsection hons-list* :parents (fast-alists list*) :short "(LIST* ...) using HONS instead of CONS" (defmacro hons-list* (&rest x) (cond ((atom x) x) ((atom (cdr x)) (car x)) (t (list 'hons (car x) (cons 'hons-list* (cdr x)))))))
other
(defsection hons-make-list :parents (fast-alists make-list) :short "Like @(see make-list), but produces honses." (defn hons-make-list-acc (n val ac) (mbe :logic (make-list-ac n val ac) :exec (if (not (posp n)) ac (hons-make-list-acc (1- n) val (hons val ac))))) (defmacro hons-make-list (size &key initial-element) `(hons-make-list-acc ,SIZE ,INITIAL-ELEMENT nil)))
other
(defsection hons-member-equal :parents (fast-alists member-equal) :short "MEMBER-EQUAL using HONS-EQUAL for each equality check" (defn hons-member-equal (x y) (mbe :logic (member-equal x y) :exec (cond ((atom y) nil) ((hons-equal x (car y)) y) (t (hons-member-equal x (cdr y)))))))
other
(defsection hons-dups-p1 :parents (fast-alists) :short "Basic duplicates check; table is a fast alist that associates already-seen elements with t." (defn hons-dups-p1 (l tab) (cond ((atom l) (ansfl nil tab)) ((hons-get (car l) tab) (ansfl l tab)) (t (hons-dups-p1 (cdr l) (hons-acons (car l) t tab))))))
hons-assoc-equal-hons-put-listencapsulate
(encapsulate nil (local (defthm hons-assoc-equal-hons-put-list-t (iff (hons-assoc-equal x (hons-put-list y t rest)) (or (hons-assoc-equal x rest) (member x y))) :hints (("goal" :induct (hons-put-list y t rest))))) (defthm hons-assoc-equal-hons-put-list (implies (atom a) (iff (hons-assoc-equal x (hons-put-list y t a)) (member x y)))))
other
(defn hons-dups-p (l) (hons-dups-p1 l '*hons-dups-p*))
local
(local (in-theory (enable alist-keys)))
local
(local (defthm member-alist-keys (iff (member x (alist-keys y)) (hons-assoc-equal x y))))
hons-dups-p-no-duplicatespencapsulate
(encapsulate nil (local (defthm intersectp-cons-second (implies (intersectp x y) (intersectp x (cons z y))))) (local (defthm intersectp-cons-second-2 (implies (not (intersectp x y)) (iff (intersectp x (cons z y)) (member z x))))) (local (defthm intersectp-cons-member (implies (member z x) (intersectp x (cons z y))))) (local (defthm hons-dups-p1-no-duplicatesp (iff (hons-dups-p1 x tab) (or (not (no-duplicatesp x)) (intersectp x (alist-keys tab)))) :hints (("Goal" :induct (hons-dups-p1 x tab))))) (defthm hons-dups-p-no-duplicatesp (iff (hons-dups-p x) (not (no-duplicatesp x)))))
fast-no-duplicatespfunction
(defun fast-no-duplicatesp (x) (declare (xargs :guard (eqlable-listp x))) (mbe :logic (no-duplicatesp-equal x) :exec (if (< (length x) 400) (no-duplicatesp x) (not (hons-dups-p x)))))
fast-no-duplicatesp-equalfunction
(defun fast-no-duplicatesp-equal (x) (declare (xargs :guard (true-listp x))) (mbe :logic (no-duplicatesp-equal x) :exec (if (< (length x) 400) (no-duplicatesp-equal x) (not (hons-dups-p x)))))
fast-no-duplicatesp-eqfunction
(defun fast-no-duplicatesp-eq (x) (declare (xargs :guard (symbol-listp x))) (mbe :logic (no-duplicatesp-equal x) :exec (if (< (length x) 400) (no-duplicatesp-eq x) (not (hons-dups-p x)))))
other
(defn hons-duplicates1 (l tab) (cond ((atom l) (ansfl nil tab)) ((hons-get (car l) tab) (cons (car l) (hons-duplicates1 (cdr l) tab))) (t (hons-duplicates1 (cdr l) (hons-acons (car l) t tab)))))
other
(defn hons-duplicates (l) (hons-duplicates1 l nil))
other
(defsection hons-sublis-aux :parents (hons-sublis) :short "Memoized core of @(see hons-sublis)." (defun hons-sublis-aux (fal x) (declare (xargs :guard t)) (if (atom x) (let ((pair (hons-get x fal))) (if pair (cdr pair) x)) (cons (hons-sublis-aux fal (car x)) (hons-sublis-aux fal (cdr x))))) (encapsulate nil (local (defthm lemma (implies (alistp x) (equal (hons-assoc-equal a x) (assoc a x))) :hints (("Goal" :induct (len x))))) (defthm hons-sublis-aux-removal (implies (alistp fal) (equal (hons-sublis-aux fal x) (sublis fal x))))) (memoize 'hons-sublis-aux :condition '(consp x)))
other
(defsection hons-sublis :parents (hons sublis) :short "@(tsee memoize)d version of SUBLIS which uses @(see fast-alists)." :long "<p>@('(hons-sublis fal x)') is like @(see sublis), but may be faster in two ways.</p> <ol> <li>It uses @(see hons-get) instead of @(see assoc), which may provide a speedup when the alist in question is very long. Note that for good performance, the fast-alist argument, @('fal'), must be a valid fast-alist.</li> <li>It uses a memoized auxiliary function, which may provide a speedup when the tree argument, @('x'), contains large, shared structures.</li> </ol>" (defun hons-sublis (fal x) (declare (xargs :guard t)) (let ((ret (hons-sublis-aux fal x))) (prog2$ (clear-memoize-table 'hons-sublis-aux) ret))) (defthm hons-sublis-removal (implies (alistp fal) (equal (hons-sublis fal x) (sublis fal x)))))
*magic-number-for-hashing*constant
(defconst *magic-number-for-hashing* 18)
other
(defn hons-int1 (l1 al2) (cond ((atom l1) nil) ((hons-get (car l1) al2) (cons (car l1) (hons-int1 (cdr l1) al2))) (t (hons-int1 (cdr l1) al2))))
other
(defn hons-intersection2 (l1 l2) (cond ((atom l1) nil) ((hons-member-equal (car l1) l2) (cons (car l1) (hons-intersection2 (cdr l1) l2))) (t (hons-intersection2 (cdr l1) l2))))
other
(defn hons-intersection (l1 l2) (cond ((worth-hashing l2) (with-fast-list fl2 l2 '*hons-intersection-alist* (hons-int1 l1 fl2))) (t (hons-intersection2 l1 l2))))
hons-intersection-is-intersection-equalencapsulate
(encapsulate nil (local (defthm hons-int1-is-intersection-equal (implies (atom atom) (equal (hons-int1 x (hons-put-list y t atom)) (intersection-equal x y))) :hints (("Goal" :in-theory (enable intersection-equal))))) (local (defthm hons-intersection2-is-intersection-equal (equal (hons-intersection2 x y) (intersection-equal x y)) :hints (("Goal" :in-theory (enable intersection-equal))))) (defthm hons-intersection-is-intersection-equal (equal (hons-intersection a b) (intersection-equal a b))))
other
(defn hons-intersect-p1 (l1 al2) (cond ((atom l1) nil) ((hons-get (car l1) al2) t) (t (hons-intersect-p1 (cdr l1) al2))))
other
(defn hons-intersect-p2 (l1 l2) (cond ((atom l1) nil) ((hons-member-equal (car l1) l2) t) (t (hons-intersect-p2 (cdr l1) l2))))
other
(defn hons-intersect-p (l1 l2) (cond ((and (worth-hashing l1) (worth-hashing l2)) (with-fast-list fl2 l2 '*hons-intersect-p-alist* (hons-intersect-p1 l1 fl2))) (t (hons-intersect-p2 l1 l2))))
hons-intersect-p-is-intersectpencapsulate
(encapsulate nil (local (defthm hons-intersect-p1-is-intersectp (implies (atom atom) (equal (hons-intersect-p1 x (hons-put-list y t atom)) (intersectp x y))) :hints (("Goal" :in-theory (enable intersectp))))) (local (defthm hons-intersect-p2-is-intersectp (equal (hons-intersect-p2 x y) (intersectp x y)) :hints (("Goal" :in-theory (enable intersectp))))) (defthm hons-intersect-p-is-intersectp (equal (hons-intersect-p a b) (intersectp a b))))
other
(defn hons-sd1 (l1 al2) (cond ((atom l1) nil) ((hons-get (car l1) al2) (hons-sd1 (cdr l1) al2)) (t (cons (car l1) (hons-sd1 (cdr l1) al2)))))
other
(defn hons-set-diff2 (l1 l2) (cond ((atom l1) nil) ((hons-member-equal (car l1) l2) (hons-set-diff2 (cdr l1) l2)) (t (cons (car l1) (hons-set-diff2 (cdr l1) l2)))))
other
(defn hons-set-diff (l1 l2) (cond ((worth-hashing l2) (with-fast-list fl2 l2 '*hons-set-diff-alist* (hons-sd1 l1 fl2))) (t (hons-set-diff2 l1 l2))))
hons-set-diff-is-set-difference$encapsulate
(encapsulate nil (local (defthm hons-sd1-is-set-difference$ (implies (atom atom) (equal (hons-sd1 x (hons-put-list y t atom)) (set-difference$ x y))) :hints (("Goal" :in-theory (enable set-difference$))))) (local (defthm hons-set-diff2-is-set-difference$ (equal (hons-set-diff2 x y) (set-difference$ x y)) :hints (("Goal" :in-theory (enable set-difference$))))) (defthm hons-set-diff-is-set-difference$ (equal (hons-set-diff a b) (set-difference$ a b))))
other
(defn hons-union1 (l1 al2 acc) (cond ((atom l1) acc) ((hons-get (car l1) al2) (hons-union1 (cdr l1) al2 acc)) (t (hons-union1 (cdr l1) al2 (cons (car l1) acc)))))
other
(defn hons-union2 (l1 l2 acc) (cond ((atom l1) acc) ((hons-member-equal (car l1) l2) (hons-union2 (cdr l1) l2 acc)) (t (hons-union2 (cdr l1) l2 (cons (car l1) acc)))))
other
(defn hons-un1 (l1 fl2) (cond ((atom l1) fl2) ((hons-get (car l1) fl2) (hons-un1 (cdr l1) fl2)) (t (hons-un1 (cdr l1) (hons-acons (car l1) t fl2)))))
other
(defn hons-union (l1 l2) (cond ((atom l1) l2) ((atom l2) l1) ((atom (cdr l1)) (if (hons-member-equal (car l1) l2) l2 (cons (car l1) l2))) ((atom (cdr l2)) (if (hons-member-equal (car l2) l1) l1 (cons (car l2) l1))) (t (let ((len1 (len l1)) (len2 (len l2))) (cond ((and (>= len2 len1) (>= len1 *magic-number-for-hashing*)) (with-fast-list fl2 l2 '*hons-union* (hons-union1 l1 fl2 l2))) ((and (>= len1 len2) (>= len2 *magic-number-for-hashing*)) (with-fast-list fl1 l1 '*hons-union* (hons-union1 l2 fl1 l1))) (t (hons-union2 l1 l2 l2)))))))
encapsulate
(encapsulate nil (local (defthm hons-union1-revappend-set-difference (equal (hons-union1 x tab y) (revappend (set-difference$ x (alist-keys tab)) y)))) (local (defthm hons-union2-revappend-set-difference (equal (hons-union2 x l y) (revappend (set-difference$ x l) y)))))
other
(defn hons-union-list (l) (if (atom l) nil (hons-union (car l) (hons-union-list (cdr l)))))
other
(defn hons-subset1 (l al) (or (atom l) (and (hons-get (car l) al) (hons-subset1 (cdr l) al))))
other
(defn hons-subset2 (l1 l2) (cond ((atom l1) t) ((hons-member-equal (car l1) l2) (hons-subset2 (cdr l1) l2))))
other
(defn hons-subset (l1 l2) (cond ((worth-hashing l2) (with-fast-list fl2 l2 '*hons-subset-alist* (hons-subset1 l1 fl2))) (t (hons-subset2 l1 l2))))
other
(defn hons-set-equal (l1 l2) (and (hons-subset l1 l2) (hons-subset l2 l1)))
defhonstmacro
(defmacro defhonst (name form &key (evisc 'nil eviscp) check doc) (declare (ignore doc)) `(with-output :off summary (progn (defconst ,NAME (hons-copy-persistent ,FORM)) (table evisc-table ,NAME ,(IF EVISCP EVISC (LET ((STR (SYMBOL-NAME NAME))) (IF (MAY-NEED-SLASHES STR) (CONCATENATE 'STRING "#.|" STR "|") (CONCATENATE 'STRING "#." STR))))) ,@(AND CHECK `((ASSERT-EVENT ,CHECK))) (value-triple ',NAME))))