Filtering...

symbolic-arithmetic

books/centaur/gl/symbolic-arithmetic
other
(in-package "GL")
other
(include-book "bvecs")
other
(include-book "bfr-reasoning")
other
(local (include-book "clause-processors/find-subterms" :dir :system))
other
(local (include-book "centaur/bitops/ihsext-basics" :dir :system))
other
(local (include-book "arithmetic/top-with-meta" :dir :system))
other
(local (include-book "arith-lemmas"))
other
(local (defthm equal-complexes-rw
    (implies (and (acl2-numberp x)
        (rationalp a)
        (rationalp b))
      (equal (equal (complex a b) x)
        (and (equal a (realpart x))
          (equal b (imagpart x)))))
    :hints (("goal" :use ((:instance realpart-imagpart-elim))))))
other
(defsection symbolic-arithmetic
  :parents (reference)
  :short "Internal operations for computing on symbolic bit vectors."
  :long "<p>Naming convention:</p>
<ul>
<li>B stands for a boolean variable.</li>
<li>S stands for a signed bvec.</li>
<li>U stands for an unsigned bvec.</li>
<li>V stands for a generic bvec where signedness doesn't matter.</li>
<li>N stands for a known natural constant.</li>
</ul>

<p>For instance, @('bfr-ite-bss-fn') has @('bss'), indicating that it's
for computing:</p>

@({
     (ite Boolean Signed-Bvec Signed-Bvec)
})")
other
(local (set-default-parents symbolic-arithmetic))
other
(define int-set-sign
  ((negp "True if we should set the sign bit to 1.") (i integerp "The integer to modify."))
  :short "Change the sign bit of an integer to a new value."
  :returns (new-i integerp :rule-classes :type-prescription)
  (let ((i (lifix i)))
    (logapp (integer-length i)
      i
      (if negp
        -1
        0)))
  ///
  (defthm sign-of-int-set-sign
    (iff (< (int-set-sign negp i) 0) negp)
    :hints (("Goal" :in-theory (e/d* (int-set-sign) (logapp ifix-under-int-equiv))))))
other
(define non-int-fix
  (x)
  :short "Identity for non-integers; coerces any integers to @('nil')."
  (declare (xargs :guard t))
  (and (not (integerp x)) x)
  ///
  (defthm non-int-fix-when-non-integer
    (implies (not (integerp x))
      (equal (non-int-fix x) x))
    :hints (("Goal" :in-theory (enable non-int-fix)))
    :rule-classes ((:rewrite :backchain-limit-lst 0))))
other
(define maybe-integer
  ((i integerp) x intp)
  (if intp
    (ifix i)
    (non-int-fix x))
  ///
  (defthm maybe-integer-t
    (equal (maybe-integer i x t) (ifix i))
    :hints (("Goal" :in-theory (enable maybe-integer))))
  (defthm maybe-integer-nil
    (equal (maybe-integer i x nil)
      (non-int-fix x))
    :hints (("Goal" :in-theory (enable maybe-integer)))))
extract-some-keywordsfunction
(defun extract-some-keywords
  (legal-kwds args kwd-alist)
  "Returns (mv kwd-alist other-args other-keywords)"
  (declare (xargs :guard (and (symbol-listp legal-kwds)
        (no-duplicatesp legal-kwds)
        (alistp kwd-alist))))
  (b* (((when (atom args)) (mv kwd-alist nil args)) (arg1 (first args))
      ((unless (and (keywordp arg1) (consp (cdr args)))) (b* (((mv kwd-alist other-kws other-args) (extract-some-keywords legal-kwds
               (cdr args)
               kwd-alist)))
          (mv kwd-alist
            other-kws
            (cons arg1 other-args))))
      ((unless (member arg1 legal-kwds)) (b* (((mv kwd-alist other-kws other-args) (extract-some-keywords legal-kwds
               (cddr args)
               kwd-alist)))
          (mv kwd-alist
            (cons arg1 (cons (cadr args) other-kws))
            other-args)))
      (value (second args))
      (kwd-alist (acons arg1 value kwd-alist)))
    (extract-some-keywords legal-kwds
      (cddr args)
      kwd-alist)))
defsymbolic-check-formalsfunction
(defun defsymbolic-check-formals
  (x)
  (if (atom x)
    t
    (if (and (consp (car x))
        (eql (len (car x)) 2)
        (symbolp (caar x))
        (member (cadar x)
          '(n i p b u s ru rs)))
      (defsymbolic-check-formals (cdr x))
      (er hard?
        'defsymbolic-check-formals
        "Bad formal: ~x0"
        (car x)))))
defsymbolic-check-returnsfunction
(defun defsymbolic-check-returns
  (x)
  (if (atom x)
    t
    (if (and (consp (car x))
        (>= (len (car x)) 2)
        (symbolp (caar x))
        (member (cadar x)
          '(n i p b u s ru rs))
        (or (member (cadar x) '(n i))
          (eql (len (car x)) 3)))
      (defsymbolic-check-returns (cdr x))
      (er hard?
        'defsymbolic-check-returns
        "Bad return: ~x0"
        (car x)))))
defsymbolic-formals-pair-with-evalsfunction
(defun defsymbolic-formals-pair-with-evals
  (x)
  (if (atom x)
    nil
    (cons (cons (caar x)
        (case (cadar x)
          (n `(nfix ,(CAAR GL::X)))
          (i `(ifix ,(CAAR GL::X)))
          (p `(pos-fix ,(CAAR GL::X)))
          (b `(bfr-eval ,(CAAR GL::X) env))
          (u `(bfr-list->u ,(CAAR GL::X) env))
          (s `(bfr-list->s ,(CAAR GL::X) env))
          (ru `(bfr-list->u (rev ,(CAAR GL::X)) env))
          (rs `(bfr-list->s (rev ,(CAAR GL::X)) env))))
      (defsymbolic-formals-pair-with-evals (cdr x)))))
defsymbolic-define-formalsfunction
(defun defsymbolic-define-formals
  (x)
  (if (atom x)
    nil
    (cons (case (cadar x)
        (n `(,(CAAR GL::X) natp))
        (i `(,(CAAR GL::X) integerp))
        (p `(,(CAAR GL::X) posp))
        ((u s ru rs) `(,(CAAR GL::X) true-listp))
        (t (caar x)))
      (defsymbolic-define-formals (cdr x)))))
defsymbolic-guardsfunction
(defun defsymbolic-guards
  (x)
  (if (atom x)
    nil
    (append (case (cadar x)
        (n `((natp ,(CAAR GL::X))))
        (i `((integerp ,(CAAR GL::X))))
        (p `((posp ,(CAAR GL::X))))
        ((u s ru rs) `((true-listp ,(CAAR GL::X)))))
      (defsymbolic-guards (cdr x)))))
defsymbolic-define-returns1function
(defun defsymbolic-define-returns1
  (x)
  (if (atom x)
    nil
    (cons (case (cadar x)
        (n `(,(CAAR GL::X) natp :rule-classes :type-prescription))
        (i `(,(CAAR GL::X) integerp :rule-classes :type-prescription))
        (p `(,(CAAR GL::X) posp :rule-classes :type-prescription))
        (b `(,(CAAR GL::X) t))
        (t `(,(CAAR GL::X) true-listp
            :rule-classes :type-prescription)))
      (defsymbolic-define-returns1 (cdr x)))))
defsymbolic-define-returnsfunction
(defun defsymbolic-define-returns
  (x)
  (let ((rets (defsymbolic-define-returns1 x)))
    (if (atom (cdr rets))
      (car rets)
      (cons 'mv rets))))
defsymbolic-spec-termfunction
(defun defsymbolic-spec-term
  (formal-evals retspec)
  (if (eql (len retspec) 3)
    (sublis formal-evals (third retspec))
    (if (and (eql (len retspec) 5)
        (eq (fourth retspec) :cond))
      `(implies ,(SUBLIS GL::FORMAL-EVALS (FIFTH GL::RETSPEC))
        ,(SUBLIS GL::FORMAL-EVALS (THIRD GL::RETSPEC)))
      (er hard?
        'defsymbolic
        "bad return-spec: ~x0~%"
        retspec))))
defsymbolic-return-specsfunction
(defun defsymbolic-return-specs
  (x formal-evals)
  (if (atom x)
    nil
    (append (b* ((spec-term (defsymbolic-spec-term formal-evals (car x))))
        (case (cadar x)
          ((n i p) (and (third (car x))
              `((equal ,(CAAR GL::X) ,GL::SPEC-TERM))))
          (b `((equal (bfr-eval ,(CAAR GL::X) env) ,GL::SPEC-TERM)))
          (u `((equal (bfr-list->u ,(CAAR GL::X) env)
               ,GL::SPEC-TERM)))
          (s `((equal (bfr-list->s ,(CAAR GL::X) env)
               ,GL::SPEC-TERM)))
          (ru `((equal (bfr-list->u (rev ,(CAAR GL::X)) env)
               ,GL::SPEC-TERM)))
          (rs `((equal (bfr-list->s (rev ,(CAAR GL::X)) env)
               ,GL::SPEC-TERM)))))
      (defsymbolic-return-specs (cdr x) formal-evals))))
defsymbolic-not-depends-onfunction
(defun defsymbolic-not-depends-on
  (x)
  (if (atom x)
    nil
    (append (case (cadar x)
        (b `((not (pbfr-depends-on varname param ,(CAAR GL::X)))))
        ((u s ru rs) `((not (pbfr-list-depends-on varname
               param
               ,(CAAR GL::X))))))
      (defsymbolic-not-depends-on (cdr x)))))
induct/expand-fnfunction
(defun induct/expand-fn
  (fn id world)
  (declare (xargs :mode :program))
  (and (not (access clause-id id :pool-lst))
    (let ((formals (formals fn world)))
      (append (and (recursivep fn t world)
          `(:induct (,GL::FN . ,GL::FORMALS)))
        `(:expand ((,GL::FN . ,GL::FORMALS))
          :in-theory (disable (:d ,GL::FN)))))))
induct/expandmacro
(defmacro induct/expand
  (fn)
  `(induct/expand-fn ',GL::FN id world))
defsymbolic-fnfunction
(defun defsymbolic-fn
  (name args)
  (declare (xargs :mode :program))
  (b* (((mv kwd-alist other-kws other-args) (extract-some-keywords '(:spec :returns :correct-hints :depends-hints :correct-hyp :abstract :guard-hints)
         args
         nil)) ((unless (eql (len other-args) 2)) (er hard?
          'defsymbolic-fn
          "Need formals and body in addition to keyword args"))
      (formals (car other-args))
      (body (cadr other-args))
      (abstractp (getarg :abstract nil kwd-alist))
      (returns (cdr (assoc :returns kwd-alist)))
      ((unless (consp returns)) (er hard? 'defsymbolic-fn "Need a returns list"))
      (returns (if (eq (car returns) 'mv)
          (cdr returns)
          (list returns)))
      (- (defsymbolic-check-formals formals))
      (- (defsymbolic-check-returns returns))
      ((when (intersectp-eq (strip-cars formals)
           (strip-cars returns))) (er hard?
          'defsymbolic-fn
          "Formals and returns overlap"))
      (return-binder (if (consp (cdr returns))
          `(mv . ,(GL::STRIP-CARS GL::RETURNS))
          (caar returns)))
      (formal-vars (strip-cars formals))
      (exec-name (if abstractp
          (intern-in-package-of-symbol (concatenate 'string (symbol-name name) "-EXEC")
            name)
          name)))
    `(progn (define ,GL::EXEC-NAME
        ,(GL::DEFSYMBOLIC-DEFINE-FORMALS GL::FORMALS)
        ,@GL::OTHER-KWS
        :verify-guards nil
        :returns ,(GL::DEFSYMBOLIC-DEFINE-RETURNS GL::RETURNS)
        ,(SUBST GL::EXEC-NAME GL::NAME GL::BODY)
        ///
        (verify-guards ,GL::EXEC-NAME
          :hints ,(CDR (ASSOC :GUARD-HINTS GL::KWD-ALIST)))
        (defthm ,(GL::INTERN-IN-PACKAGE-OF-SYMBOL
  (CONCATENATE 'STRING (SYMBOL-NAME GL::EXEC-NAME) "-CORRECT") GL::EXEC-NAME)
          (b* ((,GL::RETURN-BINDER (,GL::EXEC-NAME . ,GL::FORMAL-VARS)))
            ,(LET ((GL::CONCL
        `(AND
          . ,(GL::DEFSYMBOLIC-RETURN-SPECS GL::RETURNS
              (GL::DEFSYMBOLIC-FORMALS-PAIR-WITH-EVALS GL::FORMALS))))
       (GL::CORRECT-HYP (CDR (ASSOC :CORRECT-HYP GL::KWD-ALIST))))
   (IF GL::CORRECT-HYP
       `(GL::IMPLIES ,GL::CORRECT-HYP ,GL::CONCL)
       GL::CONCL)))
          :hints ((induct/expand ,GL::EXEC-NAME) . ,(SUBST GL::EXEC-NAME GL::NAME (CDR (ASSOC :CORRECT-HINTS GL::KWD-ALIST)))))
        (defthm ,(GL::INTERN-IN-PACKAGE-OF-SYMBOL
  (CONCATENATE 'STRING (SYMBOL-NAME GL::EXEC-NAME) "-DEPS") GL::EXEC-NAME)
          (b* ((,GL::RETURN-BINDER (,GL::EXEC-NAME . ,GL::FORMAL-VARS)))
            (implies (and . ,(GL::DEFSYMBOLIC-NOT-DEPENDS-ON GL::FORMALS))
              (and . ,(GL::DEFSYMBOLIC-NOT-DEPENDS-ON GL::RETURNS))))
          :hints ((induct/expand ,GL::EXEC-NAME) . ,(SUBST GL::EXEC-NAME GL::NAME (CDR (ASSOC :DEPENDS-HINTS GL::KWD-ALIST))))))
      ,@(AND GL::ABSTRACTP
       `((GL::ENCAPSULATE
          (((,GL::NAME . ,(REPLICATE (GL::LEN GL::FORMALS) '*)) GL::=>
            ,(IF (CONSP (CDR GL::RETURNS))
                 `(GL::MV . ,(REPLICATE (GL::LEN GL::RETURNS) '*))
                 '*)
            :FORMALS ,GL::FORMAL-VARS :GUARD
            (AND
             ,@(LET ((GL::GUARD
                      (CADR (GL::ASSOC-KEYWORD :GUARD GL::OTHER-KWS))))
                 (AND GL::GUARD `(,GL::GUARD)))
             . ,(GL::DEFSYMBOLIC-GUARDS GL::FORMALS))))
          (GL::LOCAL
           (DEFUN ,GL::NAME ,GL::FORMAL-VARS
             (,GL::EXEC-NAME . ,GL::FORMAL-VARS)))
          (GL::DEFTHM
           ,(GL::INTERN-IN-PACKAGE-OF-SYMBOL
             (CONCATENATE 'STRING (SYMBOL-NAME GL::NAME) "-CORRECT") GL::NAME)
           (GL::B* ((,GL::RETURN-BINDER (,GL::NAME . ,GL::FORMAL-VARS)))
            ,(LET ((GL::CONCL
                    `(AND
                      . ,(GL::DEFSYMBOLIC-RETURN-SPECS GL::RETURNS
                          (GL::DEFSYMBOLIC-FORMALS-PAIR-WITH-EVALS
                           GL::FORMALS))))
                   (GL::CORRECT-HYP (CDR (ASSOC :CORRECT-HYP GL::KWD-ALIST))))
               (IF GL::CORRECT-HYP
                   `(GL::IMPLIES ,GL::CORRECT-HYP ,GL::CONCL)
                   GL::CONCL))))
          (GL::DEFTHM
           ,(GL::INTERN-IN-PACKAGE-OF-SYMBOL
             (CONCATENATE 'STRING (SYMBOL-NAME GL::NAME) "-DEPS") GL::NAME)
           (GL::B* ((,GL::RETURN-BINDER (,GL::NAME . ,GL::FORMAL-VARS)))
            (GL::IMPLIES (AND . ,(GL::DEFSYMBOLIC-NOT-DEPENDS-ON GL::FORMALS))
             (AND . ,(GL::DEFSYMBOLIC-NOT-DEPENDS-ON GL::RETURNS))))))
         (GL::DEFATTACH ,GL::NAME ,GL::EXEC-NAME)))
      (table defsymbolic-forms ',GL::NAME ',GL::ARGS))))
defsymbolicmacro
(defmacro defsymbolic
  (name &rest args)
  (defsymbolic-fn name args))
other
(local (in-theory (e/d* (ihsext-redefs ihsext-inductions pbfr-list-depends-on))))
other
(local (in-theory (disable (force) logext** logext-identity truncate)))
car/cdrmacro
(defmacro car/cdr
  (x)
  `(let* ((a ,GL::X))
    (mbe :logic (mv (car a) (cdr a))
      :exec (if (atom a)
        (mv nil nil)
        (mv (car a) (cdr a))))))
other
(defsymbolic bfr-ite-bvv-fn-aux
  ((c b) (v1 u) (v0 u))
  :returns (vv u
    (if c
      v1
      v0))
  :abstract nil
  :measure (+ (acl2-count v1) (acl2-count v0))
  (b* (((when (and (atom v1) (atom v0))) nil) ((mv v11 v1r) (car/cdr v1))
      ((mv v01 v0r) (car/cdr v0))
      (tail (bfr-ite-bvv-fn-aux c v1r v0r))
      (head (bfr-ite c v11 v01)))
    (bfr-ucons head tail)))
other
(defsymbolic bfr-ite-bvv-fn
  ((c b) (v1 u) (v0 u))
  :returns (vv u
    (if c
      v1
      v0))
  :abstract nil
  (if c
    (if (eq c t)
      (llist-fix v1)
      (bfr-ite-bvv-fn-aux c v1 v0))
    (llist-fix v0)))
other
(defthm bfr-ite-bvv-fn-of-const-tests
  (and (equal (bfr-ite-bvv-fn t v1 v0)
      (list-fix v1))
    (equal (bfr-ite-bvv-fn nil v1 v0)
      (list-fix v0)))
  :hints (("Goal" :in-theory (enable bfr-ite-bvv-fn))))
other
(defthm bfr-ite-bvv-fn-aux-elim
  (implies (and (not (equal c t)) c)
    (equal (bfr-ite-bvv-fn-aux c v1 v0)
      (bfr-ite-bvv-fn c v1 v0)))
  :hints (("Goal" :in-theory (enable bfr-ite-bvv-fn))))
bfr-ite-bvvmacro
(defmacro bfr-ite-bvv
  (c v1 v0)
  `(mbe :logic (bfr-ite-bvv-fn ,GL::C ,GL::V1 ,GL::V0)
    :exec (let ((bfr-ite-bvv-test ,GL::C))
      (if bfr-ite-bvv-test
        (if (eq bfr-ite-bvv-test t)
          (llist-fix ,GL::V1)
          (bfr-ite-bvv-fn-aux bfr-ite-bvv-test
            ,GL::V1
            ,GL::V0))
        (llist-fix ,GL::V0)))))
other
(add-macro-alias bfr-ite-bvv bfr-ite-bvv-fn)
other
(defsymbolic bfr-ite-bss-fn-aux
  ((c b) (v1 s) (v0 s))
  :returns (vv s
    (if c
      v1
      v0))
  :abstract nil
  :measure (+ (acl2-count v1) (acl2-count v0))
  (b* (((mv head1 tail1 end1) (first/rest/end v1)) ((mv head0 tail0 end0) (first/rest/end v0))
      ((when (and end1 end0)) (bfr-sterm (bfr-ite-fn c head1 head0)))
      (rst (bfr-ite-bss-fn-aux c tail1 tail0))
      (head (bfr-ite c head1 head0)))
    (bfr-scons head rst)))
other
(defsymbolic bfr-ite-bss-fn
  ((c b) (v1 s) (v0 s))
  :returns (vv s
    (if c
      v1
      v0))
  :abstract nil
  (if c
    (if (eq c t)
      (llist-fix v1)
      (bfr-ite-bss-fn-aux c v1 v0))
    (llist-fix v0)))
other
(defthm bfr-ite-bss-fn-of-const-tests
  (and (equal (bfr-ite-bss-fn t v1 v0)
      (list-fix v1))
    (equal (bfr-ite-bss-fn nil v1 v0)
      (list-fix v0)))
  :hints (("Goal" :in-theory (enable bfr-ite-bss-fn))))
other
(defthm bfr-ite-bss-fn-aux-elim
  (implies (and (not (equal c t)) c)
    (equal (bfr-ite-bss-fn-aux c v1 v0)
      (bfr-ite-bss-fn c v1 v0)))
  :hints (("Goal" :in-theory (enable bfr-ite-bss-fn))))
bfr-ite-bssmacro
(defmacro bfr-ite-bss
  (c v1 v0)
  `(mbe :logic (bfr-ite-bss-fn ,GL::C ,GL::V1 ,GL::V0)
    :exec (let ((bfr-ite-bss-test ,GL::C))
      (if bfr-ite-bss-test
        (if (eq bfr-ite-bss-test t)
          (llist-fix ,GL::V1)
          (bfr-ite-bss-fn-aux bfr-ite-bss-test
            ,GL::V1
            ,GL::V0))
        (llist-fix ,GL::V0)))))
other
(add-macro-alias bfr-ite-bss bfr-ite-bss-fn)
other
(defsymbolic bfr-loghead-ns
  ((n n) (x s))
  :returns (xx s (loghead n x))
  (b* (((when (zp n)) (bfr-sterm nil)) ((mv head tail ?end) (first/rest/end x)))
    (bfr-scons head
      (bfr-loghead-ns (1- n) tail))))
other
(defsymbolic bfr-logext-ns
  ((n p) (x s))
  :returns (xx s (logext n x))
  :measure (pos-fix n)
  (b* ((n (lposfix n)) ((mv head tail ?end) (first/rest/end x))
      ((when end) (llist-fix x))
      ((when (eql n 1)) (bfr-sterm head)))
    (bfr-scons head
      (bfr-logext-ns (1- n) tail)))
  :correct-hints (("goal" :induct (bfr-logext-ns n x)) (and stable-under-simplificationp
      '(:expand ((:free (x) (logext (pos-fix n) x)))))))
other
(defsymbolic bfr-logtail-ns
  ((place n) (x s))
  :returns (xx s (logtail place x))
  (if (or (zp place) (s-endp x))
    (llist-fix x)
    (bfr-logtail-ns (1- place) (scdr x))))
other
(defsymbolic bfr-+-ss
  ((c b) (v1 s) (v2 s))
  :returns (sum s (+ (bool->bit c) v1 v2))
  :measure (+ (len v1) (len v2))
  (b* (((mv head1 tail1 end1) (first/rest/end v1)) ((mv head2 tail2 end2) (first/rest/end v2))
      (axorb (bfr-xor head1 head2))
      (s (bfr-xor c axorb))
      ((when (and end1 end2)) (let ((last (bfr-ite axorb (bfr-not c) head1)))
          (bfr-scons s (bfr-sterm last))))
      (c (bfr-or (bfr-and c axorb)
          (bfr-and head1 head2)))
      (rst (bfr-+-ss c tail1 tail2)))
    (bfr-scons s rst))
  :correct-hints ('(:in-theory (enable logcons))))
other
(defsymbolic bfr-lognot-s
  ((x s))
  :returns (nx s (lognot x))
  (b* (((mv head tail end) (first/rest/end x)) ((when end) (bfr-sterm (bfr-not head))))
    (bfr-scons (bfr-not head)
      (bfr-lognot-s tail))))
other
(defsymbolic bfr-unary-minus-s
  ((x s))
  :returns (ms s (- x))
  (bfr-+-ss t nil (bfr-lognot-s x))
  :correct-hints ('(:in-theory (enable lognot))))
other
(defsymbolic bfr-logxor-ss
  ((a s) (b s))
  :returns (xab s (logxor a b))
  :measure (+ (len a) (len b))
  (b* (((mv af ar aend) (first/rest/end a)) ((mv bf br bend) (first/rest/end b))
      (c (bfr-xor af bf))
      ((when (and aend bend)) (bfr-sterm c))
      (r (bfr-logxor-ss ar br)))
    (bfr-scons c r)))
other
(defsymbolic bfr-sign-s
  ((x s))
  :returns (sign b (< x 0))
  (b* (((mv first rest endp) (first/rest/end x)) ((when endp) first))
    (bfr-sign-s rest)))
other
(defsymbolic bfr-integer-length-s1
  ((offset p) (x s))
  :measure (len x)
  :returns (mv (not-done b
      (and (not (equal x 0)) (not (equal x -1))))
    (ilen s
      (if (or (equal x 0) (equal x -1))
        0
        (+ -1 offset (integer-length x)))))
  :prepwork ((local (defthm bfr-eval-of-car-when-bfr-list->s
       (implies (and (equal (bfr-list->s x env) c)
           (syntaxp (quotep c)))
         (equal (bfr-eval (car x) env)
           (equal 1 (logcar c)))))))
  (b* (((mv first rest end) (first/rest/end x)) (offset (lposfix offset))
      ((when end) (mv nil nil))
      ((mv changed res) (bfr-integer-length-s1 (1+ offset) rest))
      ((when (eq changed t)) (mv t res))
      (change (bfr-xor first (car rest))))
    (mv (bfr-or changed change)
      (bfr-ite-bss changed
        res
        (bfr-ite-bss change (i2v offset) nil))))
  :correct-hints ((bfr-reasoning)))
other
(defsymbolic bfr-integer-length-s
  ((x s))
  :returns (ilen s (integer-length x))
  (b* (((mv ?changed res) (bfr-integer-length-s1 1 x)))
    res))
other
(define integer-length-bound-s
  (x)
  :returns (bound posp :rule-classes :type-prescription)
  (max (len x) 1)
  ///
  (local (defthm s-endp-true-by-len
      (implies (<= (len x) 1) (s-endp x))
      :hints (("Goal" :in-theory (enable s-endp)))))
  (defthm integer-length-bound-s-correct
    (< (integer-length (bfr-list->s x env))
      (integer-length-bound-s x))
    :rule-classes :linear))
other
(defsymbolic bfr-abs-s
  ((x s))
  :returns (xabs s (abs x))
  :prepwork ((local (in-theory (enable loghead-of-integer-length-nonneg))) (local (defthm loghead-of-abs-2
        (implies (and (< (integer-length x) (nfix n))
            (integerp x)
            (< x 0))
          (equal (loghead n (- x)) (- x)))
        :hints (("Goal" :induct (loghead n x)
           :expand ((loghead n (- x)))
           :in-theory (disable loghead**)) (and stable-under-simplificationp
            '(:in-theory (e/d (logcons minus-to-lognot) (loghead**))))))))
  (let ((sign (bfr-sign-s x)))
    (bfr-loghead-ns (integer-length-bound-s x)
      (bfr-+-ss sign
        nil
        (bfr-logxor-ss (bfr-sterm sign) x))))
  :correct-hints ('(:use (integer-length-bound-s-correct bfr-sign-s-correct)
     :in-theory (e/d* (lognot)
       (integer-length-bound-s-correct bfr-sign-s-correct
         ihsext-redefs)))))
other
(defsymbolic bfr-=-uu
  ((a u) (b u))
  :returns (a=b b (equal a b))
  :measure (+ (len a) (len b))
  (b* (((when (and (atom a) (atom b))) t) ((mv head1 tail1) (car/cdr a))
      ((mv head2 tail2) (car/cdr b))
      (first-eq (bfr-iff head1 head2)))
    (bfr-and first-eq
      (bfr-=-uu tail1 tail2))))
other
(defsymbolic bfr-=-ss
  ((a s) (b s))
  :returns (a=b b (equal a b))
  :measure (+ (len a) (len b))
  (b* (((mv head1 tail1 end1) (first/rest/end a)) ((mv head2 tail2 end2) (first/rest/end b))
      ((when (and end1 end2)) (bfr-iff head1 head2))
      (first-eq (bfr-iff head1 head2)))
    (bfr-and first-eq
      (bfr-=-ss tail1 tail2))))
other
(local (add-bfr-pat (bfr-sign-s . &)))
other
(local (add-bfr-pat (bfr-=-ss . &)))
other
(defsymbolic bfr-*-ss
  ((v1 s) (v2 s))
  :measure (+ (len v1) (len v2))
  :returns (prod s (* v1 v2))
  (b* (((mv dig1 rest end1) (first/rest/end v1)) ((when end1) (bfr-ite-bss dig1
          (bfr-unary-minus-s v2)
          nil))
      (rest (bfr-*-ss rest v2)))
    (bfr-+-ss nil
      (bfr-ite-bss dig1 v2 nil)
      (bfr-scons nil rest)))
  :correct-hints ('(:in-theory (enable logcons))))
other
(define syntactically-true-p
  (x)
  :returns (true-p booleanp)
  (eq x t)
  ///
  (defretd syntactically-true-p-implies
    (implies (syntactically-true-p x)
      (equal (bfr-eval x env) t)))
  (defretd syntactically-true-p-rewrite
    (implies (and (rewriting-negative-literal `(syntactically-true-p ,GL::X))
        (bind-free '((env . env)) (env)))
      (iff (syntactically-true-p x)
        (and (equal (bfr-eval x env) t)
          (hide (syntactically-true-p x)))))
    :hints (("goal" :expand ((:free (x) (hide x)))))))
other
(defsymbolic bfr-<-=-ss
  ((a s) (b s))
  :measure (+ (len a) (len b))
  :returns (mv (a<b b (< a b))
    (a=b b (= a b)))
  :correct-hints ('(:in-theory (e/d (syntactically-true-p-rewrite))
     :do-not-induct t))
  (b* (((mv head1 tail1 end1) (first/rest/end a)) ((mv head2 tail2 end2) (first/rest/end b))
      ((when (and end1 end2)) (b* ((less (bfr-and head1 (bfr-not head2))))
          (mv less
            (if (syntactically-true-p less)
              nil
              (bfr-iff head1 head2)))))
      ((mv rst< rst=) (bfr-<-=-ss tail1 tail2))
      (less (bfr-or rst<
          (bfr-and rst= head2 (bfr-not head1)))))
    (mv less
      (if (syntactically-true-p less)
        nil
        (bfr-and rst= (bfr-iff head1 head2))))))
other
(define syntactically-zero-p
  ((x true-listp))
  :returns (result booleanp)
  (b* (((mv head tail end) (first/rest/end x)))
    (and (eq head nil)
      (or end (syntactically-zero-p tail))))
  ///
  (defretd syntactically-zero-p-implies
    (implies (syntactically-zero-p x)
      (equal (bfr-list->s x env) 0))))
other
(defsymbolic bfr-<-ss
  ((a s) (b s))
  :returns (a<b b (< a b))
  :correct-hints ('(:in-theory (enable syntactically-zero-p-implies)))
  (b* (((when (syntactically-zero-p b)) (bfr-sign-s a)) ((mv head1 tail1 end1) (first/rest/end a))
      ((mv head2 tail2 end2) (first/rest/end b))
      ((when (and end1 end2)) (bfr-and head1 (bfr-not head2)))
      ((mv rst< rst=) (bfr-<-=-ss tail1 tail2)))
    (bfr-or rst<
      (bfr-and rst= head2 (bfr-not head1)))))
other
(defsymbolic bfr-logapp-nss
  ((n n) (a s) (b s))
  :returns (a-app-b s (logapp n a b))
  (b* (((when (zp n)) (llist-fix b)) ((mv first rest &) (first/rest/end a)))
    (bfr-scons first
      (bfr-logapp-nss (1- n) rest b))))
other
(defsymbolic bfr-logapp-nus-aux
  ((n n) (a u) (b s))
  :returns (a-app-b s (logapp n a b))
  (b* (((when (zp n)) (llist-fix b)) ((mv first rest) (car/cdr a)))
    (bfr-scons first
      (bfr-logapp-nus-aux (1- n) rest b))))
other
(defsymbolic bfr-loghead-nu
  ((n n) (a u))
  :returns (head s (loghead n a))
  (b* (((when (or (zp n) (atom a))) '(nil)) ((mv first rest) (car/cdr a)))
    (bfr-scons first (bfr-loghead-nu (1- n) rest))))
other
(defsymbolic bfr-logapp-nus
  ((n n) (a u) (b s))
  :returns (a-app-b s (logapp n a b))
  :correct-hints ('(:in-theory (enable syntactically-zero-p-implies)))
  (b* (((when (syntactically-zero-p b)) (bfr-loghead-nu n a)))
    (bfr-logapp-nus-aux n a b)))
other
(defsymbolic bfr-ash-ss
  ((place p) (n s) (shamt s))
  :returns (sh s
    (ash n (+ -1 place (* place shamt))))
  :measure (len shamt)
  :prepwork ((local (defthm reverse-distrib-1
       (and (equal (+ n n) (* 2 n))
         (implies (syntaxp (quotep k))
           (equal (+ n (* k n)) (* (+ 1 k) n)))
         (implies (syntaxp (quotep k))
           (equal (+ (- n) (* k n)) (* (+ -1 k) n)))
         (implies (syntaxp (quotep k))
           (equal (+ (- n) (* k n) m)
             (+ (* (+ -1 k) n) m)))
         (implies (syntaxp (and (quotep a) (quotep b)))
           (equal (+ (* a n) (* b n))
             (* (+ a b) n)))
         (equal (+ n n m) (+ (* 2 n) m))
         (implies (syntaxp (quotep k))
           (equal (+ n (* k n) m)
             (+ (* (+ 1 k) n) m)))
         (implies (syntaxp (and (quotep a) (quotep b)))
           (equal (+ (* a n) (* b n) m)
             (+ (* (+ a b) n) m)))
         (equal (+ n (- (* 2 n)) m) (+ (- n) m))))))
  (b* (((mv shdig shrst shend) (first/rest/end shamt)) (place (lposfix place))
      ((when shend) (bfr-ite-bss shdig
          (bfr-logtail-ns 1 n)
          (bfr-logapp-nss (1- place) nil n)))
      (rst (bfr-ash-ss (* 2 place) n shrst)))
    (bfr-ite-bss shdig
      rst
      (bfr-logtail-ns place rst)))
  :correct-hints ('(:expand ((:free (b)
        (logcons b
          (bfr-list->s (scdr shamt) env))) (bfr-ash-ss place n shamt))
     :in-theory (disable logtail-identity unsigned-byte-p))))
other
(defsymbolic bfr-logbitp-n2v
  ((place p) (digit u) (n s))
  :returns (bit b (logbitp (* place digit) n))
  :measure (len digit)
  (b* (((mv first & end) (first/rest/end n)) (place (lposfix place))
      ((when (or (atom digit) end)) first))
    (bfr-ite (car digit)
      (bfr-logbitp-n2v (* 2 place)
        (cdr digit)
        (bfr-logtail-ns place n))
      (bfr-logbitp-n2v (* 2 place) (cdr digit) n)))
  :correct-hints ((and stable-under-simplificationp
     '(:in-theory (enable logcons bool->bit)))))
other
(defsymbolic bfr-logand-ss
  ((a s) (b s))
  :returns (a&b s (logand a b))
  :measure (+ (len a) (len b))
  (b* (((mv af ar aend) (first/rest/end a)) ((when aend) (bfr-ite-bss af b '(nil)))
      ((mv bf br bend) (first/rest/end b))
      ((when bend) (bfr-ite-bss bf a '(nil)))
      (c (bfr-and af bf))
      (r (bfr-logand-ss ar br)))
    (bfr-scons c r)))
other
(defsymbolic bfr-logior-ss
  ((a s) (b s))
  :returns (avb s (logior a b))
  :measure (+ (len a) (len b))
  (b* (((mv af ar aend) (first/rest/end a)) ((when aend) (bfr-ite-bss af '(t) b))
      ((mv bf br bend) (first/rest/end b))
      ((when bend) (bfr-ite-bss bf '(t) a))
      (c (bfr-or af bf))
      (r (bfr-logior-ss ar br)))
    (bfr-scons c r)))
other
(defsymbolic bfr-logeqv-ss
  ((a s) (b s))
  :returns (a=b s (logeqv a b))
  :measure (+ (len a) (len b))
  (b* (((mv af ar aend) (first/rest/end a)) ((mv bf br bend) (first/rest/end b))
      (c (bfr-iff af bf))
      ((when (and aend bend)) (bfr-sterm c))
      (r (bfr-logeqv-ss ar br)))
    (bfr-scons c r)))
other
(defsymbolic bfr-floor-ss-aux
  ((a s) (b s) (not-b s))
  :returns (mv (f s (floor a b))
    (m s (mod a b)))
  :correct-hyp (< 0 (bfr-list->s b env))
  :guard (equal not-b (bfr-lognot-s b))
  :prepwork ((local (include-book "ihs/quotient-remainder-lemmas" :dir :system)) (local (encapsulate nil
        (local (progn (defthm floor-between-b-and-2b
              (implies (and (integerp a)
                  (integerp b)
                  (< 0 b)
                  (<= b a)
                  (< a (* 2 b)))
                (equal (floor a b) 1))
              :hints (("Goal" :in-theory (disable floor floor-bounded-by-/ <-*-/-left)
                 :use ((:instance floor-bounded-by-/ (x a) (y b)) (:theorem (implies (and (integerp a)
                         (integerp b)
                         (< 0 b)
                         (< a (* 2 b)))
                       (< (* a (/ b)) 2))))) (and stable-under-simplificationp
                  '(:in-theory (disable floor)))))
            (defthm floor-less-than-b
              (implies (and (integerp a)
                  (integerp b)
                  (< 0 b)
                  (<= 0 a)
                  (< a b))
                (equal (floor a b) 0))
              :hints (("Goal" :in-theory (disable floor floor-bounded-by-/ <-*-/-left)
                 :use ((:instance floor-bounded-by-/ (x a) (y b)) (:theorem (implies (and (integerp a)
                         (integerp b)
                         (< 0 b)
                         (< a b))
                       (< (* a (/ b)) 1))))) (and stable-under-simplificationp
                  '(:in-theory (disable floor)))))
            (defthm mod-between-b-and-2-b
              (implies (and (integerp a)
                  (integerp b)
                  (< 0 b)
                  (<= b a)
                  (< a (* 2 b)))
                (equal (mod a b) (- a b)))
              :hints (("Goal" :in-theory (e/d (mod) (floor floor-bounded-by-/ <-*-/-left))
                 :use ((:instance floor-bounded-by-/ (x a) (y b)) (:theorem (implies (and (integerp a)
                         (integerp b)
                         (< 0 b)
                         (< a (* 2 b)))
                       (< (* a (/ b)) 2))))) (and stable-under-simplificationp
                  '(:in-theory (disable floor)))))
            (defthm mod-less-than-b
              (implies (and (integerp a)
                  (integerp b)
                  (< 0 b)
                  (<= 0 a)
                  (< a b))
                (equal (mod a b) a))
              :hints (("Goal" :in-theory (disable floor floor-bounded-by-/ <-*-/-left)
                 :use ((:instance floor-bounded-by-/ (x a) (y b)) (:theorem (implies (and (integerp a)
                         (integerp b)
                         (< 0 b)
                         (< a (* 2 b)))
                       (< (* a (/ b)) 2))))) (and stable-under-simplificationp
                  '(:in-theory (disable floor)))))))
        (defthm floor-rewrite-+-bit-*-2-a
          (implies (and (integerp a) (integerp b) (< 0 b))
            (equal (floor (logcons c a) b)
              (if (<= b (logcons c (mod a b)))
                (logcons 1 (floor a b))
                (logcons 0 (floor a b)))))
          :hints (("Goal" :in-theory (e/d* (logcons bfix)
               (floor (:rules-of-class :generalize :here))
               ((:generalize mod-bounded-by-modulus))))))
        (defthm mod-rewrite-+-bit-*-2-a
          (implies (and (integerp a) (integerp b) (< 0 b))
            (equal (mod (logcons c a) b)
              (if (<= b (logcons c (mod a b)))
                (+ (- b) (logcons c (mod a b)))
                (logcons c (mod a b)))))
          :hints (("goal" :in-theory (e/d* (logcons bfix mod)
               (floor (:rules-of-class :generalize :here))
               ((:generalize mod-bounded-by-modulus))))))
        (defthm denominator-of-unary-/
          (implies (and (integerp n) (< 0 n))
            (equal (denominator (/ n)) n))
          :hints (("goal" :use ((:instance rational-implies2 (x (/ n)))))))
        (defthm <-1-not-integer-recip
          (implies (and (integerp n) (< 1 n))
            (not (integerp (/ n))))
          :hints (("goal" :use ((:instance denominator-of-unary-/))
             :in-theory (disable denominator-of-unary-/))))
        (defthm integer-and-integer-recip
          (implies (and (integerp n) (< 0 n))
            (equal (integerp (/ n)) (equal n 1))))
        (defthm loghead-of-bfr-integer-length-bound
          (implies (and (bind-free '((env . env)))
              (<= 0 (ifix a))
              (<= (ifix a) (bfr-list->s b env)))
            (equal (loghead (integer-length-bound-s b) a)
              (ifix a)))
          :hints (("goal" :use ((:instance loghead-of-integer-length-nonneg
                (n (integer-length-bound-s b))
                (x a)) (:instance integer-length-lte-by-compare-nonneg
                 (a a)
                 (b (bfr-list->s b env))))
             :in-theory (disable loghead-of-integer-length-nonneg))))
        (defthm logcons-onto-mod-b-bound
          (implies (and (integerp b) (integerp a) (< 0 b))
            (< (logcons bit (mod a b)) (* 2 b)))
          :hints (("Goal" :in-theory (enable logcons)))
          :rule-classes :linear)))
    (local (add-bfr-pat (bfr-<-ss . &)))
    (local (defthm +-1-logcons-0
        (equal (+ 1 (logcons 0 a)) (logcons 1 a))
        :hints (("Goal" :in-theory (enable logcons)))))
    (local (defthm boolean-listp-of-scdr
        (implies (boolean-listp x)
          (boolean-listp (scdr x)))
        :hints (("Goal" :in-theory (enable scdr)))))
    (local (defthm bfr-list->s-of-quoted-boolean-list
        (implies (and (syntaxp (quotep x))
            (boolean-listp x))
          (equal (bfr-list->s x env) (v2i x)))
        :hints (("Goal" :in-theory (enable bfr-list->s v2i)
           :expand ((boolean-listp x))
           :induct (bfr-list->s x env)))))
    (local (in-theory (e/d* nil
          (floor mod
            loghead**
            loghead-identity
            bfr-eval-list
            bfr-list->s
            equal-of-booleans-rewrite
            mod-type
            floor-type-3
            floor-type-1
            logcons-posp-1
            logcons-posp-2
            logcons-negp
            rationalp-mod
            (:t floor)
            (:t mod))))))
  (b* (((mv first rest endp) (first/rest/end a)) (not-b (mbe :logic (bfr-lognot-s b) :exec not-b)))
    (if endp
      (mv (bfr-sterm first)
        (bfr-ite-bss first (bfr-+-ss nil '(t) b) '(nil)))
      (b* (((mv rf rm) (bfr-floor-ss-aux rest b not-b)) (rm (bfr-scons first rm))
          (less (bfr-<-ss rm b)))
        (mv (bfr-scons (bfr-not less) rf)
          (bfr-ite-bss less
            rm
            (bfr-loghead-ns (integer-length-bound-s b)
              (bfr-+-ss t not-b rm)))))))
  :correct-hints ('(:expand ((:free (not-b)
        (bfr-floor-ss-aux a b not-b)) (:free (not-b)
         (bfr-floor-ss-aux nil b not-b))
       (:free (a b)
         (bfr-list->s (bfr-scons a b) env))
       (bfr-list->s a env))) (bfr-reasoning)
    (and stable-under-simplificationp
      '(:in-theory (enable lognot)))
    (and stable-under-simplificationp '(:do-not-induct t))))
other
(defsymbolic bfr-mod-ss-aux
  ((a s) (b s) (not-b s))
  :returns (m s (mod a b))
  :correct-hyp (< 0 (bfr-list->s b env))
  :guard (equal not-b (bfr-lognot-s b))
  :guard-hints ('(:expand ((:free (not-b)
        (bfr-floor-ss-aux a b not-b)))))
  (mbe :logic (non-exec (mv-nth 1 (bfr-floor-ss-aux a b not-b)))
    :exec (b* (((mv first rest endp) (first/rest/end a)) (not-b (mbe :logic (bfr-lognot-s b) :exec not-b))
        ((when endp) (bfr-ite-bss first (bfr-+-ss nil '(t) b) '(nil)))
        (rm (bfr-mod-ss-aux rest b not-b))
        (rm (bfr-scons first rm))
        (less (bfr-<-ss rm b)))
      (bfr-ite-bss less
        rm
        (bfr-loghead-ns (integer-length-bound-s b)
          (bfr-+-ss t not-b rm))))))
other
(defsymbolic bfr-sign-abs-not-s
  ((x s))
  :returns (mv (s b (< x 0))
    (a s (abs x))
    (n s (lognot (abs x))))
  (let ((abs (bfr-abs-s x)))
    (mv (bfr-sign-s x) abs (bfr-lognot-s abs))))
other
(defsymbolic bfr-floor-ss
  ((a s) (b s))
  :returns (f s (floor a b))
  :prepwork ((local (in-theory (enable bfr-sign-abs-not-s))))
  (bfr-ite-bss (bfr-=-ss b nil)
    nil
    (b* (((mv bsign babs bneg) (bfr-sign-abs-not-s b)) (anorm (bfr-ite-bss bsign
            (bfr-unary-minus-s a)
            a))
        ((mv f &) (bfr-floor-ss-aux anorm babs bneg)))
      f))
  :correct-hints ((bfr-reasoning)))
other
(defsymbolic bfr-mod-ss
  ((a s) (b s))
  :returns (m s (mod a b))
  :prepwork ((local (in-theory (enable bfr-sign-abs-not-s))))
  (bfr-ite-bss (bfr-=-ss b nil)
    (llist-fix a)
    (bfr-logext-ns (integer-length-bound-s b)
      (b* (((mv bsign babs bneg) (bfr-sign-abs-not-s b)) (anorm (bfr-ite-bss bsign
              (bfr-unary-minus-s a)
              a))
          (m (bfr-mod-ss-aux anorm babs bneg)))
        (bfr-ite-bss bsign
          (bfr-unary-minus-s m)
          m))))
  :correct-hints ((bfr-reasoning)))
other
(defsymbolic bfr-truncate-ss
  ((a s) (b s))
  :returns (tr s (truncate a b))
  :prepwork ((local (in-theory (enable bfr-sign-abs-not-s))))
  (bfr-ite-bss (bfr-=-ss b nil)
    nil
    (b* (((mv bsign babs bneg) (bfr-sign-abs-not-s b)) ((mv asign aabs &) (bfr-sign-abs-not-s a))
        ((mv f &) (bfr-floor-ss-aux aabs babs bneg)))
      (bfr-ite-bss (bfr-xor bsign asign)
        (bfr-unary-minus-s f)
        f)))
  :correct-hints ((bfr-reasoning)))
other
(defsymbolic bfr-rem-ss
  ((a s) (b s))
  :returns (r s (rem a b))
  :prepwork ((local (in-theory (disable integer-length-of-between-abs-and-minus-abs
         logext-of-integer-length-bound
         rem
         integer-length**))) (local (in-theory (enable bfr-sign-abs-not-s))))
  (bfr-ite-bss (bfr-=-ss b nil)
    (llist-fix a)
    (b* (((mv & babs bneg) (bfr-sign-abs-not-s b)) ((mv asign aabs &) (bfr-sign-abs-not-s a))
        (m (bfr-mod-ss-aux aabs babs bneg)))
      (bfr-logext-ns (integer-length-bound-s b)
        (bfr-ite-bss asign
          (bfr-unary-minus-s m)
          m))))
  :correct-hints ((bfr-reasoning) (and stable-under-simplificationp
      '(:use ((:instance integer-length-of-rem
           (a (bfr-list->s a env))
           (b (bfr-list->s b env))))
        :in-theory (e/d (logext-of-integer-length-bound)
          (integer-length-of-rem integer-length-of-mod))))))
other
(define s-take
  ((n natp) (x true-listp))
  (b* (((when (zp n)) (bfr-sterm nil)) ((mv first rest end) (first/rest/end x))
      ((when (and end (eq first nil))) '(nil)))
    (bfr-ucons first (s-take (1- n) rest)))
  ///
  (defthm deps-of-s-take
    (implies (not (pbfr-list-depends-on k p x))
      (not (pbfr-list-depends-on k
          p
          (s-take n x)))))
  (defthm s-take-correct
    (equal (bfr-list->u (s-take n x) env)
      (loghead n (bfr-list->s x env)))
    :hints (("goal" :induct (s-take n x)
       :in-theory (enable* ihsext-recursive-redefs)))))
other
(defsymbolic bfr-logapp-russ
  ((n ru) (x s) (y s))
  :returns (app s (logapp n x y))
  :prepwork ((local (in-theory (enable logcons rev))) (local (defthm logapp-loghead-logtail
        (implies (equal z
            (logapp w1 (logtail w x) y))
          (equal (logapp w (loghead w x) z)
            (logapp (+ (nfix w) (nfix w1))
              x
              y)))
        :hints (("Goal" :in-theory (enable* ihsext-recursive-redefs
             ihsext-inductions)))))
    (local (defthm loghead-of-len-of-bfr-list
        (implies (<= (len lst) (nfix n))
          (equal (loghead n (bfr-list->u lst env))
            (bfr-list->u lst env)))
        :hints (("Goal" :in-theory (enable* ihsext-recursive-redefs
             ihsext-inductions
             (:i nthcdr))
           :induct (nthcdr n lst)
           :expand ((bfr-list->u lst env) (:free (x) (loghead n x)))))))
    (local (defthm logapp-1-is-plus-ash
        (equal (logapp n x 1)
          (+ (ash 1 (nfix n)) (loghead n x)))
        :hints (("Goal" :in-theory (enable logapp ash-is-expt-*-x)))))
    (local (defthm bfr-list->u-of-append
        (equal (bfr-list->u (append a b) env)
          (logapp (len a)
            (bfr-list->u a env)
            (bfr-list->u b env)))
        :hints (("Goal" :in-theory (enable* ihsext-recursive-redefs
             ihsext-inductions
             append))))))
  (if (atom n)
    (llist-fix y)
    (if (b* (((mv x1 & xend) (first/rest/end x)) ((mv y1 & yend) (first/rest/end y)))
        (and xend yend (equal x1 y1)))
      (llist-fix x)
      (bfr-ite-bss (car n)
        (b* ((w (ash 1 (len (cdr n)))))
          (bfr-logapp-nus w
            (s-take w x)
            (bfr-logapp-russ (cdr n)
              (bfr-logtail-ns w x)
              y)))
        (bfr-logapp-russ (cdr n) x y)))))
other
(local (defsection expt-lemmas
    (defthm expt-of-0
      (equal (expt base 0) 1)
      :hints (("Goal" :in-theory (enable expt))))
    (defthm expt-of-*-2
      (implies (natp exp)
        (equal (expt base (* 2 exp))
          (* (expt base exp) (expt base exp))))
      :hints (("Goal" :in-theory (enable expt))))))
other
(define all-nil
  ((x))
  (if (atom x)
    t
    (and (eq (car x) nil) (all-nil (cdr x))))
  ///
  (defthm all-nil-when-atom
    (implies (atom x) (all-nil x)))
  (defthmd zero-when-all-nil
    (implies (all-nil x)
      (equal (bfr-list->u x env) 0))))
other
(defsymbolic bfr-expt-su
  ((b s) (e u))
  :measure (len e)
  :returns (b^e s (expt b e))
  (b* (((when (all-nil e)) '(t nil)) ((when (all-nil (cdr e))) (bfr-ite-bss (car e) b '(t nil)))
      (rest (bfr-expt-su (bfr-*-ss b b) (cdr e))))
    (bfr-ite-bss (car e) (bfr-*-ss b rest) rest))
  :correct-hints ('(:in-theory (enable zero-when-all-nil logcons))))