Filtering...

bdd

bdd
other
(in-package "ACL2")
mvfmacro
(defmacro mvf (x &rest rest) `(mv (the-fixnum ,X) ,@REST))
logandfmacro
(defmacro logandf
  (&rest args)
  (xxxjoin-fixnum 'logand args -1))
logxorfmacro
(defmacro logxorf
  (&rest args)
  (xxxjoin-fixnum 'logxor args 0))
logiorfmacro
(defmacro logiorf
  (&rest args)
  (xxxjoin-fixnum 'logior args 0))
ashfmacro
(defmacro ashf
  (x y)
  (list 'the-fixnum
    (list 'ash (list 'the-fixnum x) (list 'the-fixnum y))))
mx-id-boundmacro
(defmacro mx-id-bound nil (1- (floor (fixnum-bound) 153)))
1+mx-idmacro
(defmacro 1+mx-id
  (x)
  `(the-fixnum (let ((x ,X))
      (declare (type (signed-byte 61) x))
      (cond ((< x ,(MX-ID-BOUND)) (1+f x))
        (t (the-fixnum (er-hard-val 0
              'bdd
              "Maximum id for bdds exceeded.  Current maximum id is ~x0."
              x)))))))
bdd-errormacro
(defmacro bdd-error
  (mx-id fmt-string fmt-alist bad-cst ttree)
  `(mvf ,MX-ID
    ,FMT-STRING
    (cons ,FMT-ALIST ,BAD-CST)
    nil
    ,TTREE))
unique-idmacro
(defmacro unique-id (x) `(the-fixnum (car ,X)))
tstmacro
(defmacro tst (x) `(cadr ,X))
cst-boolpmacro
(defmacro cst-boolp (x) `(caddr ,X))
tbrmacro
(defmacro tbr (x) `(cadddr ,X))
fbrmacro
(defmacro fbr (x) `(cddddr ,X))
leafpmacro
(defmacro leafp (x) `(null (cdddr ,X)))
trmmacro
(defmacro trm (x) `(cadr ,X))
bdd-constructorsfunction
(defun bdd-constructors
  (wrld)
  (declare (xargs :guard (and (plist-worldp wrld)
        (alistp (table-alist 'acl2-defaults-table wrld)))))
  (let ((pair (assoc-eq :bdd-constructors (table-alist 'acl2-defaults-table wrld))))
    (if pair
      (cdr pair)
      '(cons))))
make-leaf-cstfunction
(defun make-leaf-cst
  (unique-id trm boolp)
  (if boolp
    (list* unique-id trm '(t))
    (list* unique-id trm '(nil))))
evg-fn-symbfunction
(defun evg-fn-symb (x) (cond ((consp x) 'cons) (t nil)))
bdd-constructor-trm-pfunction
(defun bdd-constructor-trm-p
  (trm bdd-constructors)
  (and (consp trm)
    (if (fquotep trm)
      (member-eq (evg-fn-symb (cadr trm)) bdd-constructors)
      (member-eq (car trm) bdd-constructors))))
evg-typefunction
(defun evg-type
  (x)
  (cond ((consp x) 'consp)
    ((symbolp x) 'symbol)
    ((integerp x) 'integer)
    ((rationalp x) 'rational)
    ((complex-rationalp x) 'complex-rational)
    ((stringp x) 'string)
    ((characterp x) 'character)
    (t (er hard 'fn-symb "Unexpected object, ~x0." x))))
make-if-cstfunction
(defun make-if-cst
  (unique-id tst tbr fbr bdd-constructors)
  (let* ((boolp (and (cst-boolp tbr) (cst-boolp fbr))) (new-cst (list* unique-id tst boolp tbr fbr)))
    (cond ((or (and (leafp tbr)
           (bdd-constructor-trm-p (trm tbr) bdd-constructors))
         (and (leafp fbr)
           (bdd-constructor-trm-p (trm fbr) bdd-constructors))) (mv (msg "Attempted to create IF node during BDD processing with ~@0, ~
                which would produce a non-BDD term (as defined in :DOC ~
                bdd-algorithm).  See :DOC show-bdd."
            (let ((true-fn (trm tbr)) (false-fn (trm fbr)))
              (cond ((and (leafp tbr)
                   (bdd-constructor-trm-p (trm tbr) bdd-constructors)) (cond ((and (leafp fbr)
                       (bdd-constructor-trm-p (trm fbr) bdd-constructors)) (msg "true branch with ~#0~[function symbol ~x1~/explicit ~
                         value of type ~x2~] and false branch with ~
                         ~#3~[function symbol ~x4~/explicit value  of type ~
                         ~x5~]"
                        (if (eq (car true-fn) 'quote)
                          1
                          0)
                        (car true-fn)
                        (and (eq (car true-fn) 'quote) (evg-type (cadr true-fn)))
                        (if (eq (car false-fn) 'quote)
                          1
                          0)
                        (car false-fn)
                        (and (eq (car false-fn) 'quote) (evg-type (cadr false-fn)))))
                    (t (msg "true branch with ~#0~[function symbol ~x1~/explicit ~
                           value of type ~x2~]"
                        (if (eq (car true-fn) 'quote)
                          1
                          0)
                        (car true-fn)
                        (and (eq (car true-fn) 'quote) (evg-type (cadr true-fn)))))))
                (t (msg "false branch with ~#0~[function symbol ~x1~/explicit ~
                           value of type ~x2~]"
                    (if (eq (car false-fn) 'quote)
                      1
                      0)
                    (car false-fn)
                    (and (eq (car false-fn) 'quote) (evg-type (cadr false-fn))))))))
          new-cst))
      (t (mv nil new-cst)))))
*cst-t*constant
(defconst *cst-t* (make-leaf-cst 1 *t* t))
*cst-nil*constant
(defconst *cst-nil* (make-leaf-cst 2 *nil* t))
cst=macro
(defmacro cst=
  (cst1 cst2)
  `(= (unique-id ,CST1) (unique-id ,CST2)))
cst-tpmacro
(defmacro cst-tp (cst) `(= (unique-id ,CST) 1))
cst-nilpmacro
(defmacro cst-nilp (cst) `(= (unique-id ,CST) 2))
cst-varpmacro
(defmacro cst-varp (cst) `(< 2 (unique-id ,CST)))
cst-nonnilpfunction
(defun cst-nonnilp
  (cst)
  (and (leafp cst)
    (if (quotep (trm cst))
      (not (cst-nilp cst))
      (ffn-symb-p (trm cst) 'cons))))
bool-mask1function
(defun bool-mask1
  (formals vars rune)
  (cond ((endp formals) rune)
    ((member-eq (car formals) vars) (cons t (bool-mask1 (cdr formals) vars rune)))
    (t (cons nil (bool-mask1 (cdr formals) vars rune)))))
boolean-term-varfunction
(defun boolean-term-var
  (x)
  (and (not (variablep x))
    (not (fquotep x))
    (cond ((and (eq (ffn-symb x) 'booleanp) (variablep (fargn x 1))) (fargn x 1))
      ((eq (ffn-symb x) 'if) (let ((test (fargn x 1)) (tbr (fargn x 2)) (fbr (fargn x 3)))
          (and (ffn-symb-p test 'equal)
            (let ((v (fargn test 1)))
              (and (variablep v)
                (let ((b (fargn test 2)))
                  (and (or (equal b *t*) (equal b *nil*))
                    (let ((c (if (equal b *t*)
                           *nil*
                           *t*)))
                      (if (and (equal test tbr) (equal fbr (fcons-term* 'equal v c)))
                        v
                        nil)))))))))
      (t nil))))
boolean-hyps-varsfunction
(defun boolean-hyps-vars
  (hyps)
  (if (endp hyps)
    nil
    (let ((rst (boolean-hyps-vars (cdr hyps))))
      (if (eq rst t)
        t
        (let ((v (boolean-term-var (car hyps))))
          (if v
            (cons v rst)
            t))))))
first-boolean-type-prescriptionfunction
(defun first-boolean-type-prescription
  (type-prescription-list ens formals)
  (cond ((endp type-prescription-list) (mv nil nil))
    ((and (enabled-numep (access type-prescription
           (car type-prescription-list)
           :nume)
         ens)
       (ts-subsetp (access type-prescription
           (car type-prescription-list)
           :basic-ts)
         *ts-boolean*)) (let* ((tp (car type-prescription-list)) (hyps (access type-prescription tp :hyps))
          (vars (access type-prescription tp :vars)))
        (if hyps
          (let ((more-vars (boolean-hyps-vars hyps)))
            (if (or (eq more-vars t) (not (subsetp-eq more-vars formals)))
              (first-boolean-type-prescription (cdr type-prescription-list)
                ens
                formals)
              (mv (access type-prescription tp :rune)
                (union-eq vars more-vars))))
          (mv (access type-prescription tp :rune) vars))))
    (t (first-boolean-type-prescription (cdr type-prescription-list)
        ens
        formals))))
recognizer-runefunction
(defun recognizer-rune
  (recognizer-alist wrld ens)
  (cond ((endp recognizer-alist) nil)
    ((enabled-runep (access recognizer-tuple (car recognizer-alist) :rune)
       ens
       wrld) (access recognizer-tuple (car recognizer-alist) :rune))
    (t (recognizer-rune (cdr recognizer-alist) wrld ens))))
bool-maskfunction
(defun bool-mask
  (fn wrld ens)
  (cond ((or (eq fn 'equal) (eq fn '<)) (list* nil nil *fake-rune-for-type-set*))
    ((eq fn 'not) (list* nil *fake-rune-for-type-set*))
    (t (let ((rune (recognizer-rune (getpropc fn 'recognizer-alist nil wrld)
             wrld
             ens)) (formals (formals fn wrld)))
        (if rune
          (bool-mask1 formals nil rune)
          (mv-let (rune vars)
            (first-boolean-type-prescription (getpropc fn 'type-prescriptions nil wrld)
              ens
              formals)
            (and rune (bool-mask1 formals vars rune))))))))
commutative-p1function
(defun commutative-p1
  (fn lemmas ens)
  (cond ((endp lemmas) nil)
    (t (if (and (member-eq (access rewrite-rule (car lemmas) :subclass)
            '(backchain abbreviation))
          (equal (access rewrite-rule (car lemmas) :equiv) 'equal)
          (enabled-numep (access rewrite-rule (car lemmas) :nume) ens)
          (null (access rewrite-rule (car lemmas) :hyps))
          (let ((lhs (access rewrite-rule (car lemmas) :lhs)) (rhs (access rewrite-rule (car lemmas) :rhs)))
            (and (or (eq (ffn-symb lhs) fn)
                (er hard
                  'commutative-p1
                  "We had thought we had a rewrite rule with :lhs ~
                               being a call of ~x0, but the :lhs is ~x1."
                  fn
                  lhs))
              (ffn-symb-p rhs fn)
              (variablep (fargn lhs 1))
              (variablep (fargn lhs 2))
              (not (eq (fargn lhs 1) (fargn lhs 2)))
              (equal (fargn lhs 1) (fargn rhs 2))
              (equal (fargn lhs 2) (fargn rhs 1)))))
        (access rewrite-rule (car lemmas) :rune)
        (commutative-p1 fn (cdr lemmas) ens)))))
find-equivalence-runefunction
(defun find-equivalence-rune
  (fn rules)
  (cond ((endp rules) nil)
    ((eq (access congruence-rule (car rules) :equiv) fn) (let ((rune (access congruence-rule (car rules) :rune)))
        (if (eq (car rune) :equivalence)
          rune
          (find-equivalence-rune fn (cdr rules)))))
    (t (find-equivalence-rune fn (cdr rules)))))
equivalence-rune1function
(defun equivalence-rune1
  (fn congruences)
  (cond ((endp congruences) (er hard
        'equivalence-rune
        "Failed to find an equivalence rune for function symbol ~x0."
        fn))
    (t (let ((x (car congruences)))
        (case-match x
          (('equal rules1 rules2) (let ((rune (find-equivalence-rune fn rules1)))
              (if (and rune (equal rune (find-equivalence-rune fn rules2)))
                rune
                (equivalence-rune1 fn (cdr congruences)))))
          (& (equivalence-rune1 fn (cdr congruences))))))))
equivalence-runefunction
(defun equivalence-rune
  (fn wrld)
  (declare (xargs :guard (equivalence-relationp fn wrld)))
  (cond ((eq fn 'equal) (fn-rune-nume 'equal nil nil wrld))
    (t (equivalence-rune1 fn
        (getpropc fn
          'congruences
          '(:error "See equivalence-rune.")
          wrld)))))
commutative-pfunction
(defun commutative-p
  (fn ens wrld)
  (and (= (arity fn wrld) 2)
    (if (equivalence-relationp fn wrld)
      (equivalence-rune fn wrld)
      (commutative-p1 fn (getpropc fn 'lemmas nil wrld) ens))))
op-alistfunction
(defun op-alist
  (fns acc i ens wrld)
  (cond ((endp fns) acc)
    ((> i (mx-id-bound)) (er hard
        'bdd
        "We are very surprised to see that, apparently, your problem for bdd ~
         processing involves ~x0 function symbols!  We cannot handle this many ~
         function symbols."
        (/ i 3)))
    (t (op-alist (cdr fns)
        (cons (list* (car fns)
            i
            (commutative-p (car fns) ens wrld)
            (and (not (getpropc (car fns) 'constrainedp nil wrld))
              (enabled-xfnp (car fns) ens wrld)
              (fn-rune-nume (car fns) nil t wrld))
            (bool-mask (car fns) wrld ens))
          acc)
        (+ 3 i)
        ens
        wrld))))
op-alist-infofunction
(defun op-alist-info
  (fn op-alist)
  (cond ((endp op-alist) (mv (er hard 'op-alist-info "Function not found:  ~x0" fn)
        nil
        nil
        nil))
    ((eq fn (caar op-alist)) (let ((info (cdar op-alist)))
        (mv (car info) (cadr info) (caddr info) (cdddr info))))
    (t (op-alist-info fn (cdr op-alist)))))
if-op-codemacro
(defmacro if-op-code nil 3)
hash-sizemacro
(defmacro hash-size nil (1- (expt 2 15)))
if-hash-indexmacro
(defmacro if-hash-index
  (x y z)
  `(logandf (+f (*f 131 (unique-id ,X))
      (*f 2 (unique-id ,Y))
      (unique-id ,Z))
    (hash-size)))
op-hash-index1function
(defun op-hash-index1
  (args i acc)
  (declare (type (signed-byte 61) i acc)
    (xargs :measure (acl2-count args)))
  (the-fixnum (cond ((endp args) (if (< acc 0)
          (- acc)
          acc))
      ((or (= (the-fixnum i) 18) (= (the-fixnum i) -1)) (if (> acc 0)
          (op-hash-index1 args -17 acc)
          (op-hash-index1 args 2 acc)))
      (t (op-hash-index1 (cdr args)
          (1+f i)
          (+f acc (*f i (unique-id (car args)))))))))
op-hash-indexmacro
(defmacro op-hash-index
  (op-code args)
  `(logandf (+f ,OP-CODE (op-hash-index1 ,ARGS 2 1))
    (hash-size)))
op-hash-index-2macro
(defmacro op-hash-index-2
  (op-code arg1 arg2)
  `(logandf (+f ,OP-CODE
      (*f 2 (unique-id ,ARG1))
      (*f 3 (unique-id ,ARG2)))
    (hash-size)))
op-hash-index-ifmacro
(defmacro op-hash-index-if
  (arg1 arg2 arg3)
  `(logandf (+f (if-op-code)
      (*f 2 (unique-id ,ARG1))
      (*f 3 (unique-id ,ARG2))
      (*f 4 (unique-id ,ARG3)))
    (hash-size)))
if-search-bucketfunction
(defun if-search-bucket
  (x y z lst)
  (cond ((null lst) nil)
    ((and (cst= x (tst (car lst)))
       (cst= y (tbr (car lst)))
       (cst= z (fbr (car lst)))) (car lst))
    (t (if-search-bucket x y z (cdr lst)))))
cst=-lstfunction
(defun cst=-lst
  (x y)
  (cond ((endp x) t)
    (t (and (cst= (car x) (car y)) (cst=-lst (cdr x) (cdr y))))))
eq-opmacro
(defmacro eq-op (x y) `(eq ,X ,Y))
op-search-bucketfunction
(defun op-search-bucket
  (op args lst)
  (cond ((null lst) nil)
    ((and (eq-op op (cadr (car lst)))
       (cst=-lst args (cddr (car lst)))) (car (car lst)))
    (t (op-search-bucket op args (cdr lst)))))
op-search-bucket-2function
(defun op-search-bucket-2
  (op arg1 arg2 lst)
  (cond ((null lst) nil)
    ((and (eq-op op (cadr (car lst)))
       (let ((args (cddr (car lst))))
         (and (cst= arg1 (car args)) (cst= arg2 (cadr args))))) (car (car lst)))
    (t (op-search-bucket-2 op arg1 arg2 (cdr lst)))))
op-search-bucket-iffunction
(defun op-search-bucket-if
  (arg1 arg2 arg3 lst)
  (cond ((null lst) nil)
    ((and (eq-op 'if (cadr (car lst)))
       (let ((args (cddr (car lst))))
         (and (cst= arg1 (car args))
           (cst= arg2 (cadr args))
           (cst= arg3 (caddr args))))) (car (car lst)))
    (t (op-search-bucket-if arg1 arg2 arg3 (cdr lst)))))
chk-memofunction
(defun chk-memo
  (op-code op args op-ht)
  (declare (type (signed-byte 61) op-code))
  (the-mv 2
    (signed-byte 61)
    (let ((n (op-hash-index op-code args)))
      (declare (type (signed-byte 61) n))
      (let ((ans (op-search-bucket op args (aref1 'op-ht op-ht n))))
        (cond (ans (mvf 0 ans)) (t (mvf n nil)))))))
chk-memo-2function
(defun chk-memo-2
  (op-code op arg1 arg2 op-ht)
  (declare (type (signed-byte 61) op-code))
  (the-mv 2
    (signed-byte 61)
    (let ((n (op-hash-index-2 op-code arg1 arg2)))
      (declare (type (signed-byte 61) n))
      (let ((ans (op-search-bucket-2 op arg1 arg2 (aref1 'op-ht op-ht n))))
        (cond (ans (mvf 0 ans)) (t (mvf n nil)))))))
chk-memo-iffunction
(defun chk-memo-if
  (arg1 arg2 arg3 op-ht)
  (the-mv 2
    (signed-byte 61)
    (let ((n (op-hash-index-if arg1 arg2 arg3)))
      (declare (type (signed-byte 61) n))
      (let ((ans (op-search-bucket-if arg1 arg2 arg3 (aref1 'op-ht op-ht n))))
        (cond (ans (mvf 0 ans)) (t (mvf n nil)))))))
half-hash-sizemacro
(defmacro half-hash-size nil (floor (hash-size) 2))
fourth-hash-sizemacro
(defmacro fourth-hash-size nil (floor (hash-size) 4))
op-hash-index-stringfunction
(defun op-hash-index-string
  (index acc string)
  (declare (type (signed-byte 61) index acc))
  (the-fixnum (cond ((= index 0) acc)
      (t (let ((index (1- (the-fixnum index))))
          (declare (type (signed-byte 61) index))
          (op-hash-index-string index
            (logandf (hash-size)
              (+f acc (char-code (char string index))))
            string))))))
op-hash-index-evgfunction
(defun op-hash-index-evg
  (evg)
  (the-fixnum (cond ((integerp evg) (logandf (hash-size) evg))
      ((rationalp evg) (logandf (hash-size)
          (+ (numerator evg) (* 17 (denominator evg)))))
      ((acl2-numberp evg) (logandf (hash-size)
          (+f (op-hash-index-evg (realpart evg))
            (op-hash-index-evg (imagpart evg)))))
      ((characterp evg) (+f (fourth-hash-size) (char-code evg)))
      ((symbolp evg) (logandf (hash-size)
          (*f 19 (op-hash-index-evg (symbol-name evg)))))
      ((stringp evg) (the-fixnum (op-hash-index-string (the-fixnum! (length evg) 'bdd)
            (half-hash-size)
            evg)))
      (t (logandf (hash-size)
          (+f (op-hash-index-evg (car evg))
            (*f 2 (op-hash-index-evg (cdr evg)))))))))
op-search-bucket-quotefunction
(defun op-search-bucket-quote
  (evg bucket)
  (cond ((null bucket) nil)
    ((and (eq-op 'quote (cadr (car bucket)))
       (equal evg (caddr (car bucket)))) (car (car bucket)))
    (t (op-search-bucket-quote evg (cdr bucket)))))
chk-memo-quotepfunction
(defun chk-memo-quotep
  (term op-ht)
  (the-mv 2
    (signed-byte 61)
    (let ((n (op-hash-index-evg (cadr term))))
      (declare (type (signed-byte 61) n))
      (let ((ans (op-search-bucket-quote (cadr term) (aref1 'op-ht op-ht n))))
        (cond (ans (mvf 0 ans)) (t (mvf n nil)))))))
bdd-quotepfunction
(defun bdd-quotep
  (term op-ht mx-id)
  (declare (type (signed-byte 61) mx-id))
  (the-mv 3
    (signed-byte 61)
    (cond ((equal term *t*) (mvf mx-id *cst-t* op-ht))
      ((equal term *nil*) (mvf mx-id *cst-nil* op-ht))
      (t (mv-let (hash-index ans)
          (chk-memo-quotep term op-ht)
          (declare (type (signed-byte 61) hash-index))
          (cond (ans (mvf mx-id ans op-ht))
            (t (let ((new-mx-id (1+mx-id mx-id)))
                (declare (type (signed-byte 61) new-mx-id))
                (let ((new-cst (make-leaf-cst new-mx-id term nil)))
                  (mvf new-mx-id
                    new-cst
                    (aset1-trusted 'op-ht
                      op-ht
                      hash-index
                      (cons (cons new-cst term) (aref1 'op-ht op-ht hash-index)))))))))))))
bdd-quotep+macro
(defmacro bdd-quotep+
  (term op-ht if-ht mx-id ttree)
  `(mv-let (mx-id cst op-ht)
    (bdd-quotep ,TERM ,OP-HT ,MX-ID)
    (declare (type (signed-byte 61) mx-id))
    (mvf mx-id cst op-ht ,IF-HT ,TTREE)))
other
(defrec bdd-rule (lhs rhs . rune) t)
rewrite-rule-to-bdd-rulefunction
(defun rewrite-rule-to-bdd-rule
  (lemma)
  (make bdd-rule
    :lhs (access rewrite-rule lemma :lhs)
    :rhs (access rewrite-rule lemma :rhs)
    :rune (access rewrite-rule lemma :rune)))
bdd-rules-alist1function
(defun bdd-rules-alist1
  (recp lemmas ens all-fns nondef-rules def-rules new-fns)
  (cond ((endp lemmas) (mv new-fns nondef-rules def-rules))
    (t (let ((subclass (access rewrite-rule (car lemmas) :subclass)))
        (cond ((and (eq (access rewrite-rule (car lemmas) :equiv) 'equal)
             (enabled-numep (access rewrite-rule (car lemmas) :nume) ens)
             (case subclass
               (definition (and (null recp)
                   (null (access rewrite-rule (car lemmas) :hyps))
                   (subsetp-eq (all-vars (access rewrite-rule (car lemmas) :rhs))
                     (all-vars (access rewrite-rule (car lemmas) :lhs)))))
               (abbreviation (subsetp-eq (all-vars (access rewrite-rule (car lemmas) :rhs))
                   (all-vars (access rewrite-rule (car lemmas) :lhs))))
               (backchain (and (null (access rewrite-rule (car lemmas) :hyps))
                   (null (access rewrite-rule (car lemmas) :heuristic-info))
                   (subsetp-eq (all-vars (access rewrite-rule (car lemmas) :rhs))
                     (all-vars (access rewrite-rule (car lemmas) :lhs)))))
               (otherwise nil))) (bdd-rules-alist1 recp
              (cdr lemmas)
              ens
              all-fns
              (if (eq subclass 'definition)
                nondef-rules
                (cons (rewrite-rule-to-bdd-rule (car lemmas)) nondef-rules))
              (if (eq subclass 'definition)
                (cons (rewrite-rule-to-bdd-rule (car lemmas)) def-rules)
                def-rules)
              (union-eq (set-difference-eq (all-fnnames (access rewrite-rule (car lemmas) :rhs))
                  all-fns)
                new-fns)))
          (t (bdd-rules-alist1 recp
              (cdr lemmas)
              ens
              all-fns
              nondef-rules
              def-rules
              new-fns)))))))
extra-rules-for-bddsfunction
(defun extra-rules-for-bdds
  (fn wrld)
  (cond ((eq fn 'equal) (list (make rewrite-rule
          :nume nil
          :hyps nil
          :equiv 'equal
          :subclass 'backchain
          :heuristic-info nil
          :backchain-limit-lst *initial-default-backchain-limit*
          :rune *fake-rune-for-anonymous-enabled-rule*
          :lhs (fcons-term* 'equal *nil* 'x)
          :var-info t
          :rhs (fcons-term* 'if 'x *nil* *t*))
        (make rewrite-rule
          :nume nil
          :hyps nil
          :equiv 'equal
          :subclass 'backchain
          :heuristic-info nil
          :backchain-limit-lst *initial-default-backchain-limit*
          :rune *fake-rune-for-anonymous-enabled-rule*
          :lhs (fcons-term* 'equal 'x *nil*)
          :var-info t
          :rhs (fcons-term* 'if 'x *nil* *t*))))
    ((eq fn 'consp) (list (make rewrite-rule
          :nume nil
          :hyps nil
          :equiv 'equal
          :subclass 'backchain
          :heuristic-info nil
          :backchain-limit-lst *initial-default-backchain-limit*
          :rune *fake-rune-for-anonymous-enabled-rule*
          :lhs (fcons-term* 'consp (fcons-term* 'cons 'x 'y))
          :var-info t
          :rhs *t*)))
    ((equivalence-relationp fn wrld) (list (make rewrite-rule
          :nume nil
          :hyps nil
          :equiv 'equal
          :subclass 'abbreviation
          :heuristic-info nil
          :backchain-limit-lst *initial-default-backchain-limit*
          :rune (equivalence-rune fn wrld)
          :lhs (fcons-term* fn 'x 'x)
          :var-info t
          :rhs *t*)))
    ((eq fn 'mv-nth) (list (make rewrite-rule
          :nume nil
          :hyps nil
          :equiv 'equal
          :subclass 'backchain
          :heuristic-info nil
          :backchain-limit-lst *initial-default-backchain-limit*
          :rune (fn-rune-nume 'mv-nth nil nil wrld)
          :lhs (fcons-term* 'mv-nth 'n (fcons-term* 'cons 'x 'y))
          :var-info t
          :rhs (fcons-term* 'if
            (fcons-term* 'zp 'n)
            'x
            (fcons-term* 'mv-nth
              (fcons-term* 'binary-+ 'n (kwote -1))
              'y)))))
    (t nil)))
bdd-rules-alistfunction
(defun bdd-rules-alist
  (fns all-fns bdd-rules-alist ens wrld)
  (cond ((endp fns) (mv all-fns bdd-rules-alist))
    (t (mv-let (new-fns nondef-rules def-rules)
        (bdd-rules-alist1 (recursivep (car fns) t wrld)
          (append (getpropc (car fns) 'lemmas nil wrld)
            (extra-rules-for-bdds (car fns) wrld))
          ens
          (cons (car fns) all-fns)
          nil
          nil
          nil)
        (cond ((or def-rules nondef-rules) (bdd-rules-alist (append new-fns (cdr fns))
              (append new-fns all-fns)
              (cons (cons (car fns)
                  (cons (reverse nondef-rules) (reverse def-rules)))
                bdd-rules-alist)
              ens
              wrld))
          (t (bdd-rules-alist (cdr fns) all-fns bdd-rules-alist ens wrld)))))))
one-way-unify1-cst-2macro
(defmacro one-way-unify1-cst-2
  (mx-id p1 p2 cst1 cst2 alist op-ht)
  `(mv-let (mx-id ans alist1 op-ht)
    (one-way-unify1-cst ,MX-ID ,P1 ,CST1 ,ALIST ,OP-HT)
    (declare (type (signed-byte 61) mx-id))
    (cond (ans (mv-let (mx-id ans alist2 op-ht)
          (one-way-unify1-cst mx-id ,P2 ,CST2 alist1 op-ht)
          (declare (type (signed-byte 61) mx-id))
          (cond (ans (mvf mx-id t alist2 op-ht))
            (t (mvf mx-id nil ,ALIST op-ht)))))
      (t (mvf mx-id nil ,ALIST op-ht)))))
one-way-unify1-cst-3macro
(defmacro one-way-unify1-cst-3
  (mx-id p1 p2 p3 cst1 cst2 cst3 alist op-ht)
  `(mv-let (mx-id ans alist2 op-ht)
    (one-way-unify1-cst-2 ,MX-ID
      ,P1
      ,P2
      ,CST1
      ,CST2
      ,ALIST
      ,OP-HT)
    (declare (type (signed-byte 61) mx-id))
    (cond (ans (mv-let (mx-id ans alist3 op-ht)
          (one-way-unify1-cst mx-id ,P3 ,CST3 alist2 op-ht)
          (declare (type (signed-byte 61) mx-id))
          (cond (ans (mvf mx-id t alist3 op-ht))
            (t (mvf mx-id nil ,ALIST op-ht)))))
      (t (mvf mx-id nil ,ALIST op-ht)))))
one-way-unify1-cstmutual-recursion
(mutual-recursion (defun one-way-unify1-cst
    (mx-id pat cst alist op-ht)
    (declare (type (signed-byte 61) mx-id))
    (the-mv 4
      (signed-byte 61)
      (cond ((variablep pat) (let ((pair (assoc-eq pat alist)))
            (cond (pair (cond ((cst= (cdr pair) cst) (mvf mx-id t alist op-ht))
                  (t (mvf mx-id nil alist op-ht))))
              (t (mvf mx-id t (cons (cons pat cst) alist) op-ht)))))
        ((not (leafp cst)) (cond ((fquotep pat) (mvf mx-id nil alist op-ht))
            ((eq (ffn-symb pat) 'if) (one-way-unify1-cst-3 mx-id
                (fargn pat 1)
                (fargn pat 2)
                (fargn pat 3)
                (tst cst)
                (tbr cst)
                (fbr cst)
                alist
                op-ht))
            (t (mvf mx-id nil alist op-ht))))
        (t (let ((term (trm cst)))
            (cond ((fquotep pat) (cond ((equal pat term) (mvf mx-id t alist op-ht))
                  (t (mvf mx-id nil alist op-ht))))
              ((variablep term) (mvf mx-id nil alist op-ht))
              ((fquotep term) (cond ((acl2-numberp (cadr term)) (let ((ffn-symb (ffn-symb pat)))
                      (case ffn-symb
                        (binary-+ (cond ((quotep (fargn pat 1)) (mv-let (mx-id cst op-ht)
                                (bdd-quotep (kwote (- (cadr term) (fix (cadr (fargn pat 1)))))
                                  op-ht
                                  mx-id)
                                (declare (type (signed-byte 61) mx-id))
                                (one-way-unify1-cst mx-id (fargn pat 2) cst alist op-ht)))
                            ((quotep (fargn pat 2)) (mv-let (mx-id cst op-ht)
                                (bdd-quotep (kwote (- (cadr term) (fix (cadr (fargn pat 2)))))
                                  op-ht
                                  mx-id)
                                (declare (type (signed-byte 61) mx-id))
                                (one-way-unify1-cst mx-id (fargn pat 1) cst alist op-ht)))
                            (t (mvf mx-id nil alist op-ht))))
                        (binary-* (cond ((and (quotep (fargn pat 1))
                               (integerp (cadr (fargn pat 1)))
                               (> (abs (cadr (fargn pat 1))) 1)) (mv-let (mx-id cst op-ht)
                                (bdd-quotep (kwote (/ (cadr term) (cadr (fargn pat 1))))
                                  op-ht
                                  mx-id)
                                (declare (type (signed-byte 61) mx-id))
                                (one-way-unify1-cst mx-id (fargn pat 2) cst alist op-ht)))
                            ((and (quotep (fargn pat 2))
                               (integerp (cadr (fargn pat 2)))
                               (> (abs (cadr (fargn pat 2))) 1)) (mv-let (mx-id cst op-ht)
                                (bdd-quotep (kwote (/ (cadr term) (cadr (fargn pat 2))))
                                  op-ht
                                  mx-id)
                                (declare (type (signed-byte 61) mx-id))
                                (one-way-unify1-cst mx-id (fargn pat 1) cst alist op-ht)))
                            (t (mvf mx-id nil alist op-ht))))
                        (unary-- (cond ((>= (+ (realpart (cadr term)) (imagpart (cadr term))) 0) (mvf mx-id nil alist op-ht))
                            (t (mv-let (mx-id cst op-ht)
                                (bdd-quotep (kwote (- (cadr term))) op-ht mx-id)
                                (declare (type (signed-byte 30) mx-id))
                                (one-way-unify1-cst mx-id (fargn pat 1) cst alist op-ht)))))
                        (unary-/ (cond ((or (>= (* (cadr term) (conjugate (cadr term))) 1)
                               (eql 0 (cadr term))) (mvf mx-id nil alist op-ht))
                            (t (mv-let (mx-id cst op-ht)
                                (bdd-quotep (kwote (/ (cadr term))) op-ht mx-id)
                                (declare (type (signed-byte 30) mx-id))
                                (one-way-unify1-cst mx-id (fargn pat 1) cst alist op-ht)))))
                        (otherwise (mvf mx-id nil alist op-ht)))))
                  ((consp (cadr term)) (cond ((eq (ffn-symb pat) 'cons) (mv-let (mx-id cst1 op-ht)
                          (bdd-quotep (kwote (car (cadr term))) op-ht mx-id)
                          (declare (type (signed-byte 61) mx-id))
                          (mv-let (mx-id ans alist1 op-ht)
                            (one-way-unify1-cst mx-id (fargn pat 1) cst1 alist op-ht)
                            (declare (type (signed-byte 61) mx-id))
                            (cond (ans (mv-let (mx-id cst2 op-ht)
                                  (bdd-quotep (kwote (cdr (cadr term))) op-ht mx-id)
                                  (declare (type (signed-byte 61) mx-id))
                                  (mv-let (mx-id ans alist2 op-ht)
                                    (one-way-unify1-cst mx-id (fargn pat 2) cst2 alist1 op-ht)
                                    (declare (type (signed-byte 61) mx-id))
                                    (cond (ans (mvf mx-id t alist2 op-ht))
                                      (t (mvf mx-id nil alist op-ht))))))
                              (t (mvf mx-id nil alist op-ht))))))
                      (t (mvf mx-id nil alist op-ht))))
                  (t (mvf mx-id nil alist op-ht))))
              ((eq (ffn-symb pat) (ffn-symb term)) (cond ((eq (ffn-symb pat) 'equal) (one-way-unify1-cst-equal mx-id
                      (fargn pat 1)
                      (fargn pat 2)
                      (fargn term 1)
                      (fargn term 2)
                      alist
                      op-ht))
                  (t (mv-let (mx-id ans alist1 op-ht)
                      (one-way-unify1-cst-lst mx-id
                        (fargs pat)
                        (fargs term)
                        alist
                        op-ht)
                      (declare (type (signed-byte 61) mx-id))
                      (cond (ans (mvf mx-id t alist1 op-ht))
                        (t (mvf mx-id nil alist op-ht)))))))
              (t (mvf mx-id nil alist op-ht))))))))
  (defun one-way-unify1-cst-lst
    (mx-id pl cstl alist op-ht)
    (declare (type (signed-byte 61) mx-id))
    (the-mv 4
      (signed-byte 61)
      (cond ((null pl) (mvf mx-id t alist op-ht))
        (t (mv-let (mx-id ans alist op-ht)
            (one-way-unify1-cst mx-id (car pl) (car cstl) alist op-ht)
            (declare (type (signed-byte 61) mx-id))
            (cond (ans (one-way-unify1-cst-lst mx-id
                  (cdr pl)
                  (cdr cstl)
                  alist
                  op-ht))
              (t (mvf mx-id nil alist op-ht))))))))
  (defun one-way-unify1-cst-equal
    (mx-id pat1 pat2 cst1 cst2 alist op-ht)
    (declare (type (signed-byte 61) mx-id))
    (the-mv 4
      (signed-byte 61)
      (mv-let (mx-id ans alist op-ht)
        (one-way-unify1-cst-2 mx-id pat1 pat2 cst1 cst2 alist op-ht)
        (declare (type (signed-byte 61) mx-id))
        (cond (ans (mvf mx-id t alist op-ht))
          (t (one-way-unify1-cst-2 mx-id pat2 pat1 cst1 cst2 alist op-ht)))))))
some-one-way-unify-cst-lstfunction
(defun some-one-way-unify-cst-lst
  (cst-lst rules op-ht mx-id ttree)
  (declare (type (signed-byte 61) mx-id))
  (the-mv 6
    (signed-byte 61)
    (cond ((endp rules) (mvf mx-id nil nil nil op-ht ttree))
      (t (mv-let (mx-id ans alist op-ht)
          (one-way-unify1-cst-lst mx-id
            (fargs (access bdd-rule (car rules) :lhs))
            cst-lst
            nil
            op-ht)
          (declare (type (signed-byte 61) mx-id))
          (cond (ans (mvf mx-id
                t
                (access bdd-rule (car rules) :rhs)
                alist
                op-ht
                (push-lemma (access bdd-rule (car rules) :rune) ttree)))
            (t (some-one-way-unify-cst-lst cst-lst
                (cdr rules)
                op-ht
                mx-id
                ttree))))))))
leaf-cst-listfunction
(defun leaf-cst-list
  (lst bool-vars acc mx-id)
  (cond ((endp lst) (mv mx-id acc))
    (t (mv-let (mx-id acc)
        (cond ((assoc-eq (car lst) acc) (mv mx-id acc))
          (t (let ((new-mx-id (1+mx-id mx-id)))
              (mv new-mx-id
                (cons (make-leaf-cst new-mx-id
                    (car lst)
                    (member-eq (car lst) bool-vars))
                  acc)))))
        (leaf-cst-list (cdr lst) bool-vars acc mx-id)))))
decode-cstmutual-recursion
(mutual-recursion (defun decode-cst
    (cst cst-array)
    (let ((term (aref1 'cst-array cst-array (unique-id cst))))
      (cond (term (mv term cst-array))
        ((leafp cst) (cond ((or (variablep (trm cst)) (fquotep (trm cst))) (mv (trm cst) cst-array))
            (t (mv-let (args cst-array)
                (decode-cst-lst (fargs (trm cst)) cst-array)
                (let ((x (cons-term (ffn-symb (trm cst)) args)))
                  (mv x
                    (aset1-trusted 'cst-array cst-array (unique-id cst) x)))))))
        (t (mv-let (tst cst-array)
            (decode-cst (tst cst) cst-array)
            (mv-let (tbr cst-array)
              (decode-cst (tbr cst) cst-array)
              (mv-let (fbr cst-array)
                (decode-cst (fbr cst) cst-array)
                (let ((x (mcons-term* 'if tst tbr fbr)))
                  (mv x
                    (aset1-trusted 'cst-array cst-array (unique-id cst) x))))))))))
  (defun decode-cst-lst
    (cst-lst cst-array)
    (cond ((endp cst-lst) (mv nil cst-array))
      (t (mv-let (first cst-array)
          (decode-cst (car cst-lst) cst-array)
          (mv-let (rest cst-array)
            (decode-cst-lst (cdr cst-lst) cst-array)
            (mv (cons first rest) cst-array)))))))
decode-cst-alist1function
(defun decode-cst-alist1
  (alist cst-array)
  (cond ((endp alist) (mv nil cst-array))
    (t (mv-let (term cst-array)
        (decode-cst (cdar alist) cst-array)
        (mv-let (rest cst-array)
          (decode-cst-alist1 (cdr alist) cst-array)
          (mv (cons (list (caar alist) term) rest) cst-array))))))
decode-cst-alistfunction
(defun decode-cst-alist
  (cst-alist cst-array)
  (mv-let (alist cst-array)
    (decode-cst-alist1 cst-alist cst-array)
    (declare (ignore cst-array))
    alist))
leaf-cst-list-arrayfunction
(defun leaf-cst-list-array
  (mx-id)
  (let ((dim (1+ mx-id)))
    (compress1 'cst-array
      `((:header :dimensions (,DIM)
         :maximum-length ,(+ 10 DIM)
         :default nil)))))
*some-non-nil-value*constant
(defconst *some-non-nil-value* "Some non-nil value")
falsifying-assignment1function
(defun falsifying-assignment1
  (cst acc cst-array)
  (cond ((cst-nilp cst) (mv acc cst-array))
    ((quotep (trm cst)) (mv (er hard
          'falsifying-assignment1
          "Tried to falsify ~x0!"
          (trm cst))
        cst-array))
    ((leafp cst) (mv-let (term cst-array)
        (decode-cst cst cst-array)
        (mv (cons (list term nil) acc) cst-array)))
    ((cst-nonnilp (tbr cst)) (mv-let (term cst-array)
        (decode-cst (tst cst) cst-array)
        (falsifying-assignment1 (fbr cst)
          (cons (list term nil) acc)
          cst-array)))
    (t (mv-let (term cst-array)
        (decode-cst (tst cst) cst-array)
        (falsifying-assignment1 (tbr cst)
          (cons (list term
              (if (cst-boolp (tst cst))
                t
                *some-non-nil-value*))
            acc)
          cst-array)))))
falsifying-assignmentfunction
(defun falsifying-assignment
  (cst mx-id)
  (mv-let (asst cst-array)
    (falsifying-assignment1 cst nil (leaf-cst-list-array mx-id))
    (declare (ignore cst-array))
    (reverse asst)))
make-iffunction
(defun make-if
  (mx-id n op args x y z op-ht if-ht bdd-constructors)
  (declare (type (signed-byte 61) n mx-id))
  (the-mv 4
    (signed-byte 61)
    (cond ((cst= y z) (mvf mx-id
          y
          (aset1-trusted 'op-ht
            op-ht
            n
            (cons (list* y op args) (aref1 'op-ht op-ht n)))
          if-ht))
      (t (let ((m (if-hash-index x y z)))
          (declare (type (signed-byte 61) m))
          (let* ((bucket (aref1 'if-ht if-ht m)) (old-if (if-search-bucket x y z bucket)))
            (cond (old-if (mvf mx-id
                  old-if
                  (aset1-trusted 'op-ht
                    op-ht
                    n
                    (cons (list* old-if op args) (aref1 'op-ht op-ht n)))
                  if-ht))
              ((and (cst-tp y) (cst-nilp z) (cst-boolp x)) (mvf mx-id
                  x
                  (aset1-trusted 'op-ht
                    op-ht
                    n
                    (cons (list* x op args) (aref1 'op-ht op-ht n)))
                  if-ht))
              (t (let ((mx-id (1+mx-id mx-id)))
                  (declare (type (signed-byte 61) mx-id))
                  (mv-let (erp new-if)
                    (make-if-cst mx-id x y z bdd-constructors)
                    (cond (erp (mvf mx-id (car erp) (cdr erp) new-if))
                      (t (mvf mx-id
                          new-if
                          (aset1-trusted 'op-ht
                            op-ht
                            n
                            (cons (list* new-if op args) (aref1 'op-ht op-ht n)))
                          (aset1-trusted 'if-ht if-ht m (cons new-if bucket)))))))))))))))
make-if-no-memofunction
(defun make-if-no-memo
  (mx-id x y z op-ht if-ht bdd-constructors)
  (declare (type (signed-byte 61) mx-id))
  (the-mv 4
    (signed-byte 61)
    (let ((m (if-hash-index x y z)))
      (declare (type (signed-byte 61) m))
      (let* ((bucket (aref1 'if-ht if-ht m)) (old-if (if-search-bucket x y z bucket)))
        (cond (old-if (mvf mx-id old-if op-ht if-ht))
          ((and (cst-tp y) (cst-nilp z) (cst-boolp x)) (mvf mx-id x op-ht if-ht))
          (t (let ((mx-id (1+mx-id mx-id)))
              (declare (type (signed-byte 61) mx-id))
              (mv-let (erp new-if)
                (make-if-cst mx-id x y z bdd-constructors)
                (cond (erp (mvf mx-id (car erp) (cdr erp) new-if))
                  (t (mvf mx-id
                      new-if
                      op-ht
                      (aset1-trusted 'if-ht if-ht m (cons new-if bucket)))))))))))))
split-varmacro
(defmacro split-var
  (cst)
  `(if (leafp ,CST)
    (if (and (cst-varp ,CST) (cst-boolp ,CST))
      ,CST
      nil)
    (tst ,CST)))
min-varfunction
(defun min-var
  (acc args)
  (declare (xargs :measure (acl2-count args)))
  (if (endp args)
    acc
    (let ((var (split-var (car args))))
      (if (null var)
        (min-var acc (cdr args))
        (min-var (cond ((null acc) var)
            ((< (unique-id var) (unique-id acc)) var)
            (t acc))
          (cdr args))))))
combine-op-csts1function
(defun combine-op-csts1
  (var-id args)
  (declare (type (signed-byte 61) var-id))
  (if (endp args)
    (mv nil nil)
    (mv-let (x y)
      (combine-op-csts1 var-id (cdr args))
      (cond ((leafp (car args)) (if (and (= (the-fixnum var-id) (unique-id (car args)))
              (cst-boolp (car args)))
            (mv (cons *cst-t* x) (cons *cst-nil* y))
            (mv (cons (car args) x) (cons (car args) y))))
        (t (if (= (the-fixnum var-id) (unique-id (tst (car args))))
            (mv (cons (tbr (car args)) x) (cons (fbr (car args)) y))
            (mv (cons (car args) x) (cons (car args) y))))))))
bool-flgfunction
(defun bool-flg
  (args mask)
  (cond ((endp args) mask)
    ((car mask) (and (cst-boolp (car args))
        (bool-flg (cdr args) (cdr mask))))
    (t (bool-flg (cdr args) (cdr mask)))))
some-bdd-constructorpfunction
(defun some-bdd-constructorp
  (args bdd-constructors)
  (cond ((endp args) nil)
    (t (or (and (leafp (car args))
          (bdd-constructor-trm-p (trm (car args)) bdd-constructors))
        (some-bdd-constructorp (cdr args) bdd-constructors)))))
combine-op-csts-simplefunction
(defun combine-op-csts-simple
  (hash-index op
    mask
    args
    op-ht
    if-ht
    mx-id
    bdd-constructors
    ttree)
  (declare (type (signed-byte 61) hash-index mx-id))
  (the-mv 5
    (signed-byte 61)
    (let ((new-mx-id (1+mx-id mx-id)) (rune (and mask (bool-flg args mask))))
      (declare (type (signed-byte 61) new-mx-id))
      (let ((new-cst (make-leaf-cst new-mx-id (cons op args) rune)))
        (cond ((and bdd-constructors
             (some-bdd-constructorp args bdd-constructors)) (bdd-error new-mx-id
              "Attempted to create ~x0 node during BDD processing with an argument ~
           that is a call of ~#1~[a bdd-constructor~/CONS~], which would ~
           produce a non-BDD term (as defined in :DOC bdd-algorithm).  See ~
           :DOC show-bdd."
              (list (cons #\0 op)
                (cons #\1
                  (if (equal bdd-constructors '(cons))
                    1
                    0)))
              new-cst
              ttree))
          (t (mvf new-mx-id
              new-cst
              (aset1-trusted 'op-ht
                op-ht
                hash-index
                (cons (list* new-cst op args)
                  (aref1 'op-ht op-ht hash-index)))
              if-ht
              (if rune
                (push-lemma rune ttree)
                ttree))))))))
bdd-mv-letmacro
(defmacro bdd-mv-let
  (vars form body)
  (declare (xargs :guard (and (true-listp vars)
        (eq (car vars) 'mx-id)
        (< 2 (length vars))
        (consp form)
        (true-listp form)
        (member-eq (car form)
          '(combine-if-csts+ combine-op-csts
            combine-op-csts+
            combine-op-csts-guts
            combine-op-csts-comm
            bdd
            bdd-alist
            bdd-list)))))
  `(mv-let ,VARS
    ,FORM
    (declare (type (signed-byte 61) mx-id))
    (if (stringp ,(CADR VARS))
      ,(COND
  ((EQ (CAR FORM) 'BDD)
   (LIST 'MVF (CAR VARS) (CADR VARS) (CADDR VARS)
         (LIST 'CONS (LIST 'CONS (CADR FORM) (CADDR FORM)) (CADDDR VARS))
         (CADDDR (CDR VARS))))
  (T (CONS 'MVF VARS)))
      ,BODY)))
combine-if-csts+macro
(defmacro combine-if-csts+
  (cst1 cst2 cst3 op-ht if-ht mx-id bdd-constructors)
  `(cond ((cst-nilp ,CST1) (mvf ,MX-ID ,CST3 ,OP-HT ,IF-HT))
    ((cst-nonnilp ,CST1) (mvf ,MX-ID ,CST2 ,OP-HT ,IF-HT))
    (t (combine-if-csts ,CST1
        ,CST2
        ,CST3
        ,OP-HT
        ,IF-HT
        ,MX-ID
        ,BDD-CONSTRUCTORS))))
combine-if-csts1function
(defun combine-if-csts1
  (var-id args)
  (declare (type (signed-byte 61) var-id))
  (mv-let (x y)
    (combine-op-csts1 var-id (cdr args))
    (cond ((leafp (car args)) (if (= (the-fixnum var-id) (unique-id (car args)))
          (mv (cons *cst-t* x) (cons *cst-nil* y))
          (mv (cons (car args) x) (cons (car args) y))))
      (t (if (= (the-fixnum var-id) (unique-id (tst (car args))))
          (mv (cons (tbr (car args)) x) (cons (fbr (car args)) y))
          (mv (cons (car args) x) (cons (car args) y)))))))
combine-if-cstsfunction
(defun combine-if-csts
  (test-cst true-cst
    false-cst
    op-ht
    if-ht
    mx-id
    bdd-constructors)
  (declare (type (signed-byte 61) mx-id))
  (the-mv 4
    (signed-byte 61)
    (cond ((cst= true-cst false-cst) (mvf mx-id true-cst op-ht if-ht))
      ((cst= test-cst false-cst) (combine-if-csts test-cst
          true-cst
          *cst-nil*
          op-ht
          if-ht
          mx-id
          bdd-constructors))
      ((and (cst= test-cst true-cst) (cst-boolp true-cst)) (combine-if-csts test-cst
          *cst-t*
          false-cst
          op-ht
          if-ht
          mx-id
          bdd-constructors))
      ((and (cst-nilp false-cst)
         (if (cst-tp true-cst)
           (cst-boolp test-cst)
           (cst= test-cst true-cst))) (mvf mx-id test-cst op-ht if-ht))
      (t (let ((true-var (split-var true-cst)) (false-var (split-var false-cst)))
          (cond ((and (leafp test-cst)
               (or (null true-var)
                 (< (unique-id test-cst) (unique-id true-var)))
               (or (null false-var)
                 (< (unique-id test-cst) (unique-id false-var)))) (make-if-no-memo mx-id
                test-cst
                true-cst
                false-cst
                op-ht
                if-ht
                bdd-constructors))
            (t (mv-let (hash-index ans)
                (chk-memo-if test-cst true-cst false-cst op-ht)
                (declare (type (signed-byte 61) hash-index))
                (cond (ans (mvf mx-id ans op-ht if-ht))
                  (t (let* ((args (list test-cst true-cst false-cst)) (min-var (min-var nil args)))
                      (mv-let (args1 args2)
                        (combine-if-csts1 (unique-id min-var) args)
                        (bdd-mv-let (mx-id cst1 op-ht if-ht)
                          (combine-if-csts+ (car args1)
                            (cadr args1)
                            (caddr args1)
                            op-ht
                            if-ht
                            mx-id
                            bdd-constructors)
                          (bdd-mv-let (mx-id cst2 op-ht if-ht)
                            (combine-if-csts+ (car args2)
                              (cadr args2)
                              (caddr args2)
                              op-ht
                              if-ht
                              mx-id
                              bdd-constructors)
                            (make-if mx-id
                              hash-index
                              'if
                              args
                              min-var
                              cst1
                              cst2
                              op-ht
                              if-ht
                              bdd-constructors)))))))))))))))
cst-list-to-evg-listfunction
(defun cst-list-to-evg-list
  (cst-lst)
  (cond ((endp cst-lst) nil)
    (t (cons (cadr (trm (car cst-lst)))
        (cst-list-to-evg-list (cdr cst-lst))))))
cst-quote-listpfunction
(defun cst-quote-listp
  (cst-lst)
  (cond ((endp cst-lst) t)
    ((and (leafp (car cst-lst)) (quotep (trm (car cst-lst)))) (cst-quote-listp (cdr cst-lst)))
    (t nil)))
other
(defrec bddspv
  (op-alist bdd-rules-alist . bdd-constructors)
  t)
bdd-ev-fncallfunction
(defun bdd-ev-fncall
  (mx-id hash-index
    op
    mask
    args
    op-ht
    if-ht
    bdd-constructors
    rune
    ttree
    state)
  (declare (type (signed-byte 61) hash-index mx-id))
  (the-mv 5
    (signed-byte 61)
    (mv-let (erp val latches)
      (ev-fncall op
        (cst-list-to-evg-list args)
        nil
        state
        nil
        nil
        nil)
      (declare (ignore latches))
      (cond (erp (combine-op-csts-simple hash-index
            op
            mask
            args
            op-ht
            if-ht
            mx-id
            (and (not (member-eq op bdd-constructors)) bdd-constructors)
            ttree))
        (t (bdd-quotep+ (list 'quote val)
            op-ht
            if-ht
            mx-id
            (push-lemma rune ttree)))))))
combine-op-csts+macro
(defmacro combine-op-csts+
  (mx-id comm-p
    enabled-exec-p
    op-code
    op
    mask
    args
    op-ht
    if-ht
    op-bdd-rules
    ttree
    bddspv)
  `(if ,COMM-P
    (combine-op-csts-comm ,MX-ID
      ,COMM-P
      ,ENABLED-EXEC-P
      ,OP-CODE
      ,OP
      ,MASK
      (car ,ARGS)
      (cadr ,ARGS)
      ,ARGS
      ,OP-HT
      ,IF-HT
      ,OP-BDD-RULES
      ,TTREE
      ,BDDSPV
      state)
    (combine-op-csts ,MX-ID
      ,ENABLED-EXEC-P
      ,OP-CODE
      ,OP
      ,MASK
      ,ARGS
      ,OP-HT
      ,IF-HT
      ,OP-BDD-RULES
      ,TTREE
      ,BDDSPV
      state)))
make-if-for-opfunction
(defun make-if-for-op
  (mx-id hash-index
    op
    args
    test-cst
    true-cst
    false-cst
    op-ht
    if-ht
    bdd-constructors)
  (declare (type (signed-byte 61) hash-index mx-id))
  (the-mv 4
    (signed-byte 61)
    (cond ((cst= true-cst false-cst) (mvf mx-id
          true-cst
          (aset1-trusted 'op-ht
            op-ht
            hash-index
            (cons (list* true-cst op args)
              (aref1 'op-ht op-ht hash-index)))
          if-ht))
      ((let ((true-split-var (split-var true-cst)) (false-split-var (split-var false-cst))
           (test-id (unique-id test-cst)))
         (declare (type (signed-byte 61) test-id))
         (and (or (null true-split-var)
             (< test-id (unique-id true-split-var)))
           (or (null false-split-var)
             (< test-id (unique-id false-split-var))))) (make-if mx-id
          hash-index
          op
          args
          test-cst
          true-cst
          false-cst
          op-ht
          if-ht
          bdd-constructors))
      (t (bdd-mv-let (mx-id cst op-ht if-ht)
          (combine-if-csts+ test-cst
            true-cst
            false-cst
            op-ht
            if-ht
            mx-id
            bdd-constructors)
          (mvf mx-id
            cst
            (aset1-trusted 'op-ht
              op-ht
              hash-index
              (cons (list* cst op args) (aref1 'op-ht op-ht hash-index)))
            if-ht))))))
combine-op-cstsmutual-recursion
(mutual-recursion (defun combine-op-csts
    (mx-id enabled-exec-p
      op-code
      op
      mask
      args
      op-ht
      if-ht
      op-bdd-rules
      ttree
      bddspv
      state)
    (declare (type (signed-byte 61) op-code mx-id))
    (the-mv 5
      (signed-byte 61)
      (mv-let (hash-index ans)
        (chk-memo op-code op args op-ht)
        (declare (type (signed-byte 61) hash-index))
        (cond (ans (mvf mx-id ans op-ht if-ht ttree))
          ((and enabled-exec-p (cst-quote-listp args)) (bdd-ev-fncall mx-id
              hash-index
              op
              mask
              args
              op-ht
              if-ht
              (access bddspv bddspv :bdd-constructors)
              enabled-exec-p
              ttree
              state))
          ((and (eq op 'booleanp) (cst-boolp (car args))) (mvf mx-id
              *cst-t*
              op-ht
              if-ht
              (push-lemma (fn-rune-nume 'booleanp nil nil (w state))
                ttree)))
          (t (combine-op-csts-guts mx-id
              nil
              hash-index
              enabled-exec-p
              op-code
              op
              mask
              args
              op-ht
              if-ht
              op-bdd-rules
              ttree
              bddspv
              state))))))
  (defun combine-op-csts-comm
    (mx-id comm-p
      enabled-exec-p
      op-code
      op
      mask
      arg1
      arg2
      args
      op-ht
      if-ht
      op-bdd-rules
      ttree
      bddspv
      state)
    (declare (type (signed-byte 61) op-code mx-id))
    (the-mv 5
      (signed-byte 61)
      (cond ((and (eq op 'equal) (cst= arg1 arg2)) (mvf mx-id
            *cst-t*
            op-ht
            if-ht
            (push-lemma (fn-rune-nume 'equal nil nil (w state)) ttree)))
        (t (mv-let (arg1 arg2 args ttree)
            (cond ((and (quotep arg2) (not (quotep arg1))) (mv arg2 arg1 nil (push-lemma comm-p ttree)))
              ((< (unique-id arg2) (unique-id arg1)) (mv arg2 arg1 nil (push-lemma comm-p ttree)))
              (t (mv arg1 arg2 args ttree)))
            (mv-let (hash-index ans)
              (chk-memo-2 op-code op arg1 arg2 op-ht)
              (declare (type (signed-byte 61) hash-index))
              (cond (ans (mvf mx-id ans op-ht if-ht ttree))
                ((and (eq op 'equal) (cst-tp arg1) (cst-boolp arg2)) (mvf mx-id
                    arg2
                    op-ht
                    if-ht
                    (push-lemma (fn-rune-nume 'equal nil nil (w state)) ttree)))
                ((and enabled-exec-p (quotep (trm arg1)) (quotep (trm arg2))) (bdd-ev-fncall mx-id
                    hash-index
                    op
                    mask
                    (or args (list arg1 arg2))
                    op-ht
                    if-ht
                    (access bddspv bddspv :bdd-constructors)
                    enabled-exec-p
                    ttree
                    state))
                (t (combine-op-csts-guts mx-id
                    comm-p
                    hash-index
                    enabled-exec-p
                    op-code
                    op
                    mask
                    (or args (list arg1 arg2))
                    op-ht
                    if-ht
                    op-bdd-rules
                    ttree
                    bddspv
                    state)))))))))
  (defun combine-op-csts-guts
    (mx-id comm-p
      hash-index
      enabled-exec-p
      op-code
      op
      mask
      args
      op-ht
      if-ht
      op-bdd-rules
      ttree
      bddspv
      state)
    (declare (type (signed-byte 61) op-code mx-id hash-index))
    (the-mv 5
      (signed-byte 61)
      (mv-let (mx-id ans rhs alist op-ht ttree)
        (some-one-way-unify-cst-lst args
          (car op-bdd-rules)
          op-ht
          mx-id
          ttree)
        (declare (type (signed-byte 61) mx-id))
        (cond (ans (bdd-mv-let (mx-id cst op-ht if-ht ttree)
              (bdd rhs alist op-ht if-ht mx-id ttree bddspv state)
              (mvf mx-id
                cst
                (aset1-trusted 'op-ht
                  op-ht
                  hash-index
                  (cons (list* cst op args) (aref1 'op-ht op-ht hash-index)))
                if-ht
                ttree)))
          (t (let ((bdd-constructors (access bddspv bddspv :bdd-constructors)))
              (cond ((member-eq op bdd-constructors) (combine-op-csts-simple hash-index
                    op
                    mask
                    args
                    op-ht
                    if-ht
                    mx-id
                    nil
                    ttree))
                (t (mv-let (mx-id ans rhs alist op-ht ttree)
                    (some-one-way-unify-cst-lst args
                      (cdr op-bdd-rules)
                      op-ht
                      mx-id
                      ttree)
                    (declare (type (signed-byte 61) mx-id))
                    (cond (ans (bdd-mv-let (mx-id cst op-ht if-ht ttree)
                          (bdd rhs alist op-ht if-ht mx-id ttree bddspv state)
                          (mvf mx-id
                            cst
                            (aset1-trusted 'op-ht
                              op-ht
                              hash-index
                              (cons (list* cst op args) (aref1 'op-ht op-ht hash-index)))
                            if-ht
                            ttree)))
                      (t (let ((min-var (min-var nil args)))
                          (cond ((null min-var) (combine-op-csts-simple hash-index
                                op
                                mask
                                args
                                op-ht
                                if-ht
                                mx-id
                                bdd-constructors
                                ttree))
                            (t (mv-let (args1 args2)
                                (combine-op-csts1 (unique-id min-var) args)
                                (bdd-mv-let (mx-id cst1 op-ht if-ht ttree)
                                  (combine-op-csts+ mx-id
                                    comm-p
                                    enabled-exec-p
                                    op-code
                                    op
                                    mask
                                    args1
                                    op-ht
                                    if-ht
                                    op-bdd-rules
                                    ttree
                                    bddspv)
                                  (bdd-mv-let (mx-id cst2 op-ht if-ht ttree)
                                    (combine-op-csts+ mx-id
                                      comm-p
                                      enabled-exec-p
                                      op-code
                                      op
                                      mask
                                      args2
                                      op-ht
                                      if-ht
                                      op-bdd-rules
                                      ttree
                                      bddspv)
                                    (mv-let (mx-id ans op-ht if-ht)
                                      (make-if-for-op mx-id
                                        hash-index
                                        op
                                        args
                                        min-var
                                        cst1
                                        cst2
                                        op-ht
                                        if-ht
                                        bdd-constructors)
                                      (declare (type (signed-byte 61) mx-id))
                                      (cond ((stringp ans) (bdd-error mx-id ans op-ht if-ht ttree))
                                        (t (mvf mx-id ans op-ht if-ht ttree)))))))))))))))))))))
  (defun bdd
    (term alist op-ht if-ht mx-id ttree bddspv state)
    (declare (xargs :measure (acl2-count term)
        :guard (pseudo-termp term))
      (type (signed-byte 61) mx-id))
    (the-mv 5
      (signed-byte 61)
      (cond ((variablep term) (mvf mx-id
            (or (cdr (assoc-eq term alist))
              (er hard 'bdd "Didn't find variable ~x0!" term))
            op-ht
            if-ht
            ttree))
        ((fquotep term) (cond ((eq (cadr term) t) (mvf mx-id *cst-t* op-ht if-ht ttree))
            ((eq (cadr term) nil) (mvf mx-id *cst-nil* op-ht if-ht ttree))
            (t (bdd-quotep+ term op-ht if-ht mx-id ttree))))
        ((or (eq (ffn-symb term) 'if) (eq (ffn-symb term) 'if*)) (bdd-mv-let (mx-id test-cst op-ht if-ht ttree)
            (bdd (fargn term 1)
              alist
              op-ht
              if-ht
              mx-id
              (if (eq (ffn-symb term) 'if)
                ttree
                (push-lemma (fn-rune-nume 'if* nil nil (w state)) ttree))
              bddspv
              state)
            (cond ((cst-nilp test-cst) (bdd (fargn term 3)
                  alist
                  op-ht
                  if-ht
                  mx-id
                  ttree
                  bddspv
                  state))
              ((cst-nonnilp test-cst) (bdd (fargn term 2)
                  alist
                  op-ht
                  if-ht
                  mx-id
                  ttree
                  bddspv
                  state))
              ((eq (ffn-symb term) 'if*) (bdd-error mx-id
                  "Unable to resolve test of IF* for term~|~%~p0~|~%under the ~
          bindings~|~%~x1~|~%-- use SHOW-BDD to see a backtrace."
                  (list (cons #\0 (untranslate term nil (w state)))
                    (cons #\1
                      (decode-cst-alist alist (leaf-cst-list-array mx-id))))
                  *cst-t*
                  ttree))
              (t (bdd-mv-let (mx-id true-cst op-ht if-ht ttree)
                  (bdd (fargn term 2)
                    alist
                    op-ht
                    if-ht
                    mx-id
                    ttree
                    bddspv
                    state)
                  (bdd-mv-let (mx-id false-cst op-ht if-ht ttree)
                    (bdd (fargn term 3)
                      alist
                      op-ht
                      if-ht
                      mx-id
                      ttree
                      bddspv
                      state)
                    (mv-let (mx-id cst op-ht if-ht)
                      (combine-if-csts test-cst
                        true-cst
                        false-cst
                        op-ht
                        if-ht
                        mx-id
                        (access bddspv bddspv :bdd-constructors))
                      (declare (type (signed-byte 61) mx-id))
                      (cond ((stringp cst) (bdd-error mx-id cst op-ht if-ht ttree))
                        (t (mvf mx-id cst op-ht if-ht ttree))))))))))
        ((flambdap (ffn-symb term)) (bdd-mv-let (mx-id alist op-ht if-ht ttree)
            (bdd-alist (lambda-formals (ffn-symb term))
              (fargs term)
              alist
              op-ht
              if-ht
              mx-id
              ttree
              bddspv
              state)
            (bdd (lambda-body (ffn-symb term))
              alist
              op-ht
              if-ht
              mx-id
              ttree
              bddspv
              state)))
        (t (mv-let (opcode comm-p enabled-exec-p mask)
            (op-alist-info (ffn-symb term)
              (access bddspv bddspv :op-alist))
            (declare (type (signed-byte 61) opcode))
            (cond (comm-p (bdd-mv-let (mx-id arg1 op-ht if-ht ttree)
                  (bdd (fargn term 1)
                    alist
                    op-ht
                    if-ht
                    mx-id
                    ttree
                    bddspv
                    state)
                  (bdd-mv-let (mx-id arg2 op-ht if-ht ttree)
                    (bdd (fargn term 2)
                      alist
                      op-ht
                      if-ht
                      mx-id
                      ttree
                      bddspv
                      state)
                    (combine-op-csts-comm mx-id
                      comm-p
                      enabled-exec-p
                      opcode
                      (ffn-symb term)
                      mask
                      arg1
                      arg2
                      nil
                      op-ht
                      if-ht
                      (cdr (assoc-eq (ffn-symb term)
                          (access bddspv bddspv :bdd-rules-alist)))
                      ttree
                      bddspv
                      state))))
              (t (bdd-mv-let (mx-id lst op-ht if-ht ttree)
                  (bdd-list (fargs term)
                    alist
                    op-ht
                    if-ht
                    mx-id
                    ttree
                    bddspv
                    state)
                  (combine-op-csts mx-id
                    enabled-exec-p
                    opcode
                    (ffn-symb term)
                    mask
                    lst
                    op-ht
                    if-ht
                    (cdr (assoc-eq (ffn-symb term)
                        (access bddspv bddspv :bdd-rules-alist)))
                    ttree
                    bddspv
                    state)))))))))
  (defun bdd-alist
    (formals actuals alist op-ht if-ht mx-id ttree bddspv state)
    (declare (type (signed-byte 61) mx-id))
    (the-mv 5
      (signed-byte 61)
      (cond ((endp formals) (mvf mx-id nil op-ht if-ht ttree))
        (t (bdd-mv-let (mx-id bdd op-ht if-ht ttree)
            (bdd (car actuals)
              alist
              op-ht
              if-ht
              mx-id
              ttree
              bddspv
              state)
            (bdd-mv-let (mx-id rest-alist op-ht if-ht ttree)
              (bdd-alist (cdr formals)
                (cdr actuals)
                alist
                op-ht
                if-ht
                mx-id
                ttree
                bddspv
                state)
              (mvf mx-id
                (cons (cons (car formals) bdd) rest-alist)
                op-ht
                if-ht
                ttree)))))))
  (defun bdd-list
    (lst alist op-ht if-ht mx-id ttree bddspv state)
    (declare (type (signed-byte 61) mx-id))
    (the-mv 5
      (signed-byte 61)
      (cond ((endp lst) (mvf mx-id nil op-ht if-ht ttree))
        (t (bdd-mv-let (mx-id bdd op-ht if-ht ttree)
            (bdd (car lst) alist op-ht if-ht mx-id ttree bddspv state)
            (bdd-mv-let (mx-id rest op-ht if-ht ttree)
              (bdd-list (cdr lst)
                alist
                op-ht
                if-ht
                mx-id
                ttree
                bddspv
                state)
              (mvf mx-id (cons bdd rest) op-ht if-ht ttree))))))))
if-ht-max-lengthfunction
(defun if-ht-max-length
  (state)
  (if (f-boundp-global 'if-ht-max-length state)
    (f-get-global 'if-ht-max-length state)
    (+ 100000 (hash-size))))
op-ht-max-lengthfunction
(defun op-ht-max-length
  (state)
  (if (f-boundp-global 'op-ht-max-length state)
    (f-get-global 'op-ht-max-length state)
    (+ 100000 (hash-size))))
leaf-cst-list-to-alistfunction
(defun leaf-cst-list-to-alist
  (leaf-cst-list)
  (cond ((endp leaf-cst-list) nil)
    (t (cons (cons (trm (car leaf-cst-list)) (car leaf-cst-list))
        (leaf-cst-list-to-alist (cdr leaf-cst-list))))))
bdd-topfunction
(defun bdd-top
  (term input-vars bool-vars bdd-constructors cl-id ens state)
  (let* ((fns (all-fnnames term)) (wrld (w state)))
    (mv-let (fns bdd-rules-alist)
      (bdd-rules-alist (remove1-eq 'if fns)
        (add-to-set-eq 'if fns)
        nil
        ens
        wrld)
      (let ((op-alist (op-alist fns nil 6 ens wrld)) (if-ht (compress1 'if-ht
              `((:header :dimensions (,(1+ (HASH-SIZE)))
                 :maximum-length ,(IF-HT-MAX-LENGTH STATE)
                 :default nil))))
          (op-ht (compress1 'op-ht
              `((:header :dimensions (,(1+ (HASH-SIZE)))
                 :maximum-length ,(OP-HT-MAX-LENGTH STATE)
                 :default nil))))
          (all-vars (let ((term-vars (reverse (all-vars term))))
              (cond ((not (symbol-listp input-vars)) (er hard
                    'bdd-top
                    "The second argument of BDD-TOP must ~
                                          be a list of variables, but ~x0 is ~
                                          not."
                    input-vars))
                ((subsetp-eq term-vars input-vars) input-vars)
                (t (er hard
                    'bdd-top
                    "The following variables are free ~
                                            in the input term, ~x0, but not do ~
                                            not occur in the specified input ~
                                            variables, ~x1:  ~x2."
                    term
                    input-vars
                    (set-difference-eq term-vars input-vars)))))))
        (mv-let (mx-id leaf-cst-list)
          (leaf-cst-list all-vars
            bool-vars
            nil
            (max (unique-id *cst-nil*) (unique-id *cst-t*)))
          (mv-let (mx-id cst op-ht if-ht ttree)
            (bdd term
              (leaf-cst-list-to-alist leaf-cst-list)
              op-ht
              if-ht
              mx-id
              nil
              (make bddspv
                :op-alist op-alist
                :bdd-rules-alist bdd-rules-alist
                :bdd-constructors bdd-constructors)
              state)
            (cond ((stringp cst) (make bddnote
                  :cl-id cl-id
                  :goal-term term
                  :mx-id mx-id
                  :err-string cst
                  :fmt-alist (car op-ht)
                  :cst (cdr op-ht)
                  :term nil
                  :bdd-call-stack if-ht
                  :ttree ttree))
              (t (make bddnote
                  :cl-id cl-id
                  :goal-term term
                  :mx-id mx-id
                  :err-string nil
                  :fmt-alist nil
                  :cst cst
                  :term nil
                  :bdd-call-stack nil
                  :ttree ttree)))))))))
get-bool-varsfunction
(defun get-bool-vars
  (vars type-alist ttree acc)
  (cond ((endp vars) (mv acc ttree))
    (t (let ((entry (assoc-eq (car vars) type-alist)))
        (cond ((and entry (ts-subsetp (cadr entry) *ts-boolean*)) (get-bool-vars (cdr vars)
              type-alist
              (cons-tag-trees (cddr entry) ttree)
              (cons (car vars) acc)))
          (t (get-bool-vars (cdr vars) type-alist ttree acc)))))))
bdd-clause1function
(defun bdd-clause1
  (hint-alist type-alist
    cl
    position
    ttree0
    cl-id
    ens
    wrld
    state)
  (let* ((term (case position
         (:conc (mcons-term* 'if (car (last cl)) *t* *nil*))
         (:all (mcons-term* 'if (disjoin cl) *t* *nil*))
         (otherwise (let ((lit (nth position cl)))
             (case-match lit
               (('not x) (mcons-term* 'if x *t* *nil*))
               (& (mcons-term* 'not lit))))))) (all-vars (all-vars term))
      (vars-hint (cdr (assoc-eq :vars hint-alist)))
      (prove-hint (if (assoc-eq :prove hint-alist)
          (cdr (assoc-eq :prove hint-alist))
          t))
      (bdd-constructors-hint (if (assoc-eq :bdd-constructors hint-alist)
          (cdr (assoc-eq :bdd-constructors hint-alist))
          (bdd-constructors wrld))))
    (mv-let (bool-vars ttree1)
      (get-bool-vars all-vars type-alist ttree0 nil)
      (cond ((not (subsetp-eq (if (eq vars-hint t)
               all-vars
               vars-hint)
             bool-vars)) (let ((bad-vars (set-difference-eq (if (eq vars-hint t)
                   all-vars
                   vars-hint)
                 bool-vars)))
            (mv 'error
              (msg "The following variable~#0~[ is~/s are~] not known to be ~
                   Boolean by trivial (type set) reasoning:  ~&0.  Perhaps you ~
                   need to add hypotheses to that effect.  Alternatively, you ~
                   may want to prove :type-prescription rules (see :DOC ~
                   type-prescription) or :forward-chaining (see :DOC ~
                   forward-chaining) rules to help with the situation, or ~
                   perhaps to start with the hint ~x1."
                bad-vars
                (list :cases (if (consp (cdr bad-vars))
                    (list (cons 'and
                        (pairlis$ (make-list (length bad-vars) :initial-element 'booleanp)
                          (pairlis$ bad-vars nil))))
                    `((booleanp ,(CAR BAD-VARS))))))
              nil)))
        (t (let* ((real-vars-hint (if (eq vars-hint t)
                 nil
                 vars-hint)) (bddnote (bdd-top term
                  (append real-vars-hint
                    (set-difference-eq (reverse all-vars) real-vars-hint))
                  bool-vars
                  bdd-constructors-hint
                  cl-id
                  ens
                  state))
              (cst (access bddnote bddnote :cst))
              (err-string (access bddnote bddnote :err-string))
              (ttree (access bddnote bddnote :ttree)))
            (cond (err-string (if prove-hint
                  (mv 'error
                    (cons (access bddnote bddnote :err-string)
                      (access bddnote bddnote :fmt-alist))
                    bddnote)
                  (mv 'miss nil bddnote)))
              ((cst-tp cst) (mv 'hit
                  nil
                  (add-to-tag-tree 'bddnote
                    bddnote
                    (cons-tag-trees ttree ttree1))))
              (prove-hint (mv 'error
                  (list "The :BDD hint for the current goal has ~
                      successfully simplified this goal, but has ~
                      failed to prove it.  Consider using (SHOW-BDD) ~
                      to suggest a counterexample; see :DOC show-bdd.")
                  bddnote))
              (t (mv-let (new-term cst-array)
                  (decode-cst cst
                    (leaf-cst-list-array (access bddnote bddnote :mx-id)))
                  (declare (ignore cst-array))
                  (let* ((bddnote (change bddnote bddnote :term new-term)) (ttree (add-to-tag-tree 'bddnote
                          bddnote
                          (cons-tag-trees ttree ttree1))))
                    (cond ((eq position :conc) (mv 'hit
                          (list (add-literal new-term (butlast cl 1) t))
                          ttree))
                      ((eq position :all) (mv 'hit (list (add-literal new-term nil nil)) ttree))
                      (t (mv 'hit
                          (list (subst-for-nth-arg (dumb-negate-lit new-term) position cl))
                          ttree)))))))))))))
expand-and-or-simple+macro
(defmacro expand-and-or-simple+
  (term bool fns-to-be-ignored-by-rewrite wrld ttree)
  `(mv-let (hitp lst ttree1)
    (expand-and-or-simple ,TERM
      ,BOOL
      ,FNS-TO-BE-IGNORED-BY-REWRITE
      ,WRLD
      ,TTREE)
    (cond (hitp (mv hitp lst ttree1))
      (t (mv t (list ,TERM) ,TTREE)))))
expand-and-or-simplefunction
(defun expand-and-or-simple
  (term bool fns-to-be-ignored-by-rewrite wrld ttree)
  (cond ((variablep term) (mv nil nil ttree))
    ((fquotep term) (cond ((equal term *nil*) (if bool
            (mv t nil ttree)
            (mv nil nil ttree)))
        ((equal term *t*) (if bool
            (mv nil nil ttree)
            (mv t nil ttree)))
        (t (if bool
            (mv t (list *t*) ttree)
            (mv t nil ttree)))))
    ((member-equal (ffn-symb term) fns-to-be-ignored-by-rewrite) (mv nil nil ttree))
    ((flambda-applicationp term) (mv-let (hitp lst ttree0)
        (expand-and-or-simple (lambda-body (ffn-symb term))
          bool
          fns-to-be-ignored-by-rewrite
          wrld
          ttree)
        (cond (hitp (mv hitp
              (subcor-var-lst (lambda-formals (ffn-symb term))
                (fargs term)
                lst)
              ttree0))
          (t (mv nil nil ttree)))))
    ((eq (ffn-symb term) 'not) (mv-let (hitp lst ttree0)
        (expand-and-or-simple (fargn term 1)
          (not bool)
          fns-to-be-ignored-by-rewrite
          wrld
          ttree)
        (cond (hitp (mv hitp
              (dumb-negate-lit-lst lst)
              (push-lemma (fn-rune-nume 'not nil nil wrld) ttree0)))
          (t (mv nil nil ttree)))))
    ((and (eq (ffn-symb term) 'implies) bool) (expand-and-or-simple (subcor-var (formals 'implies wrld)
          (fargs term)
          (bbody 'implies))
        bool
        fns-to-be-ignored-by-rewrite
        wrld
        (push-lemma (fn-rune-nume 'implies nil nil wrld) ttree)))
    ((eq (ffn-symb term) 'if) (let ((t1 (fargn term 1)) (t2 (fargn term 2))
          (t3 (fargn term 3)))
        (cond ((or (equal t1 *nil*) (equal t2 t3)) (expand-and-or-simple+ t3
              bool
              fns-to-be-ignored-by-rewrite
              wrld
              ttree))
          ((quotep t1) (expand-and-or-simple+ t2
              bool
              fns-to-be-ignored-by-rewrite
              wrld
              ttree))
          ((and (quotep t2) (quotep t3)) (cond ((equal t2 *nil*) (mv-let (hitp lst ttree)
                  (expand-and-or-simple t1
                    (not bool)
                    fns-to-be-ignored-by-rewrite
                    wrld
                    ttree)
                  (mv t
                    (if hitp
                      (dumb-negate-lit-lst lst)
                      (list (dumb-negate-lit t1)))
                    ttree)))
              ((equal t3 *nil*) (expand-and-or-simple+ t1
                  bool
                  fns-to-be-ignored-by-rewrite
                  wrld
                  ttree))
              (t (expand-and-or-simple *t*
                  bool
                  fns-to-be-ignored-by-rewrite
                  wrld
                  ttree))))
          ((and (quotep t3) (eq (not bool) (equal t3 *nil*))) (mv-let (hitp lst1 ttree)
              (expand-and-or-simple+ t1
                nil
                fns-to-be-ignored-by-rewrite
                wrld
                ttree)
              (declare (ignore hitp))
              (mv-let (hitp lst2 ttree)
                (expand-and-or-simple+ t2
                  bool
                  fns-to-be-ignored-by-rewrite
                  wrld
                  ttree)
                (declare (ignore hitp))
                (if bool
                  (mv t (union-equal (dumb-negate-lit-lst lst1) lst2) ttree)
                  (mv t (union-equal lst1 lst2) ttree)))))
          ((and (quotep t2) (eq (not bool) (equal t2 *nil*))) (mv-let (hitp lst1 ttree)
              (expand-and-or-simple+ t1
                t
                fns-to-be-ignored-by-rewrite
                wrld
                ttree)
              (declare (ignore hitp))
              (mv-let (hitp lst2 ttree)
                (expand-and-or-simple+ t3
                  bool
                  fns-to-be-ignored-by-rewrite
                  wrld
                  ttree)
                (declare (ignore hitp))
                (if bool
                  (mv t (union-equal lst1 lst2) ttree)
                  (mv t (union-equal (dumb-negate-lit-lst lst1) lst2) ttree)))))
          (t (mv nil nil ttree)))))
    (t (mv nil nil ttree))))
expand-clausefunction
(defun expand-clause
  (cl fns-to-be-ignored-by-rewrite wrld ttree acc)
  (cond ((endp cl) (mv acc ttree))
    (t (mv-let (hitp lst ttree)
        (expand-and-or-simple+ (car cl)
          t
          fns-to-be-ignored-by-rewrite
          wrld
          ttree)
        (declare (ignore hitp))
        (expand-clause (cdr cl)
          fns-to-be-ignored-by-rewrite
          wrld
          ttree
          (union-equal lst acc))))))
bdd-clausefunction
(defun bdd-clause
  (bdd-hint cl-id top-clause pspv wrld state)
  (let ((rcnst (access prove-spec-var pspv :rewrite-constant)) (literal-hint (or (cdr (assoc-eq :literal bdd-hint)) :all)))
    (cond ((and (integerp literal-hint)
         (not (< literal-hint (1- (length top-clause))))) (mv 'error
          (msg "There ~#0~[are no hypotheses~/is only one hypothesis~/are only ~
                ~n0 hypotheses~] in this goal, but your :BDD hint suggested ~
                that there would be at least ~x1 ~
                ~#1~[~/hypothesis~/hypotheses]."
            (1- (length top-clause))
            (1+ literal-hint))
          nil
          pspv))
      (t (mv-let (hitp current-clause
            current-clause-pts
            remove-trivial-equivalences-ttree)
          (remove-trivial-equivalences top-clause
            (enumerate-elements top-clause 0)
            t
            (access rewrite-constant rcnst :current-enabled-structure)
            wrld
            state
            nil)
          (declare (ignore hitp))
          (let ((position (cond ((integerp literal-hint) (position literal-hint current-clause-pts))
                 (t literal-hint))))
            (cond ((or (null position)
                 (and (eq literal-hint :conc)
                   (not (member (1- (length top-clause)) current-clause-pts)))) (mv 'error
                  (msg "The attempt to use a :BDD hint for the goal named ~
                            "~@0" has failed.  The problem is that the hint ~
                            specified that BDD processing was to be used on ~
                            the ~#1~[~n2 hypothesis~/conclusion~], which has ~
                            somehow disappeared.  One possibility is that this ~
                            literal is an equivalence that has disappeared ~
                            after being used for substitution into the rest of ~
                            the goal.  Another possibility is that this ~
                            literal has merged with another.  We suspect, ~
                            therefore, that you would benefit by reconsidering ~
                            this :BDD hint, possibly attaching it to a ~
                            subsequent goal instead."
                    (tilde-@-clause-id-phrase cl-id)
                    (if (null position)
                      0
                      1)
                    (if (null position)
                      (1+ literal-hint)
                      0))
                  nil
                  pspv))
              (t (let ((ens (access rewrite-constant rcnst :current-enabled-structure)))
                  (mv-let (expanded-clause ttree)
                    (expand-clause current-clause
                      (access rewrite-constant
                        rcnst
                        :fns-to-be-ignored-by-rewrite)
                      wrld
                      remove-trivial-equivalences-ttree
                      nil)
                    (mv-let (contradictionp type-alist fc-pair-lst)
                      (forward-chain-top 'bdd-clause
                        expanded-clause
                        nil
                        nil
                        t
                        wrld
                        ens
                        (match-free-override wrld)
                        state)
                      (cond (contradictionp (mv 'hit nil (cons-tag-trees ttree fc-pair-lst) pspv))
                        (t (mv-let (changedp clauses ttree)
                            (bdd-clause1 bdd-hint
                              type-alist
                              current-clause
                              position
                              ttree
                              cl-id
                              ens
                              wrld
                              state)
                            (mv changedp clauses ttree pspv)))))))))))))))