other
(in-package "TRUTH")
other
(include-book "std/util/define" :dir :system)
other
(include-book "ihs/logops-definitions" :dir :system)
other
(include-book "centaur/bitops/extra-defs" :dir :system)
other
(include-book "centaur/bitops/logrepeat" :dir :system)
other
(include-book "centaur/fty/fixequiv" :dir :system)
other
(include-book "centaur/bitops/trailing-0-count" :dir :system)
other
(local (include-book "centaur/bitops/equal-by-logbitp" :dir :system))
other
(local (include-book "centaur/bitops/ihsext-basics" :dir :system))
other
(local (include-book "std/basic/arith-equivs" :dir :system))
other
(local (include-book "arithmetic/top-with-meta" :dir :system))
other
(local (include-book "std/util/termhints" :dir :system))
other
(local (in-theory (disable unsigned-byte-p logmask)))
other
(local (add-default-post-define-hook :fix))
other
(set-waterfall-parallelism nil)
other
(defxdoc truth :parents (boolean-reasoning) :short "Library for reasoning about and computing with integer-encoded truth tables." :long "<p>A Boolean function of @('n') variables can be represented using a bit vector of @('2^n') bits. Operators such as AND/OR/XOR can then be computed using @('logand'), @('logior'), and @('logxor'), respectively. This library provides utilities for using this encoding of Boolean functions and reasoning about them. It is particularly useful in the @(see aignet::rewrite) AIG transformation.</p>")
other
(local (set-default-parents truth))
other
(define true nil -1)
other
(define false nil 0)
other
(define truth-eval ((truth integerp) (env natp) (numvars natp)) :guard (unsigned-byte-p numvars env) (b* ((env (mbe :logic (loghead (nfix numvars) (nfix env)) :exec env))) (logbitp env truth)) /// (defthm truth-eval-of-lognot (equal (truth-eval (lognot truth) env numvars) (not (truth-eval truth env numvars))) :hints (("Goal" :in-theory (enable truth-eval)))) (defthm truth-eval-of-logand (equal (truth-eval (logand x y) env numvars) (and (truth-eval x env numvars) (truth-eval y env numvars))) :hints (("Goal" :in-theory (enable truth-eval)))) (defthm truth-eval-of-logior (equal (truth-eval (logior x y) env numvars) (or (truth-eval x env numvars) (truth-eval y env numvars))) :hints (("Goal" :in-theory (enable truth-eval)))) (defthm truth-eval-of-logxor (equal (truth-eval (logxor x y) env numvars) (xor (truth-eval x env numvars) (truth-eval y env numvars))) :hints (("Goal" :in-theory (enable truth-eval)))) (defthm truth-eval-of-consts (and (equal (truth-eval 0 env numvars) nil) (equal (truth-eval -1 env numvars) t))))
other
(define env-update ((var natp) (val booleanp) (env natp)) :returns (new-env natp :rule-classes :type-prescription) (install-bit var (bool->bit val) (lnfix env)) /// (defthm env-lookup-of-env-update-split (equal (env-lookup var (env-update var1 val env)) (if (equal (nfix var) (nfix var1)) (bool-fix val) (env-lookup var env))) :hints (("Goal" :in-theory (enable* env-lookup (:ruleset arith-equiv-forwarding))))) (defthm env-update-of-env-update (equal (env-update n x (env-update n y env)) (env-update n x env))) (defthm env-update-swap (implies (not (nat-equiv var1 var2)) (equal (env-update var2 val2 (env-update var1 val1 env)) (env-update var1 val1 (env-update var2 val2 env)))) :hints (("Goal" :in-theory (enable env-update)))) (defthm env-update-redundant (implies (iff (env-lookup n env) val) (equal (env-update n val env) (nfix env))) :hints (("Goal" :in-theory (enable env-lookup)))))
other
(local (encapsulate nil (local (include-book "ihs/quotient-remainder-lemmas" :dir :system)) (defthm mod-when-less (implies (and (natp n) (natp w) (< n w)) (equal (mod n w) n))) (defthm mod-when-greater (implies (and (natp n) (natp w) (<= w n) (syntaxp (not (equal w ''0)))) (equal (mod n w) (mod (- n w) w)))) (defthm natp-of-mod (implies (and (natp n) (natp w)) (natp (mod n w))) :hints (("Goal" :in-theory (disable (force))))) (defthm mod-less-than-modulus (implies (and (natp n) (posp w)) (< (mod n w) w)))))
other
(local (defthm lognot-of-logapp (equal (lognot (logapp w a b)) (logapp w (lognot a) (lognot b))) :hints (("Goal" :in-theory (e/d* (ihsext-inductions) (logapp-of-i-0)) :induct (logapp w a b) :expand ((:free (a b) (logapp w a b)))))))
other
(define var-repetitions ((n natp) (val natp) (numvars natp)) :guard (and (<= n numvars) (unsigned-byte-p (ash 1 n) val)) :verify-guards nil :returns (rep-val natp :rule-classes :type-prescription) :enabled t (mbe :logic (logrepeat (ash 1 (- (nfix numvars) (nfix n))) (ash 1 (nfix n)) (nfix val)) :exec (b* ((shift (ash 1 n)) ((when (mbe :logic (zp (- numvars n)) :exec (eql n numvars))) val)) (var-repetitions (+ 1 n) (logapp shift val val) numvars))) /// (verify-guards var-repetitions :hints (("Goal" :in-theory (e/d* (logcons) (exponents-add)) :expand ((ash 1 (+ (- n) numvars)) (ash 1 (+ 1 n)))))))
other
(local (defthm posp-of-ash-1 (implies (not (negp n)) (posp (ash 1 n))) :hints (("Goal" :in-theory (enable* ihsext-inductions ihsext-recursive-redefs))) :rule-classes :type-prescription))
other
(local (defthmd logbitp-in-terms-of-loghead (iff (logbitp n x) (<= (ash 1 (nfix n)) (loghead (+ 1 (nfix n)) x))) :hints (("Goal" :in-theory (enable* ihsext-inductions ihsext-recursive-redefs)))))
other
(local (defthmd ash-1-monotonic (implies (and (< a b) (natp a) (integerp b)) (< (ash 1 a) (ash 1 b))) :hints (("Goal" :in-theory (enable ash-is-expt-*-x))) :rule-classes ((:rewrite) (:linear))))
other
(local (defthmd loghead-less-than-ash (implies (not (negp n)) (< (loghead n x) (ash 1 n))) :hints (("Goal" :in-theory (enable* ihsext-inductions ihsext-recursive-redefs))) :rule-classes (:rewrite :linear)))
other
(define var ((n natp) (numvars natp)) :guard (< n numvars) :returns (var-enc natp :rule-classes :type-prescription) :guard-hints (("goal" :expand ((ash 1 (+ 1 n))) :in-theory (enable logcons))) :prepwork ((local (defthm plus-minus-*2 (equal (+ (- x) (* 2 x)) (fix x))))) (b* ((n (lnfix n)) (numvars (lnfix numvars)) (w (ash 1 n)) (rep (ash (logmask w) w))) (var-repetitions (+ 1 n) rep numvars)) /// (local (defthm loghead-less-than-ash-times-2-linear (implies (natp n) (< (loghead (+ 1 n) x) (* 2 (ash 1 n)))) :hints (("goal" :use ((:instance loghead-less-than-ash (n (+ 1 n)))) :expand ((ash 1 (+ 1 n))) :in-theory (enable logcons))) :rule-classes :linear)) (local (defthm product-of-ash (implies (and (natp a) (natp b)) (equal (* (ash 1 a) (ash 1 b)) (ash 1 (+ a b)))) :hints (("Goal" :in-theory (enable ash-is-expt-*-x))))) (local (defthm mod-of-ash-1-is-loghead (implies (and (natp n) (integerp x)) (equal (mod x (ash 1 n)) (loghead n x))) :hints (("Goal" :in-theory (enable loghead ash-is-expt-*-x))))) (defret logbitp-of-var (implies (< (nfix n) (nfix numvars)) (equal (logbitp env var-enc) (and (< (nfix env) (ash 1 numvars)) (logbitp n (nfix env))))) :hints ((and stable-under-simplificationp '(:in-theory (enable logbitp-of-ash-split loghead-less-than-ash))) (and stable-under-simplificationp '(:in-theory (enable logbitp-in-terms-of-loghead))))) (defret eval-of-var (implies (< (nfix n) (nfix numvars)) (equal (truth-eval var-enc env numvars) (env-lookup n env))) :hints (("goal" :in-theory (e/d (truth-eval env-lookup loghead-less-than-ash) (var))))) (defret var-size-basic (implies (and (< (nfix n) numvars) (natp numvars)) (unsigned-byte-p (ash 1 numvars) var-enc)) :hints (("goal" :expand ((ash 1 (+ 1 (nfix n))) (ash 1 numvars)) :in-theory (enable logcons)))) (defret var-size (implies (and (natp m) (<= (ash 1 numvars) m) (< (nfix n) numvars) (natp numvars)) (unsigned-byte-p m var-enc)) :hints (("goal" :use var-size-basic :in-theory (disable var-size-basic)))) (local (defthm lognot-of-ash (implies (natp n) (equal (lognot (ash x n)) (logapp n -1 (lognot x)))) :hints ((logbitp-reasoning)))) (local (defthm loghead-of-logapp (implies (<= (nfix w1) (nfix w2)) (equal (loghead w2 (logapp w1 a b)) (logapp w1 a (loghead (- (nfix w2) (nfix w1)) b)))) :hints ((logbitp-reasoning)))) (local (defthm plus-minus-*-n (implies (and (syntaxp (quotep n)) (natp n)) (equal (+ (- x) (* n x)) (* (+ -1 n) x))))) (local (defthm plus-*-minus-n (implies (and (syntaxp (quotep n)) (natp n)) (equal (+ x (- (* n x))) (- (* (+ -1 n) x)))))) (local (defthm loghead-lognot-logmask (equal (loghead n (lognot (logmask n))) 0) :hints ((logbitp-reasoning)))) (local (defthm var-negated-masked-lemma (implies (natp n) (equal (loghead (* 2 n) (logapp n -1 (lognot (logmask n)))) (logmask n))) :hints ((logbitp-reasoning)))) (local (defthm plus-minus-times-2 (equal (+ n (- (* 2 n)) m) (+ (- n) m)))) (defret var-negated-masked-size (implies (and (< (nfix n) numvars) (natp numvars)) (unsigned-byte-p (- (ash 1 numvars) (ash 1 (nfix n))) (loghead (ash 1 numvars) (lognot var-enc)))) :hints (("Goal" :use ((:instance size-of-logrepeat-by-data-size (n (+ (ash 1 numvars) (- (ash 1 (nfix n))))) (m (ash 1 (nfix n))) (times (ash 1 (+ -1 numvars (- (nfix n))))) (width (ash 1 (+ 1 (nfix n)))) (data (logapp (ash 1 (nfix n)) -1 (lognot (logmask (ash 1 (nfix n))))))) (:instance var-negated-masked-lemma (n (ash 1 (nfix n))))) :expand ((ash 1 (+ 1 (nfix n))) (ash 1 numvars)) :in-theory (e/d (logcons ash-1-monotonic) (size-of-logrepeat-by-data-size var-negated-masked-lemma))))) (local (defthm loghead-of-plus-last-bit (implies (and (natp n) (integerp x)) (equal (loghead (+ 1 n) (+ x (ash 1 n))) (if (< (loghead (+ 1 n) x) (ash 1 n)) (+ (loghead (+ 1 n) x) (ash 1 n)) (- (loghead (+ 1 n) x) (ash 1 n))))) :hints (("goal" :induct (loghead n x) :in-theory (enable* ihsext-inductions ihsext-recursive-redefs logcons))))) (local (defun less-when-loghead-less-ind (w n num) (if (zp n) (list w num) (less-when-loghead-less-ind (logcdr w) (1- n) (1- num))))) (local (defthm not-even-when-loghead-0 (implies (and (equal (logcar x) 1) (integerp y)) (not (equal (* 2 y) x))))) (local (defthm less-when-loghead-less (implies (and (integerp w) (natp num) (natp n) (< n num) (< w (ash 1 num)) (< (loghead (+ 1 n) w) (ash 1 n))) (< (+ w (ash 1 n)) (ash 1 num))) :hints (("goal" :induct (less-when-loghead-less-ind w n num) :expand ((loghead (+ 1 n) w) (loghead 1 w) (ash 1 n) (ash 1 num)) :in-theory (enable logcons))))) (defret var-negated (implies (and (< (nfix n) numvars) (natp numvars)) (equal (loghead (ash 1 numvars) (lognot var-enc)) (logtail (ash 1 (nfix n)) var-enc))) :hints ((logbitp-reasoning))))
other
(local (defthmd loghead-less-than-ash-nfix (< (loghead n x) (ash 1 (nfix n))) :hints (("Goal" :in-theory (enable* ihsext-inductions ihsext-recursive-redefs)))))
other
(define truth-norm ((truth integerp) (numvars natp)) :returns (norm-truth) (loghead (ash 1 (lnfix numvars)) truth) /// (local (in-theory (enable loghead-less-than-ash-nfix))) (local (defthm logbitp-of-loghead-past-range (implies (< (nfix n) (nfix m)) (equal (logbitp n (loghead m x)) (logbitp n x))) :hints (("Goal" :in-theory (enable* ihsext-inductions ihsext-recursive-redefs))))) (defret truth-eval-of-truth-norm (equal (truth-eval (truth-norm truth numvars) env numvars) (truth-eval truth env numvars)) :hints (("Goal" :in-theory (enable truth-eval)))) (defret truth-norm-of-truth-norm (equal (truth-norm (truth-norm truth numvars) numvars) (truth-norm truth numvars))) (defret size-of-truth-norm (implies (and (natp size) (<= (ash 1 (nfix numvars)) size)) (unsigned-byte-p size norm-truth))) (defret truth-eval-of-truth-norm-minus1 (implies (and (syntaxp (and (quotep truth) (quotep numvars))) (equal truth (truth-norm -1 numvars))) (truth-eval truth env numvars)) :hints (("Goal" :in-theory (disable truth-norm)))))
other
(local (encapsulate nil (local (defthmd loghead-of-install-bit-lemma (implies (posp i) (equal (loghead (+ i (nfix n)) (install-bit n v x)) (install-bit n v (loghead (+ i (nfix n)) x)))) :hints (("Goal" :in-theory (enable* ihsext-inductions ihsext-recursive-redefs) :induct (logbitp n x)) (and stable-under-simplificationp '(:expand ((:free (x) (install-bit n v x)) (:free (x) (install-bit 0 v x)))))))) (defthm loghead-of-install-bit (implies (< (nfix n) (nfix w)) (equal (loghead w (install-bit n v x)) (install-bit n v (loghead w x)))) :hints (("Goal" :use ((:instance loghead-of-install-bit-lemma (i (- (nfix w) (nfix n))))))))))
other
(define positive-cofactor ((n natp) (truth integerp) (numvars natp)) :guard (< n numvars) :returns (cofactor integerp :rule-classes :type-prescription) (b* ((mask (logand (var n numvars) (truth-norm truth numvars)))) (logior mask (ash mask (- (ash 1 (lnfix n)))))) /// (local (defthm logcons-logcar-plus-logcdr (implies (and (equal y (+ (logcdr x) z)) (integerp z)) (equal (logcons (logcar x) y) (+ (ifix x) (logcons 0 z)))) :hints (("Goal" :in-theory (enable equal-logcons-strong))))) (local (defthm plus-ash-1-is-install-bit (implies (and (not (logbitp n x)) (integerp x)) (equal (+ (ash 1 (nfix n)) x) (install-bit n 1 x))) :hints (("Goal" :in-theory (enable* ihsext-inductions ihsext-recursive-redefs install-bit**) :induct (logbitp n x)) (and stable-under-simplificationp '(:in-theory (enable equal-logcons-strong)))))) (local (defthmd logbitp-past-width-lemma (implies (and (unsigned-byte-p n x) (natp i)) (not (logbitp (+ i n) x))) :hints (("goal" :induct (logbitp n x) :in-theory (enable* ihsext-inductions ihsext-recursive-redefs))))) (local (defthm not-logbitp-of-var-past-range (implies (and (< (nfix n) numvars) (natp numvars) (not (unsigned-byte-p numvars (nfix i)))) (not (logbitp i (var n numvars)))) :hints (("goal" :use ((:instance var-size-basic) (:instance logbitp-past-width-lemma (n (ash 1 numvars)) (i (- (nfix i) (ash 1 numvars))) (x (var n numvars)))) :in-theory (e/d (unsigned-byte-p expt-2-is-ash) (var-size-basic)))))) (local (defthm logbitp-n-of-plus-ash-1-n (implies (integerp x) (equal (logbitp n (+ (ash 1 (nfix n)) x)) (not (logbitp n x)))) :hints (("Goal" :in-theory (enable* ihsext-inductions ihsext-recursive-redefs))))) (local (defthm <-ash-by-unsigned-byte-p (implies (unsigned-byte-p n x) (< x (ash 1 n))) :hints (("Goal" :in-theory (enable unsigned-byte-p ash-is-expt-*-x))))) (defret positive-cofactor-correct (implies (< (nfix n) (nfix numvars)) (equal (truth-eval cofactor env numvars) (truth-eval truth (env-update n t env) numvars))) :hints ((and stable-under-simplificationp '(:in-theory (enable env-lookup env-update truth-eval logbitp-of-ash-split truth-norm))) (and stable-under-simplificationp '(:cases ((logbitp n (nfix env))))) (and stable-under-simplificationp '(:cases ((unsigned-byte-p numvars (+ (ash 1 (nfix n)) (loghead numvars (nfix env))))))))) (defret positive-cofactor-size-basic (implies (and (< (nfix n) numvars) (natp numvars)) (unsigned-byte-p (ash 1 numvars) cofactor))) (defret positive-cofactor-size (implies (and (natp m) (<= (ash 1 numvars) m) (< (nfix n) numvars) (natp numvars)) (unsigned-byte-p m cofactor)) :hints (("goal" :use positive-cofactor-size-basic :in-theory (disable positive-cofactor-size-basic)))) (defthm positive-cofactor-of-truth-norm (equal (positive-cofactor n (truth-norm truth numvars) numvars) (positive-cofactor n truth numvars))) (defthm truth-norm-of-positive-cofactor (implies (< (nfix n) (nfix numvars)) (equal (truth-norm (positive-cofactor n truth numvars) numvars) (positive-cofactor n truth numvars))) :hints (("Goal" :in-theory (e/d (truth-norm) (positive-cofactor))))))
other
(define negative-cofactor ((n natp) (truth integerp) (numvars natp)) :guard (< n numvars) :returns (cofactor integerp :rule-classes :type-prescription) (b* ((mask (logand (lognot (var n numvars)) (loghead (ash 1 (lnfix numvars)) truth)))) (logior mask (ash mask (ash 1 (lnfix n))))) /// (local (in-theory (disable logmask))) (local (defthm logcons-logcar-plus-logcdr (implies (and (equal y (+ (logcdr x) z)) (integerp z)) (equal (logcons (logcar x) y) (+ (ifix x) (logcons 0 z)))) :hints (("Goal" :in-theory (enable equal-logcons-strong))))) (local (defthmd plus-1-lognot (equal (+ 1 (lognot x)) (- (ifix x))) :hints (("Goal" :in-theory (enable lognot))))) (local (defthmd logcdr-of-minus (implies (integerp x) (equal (logcdr (- x)) (+ (b-not (logcar x)) (lognot (logcdr x))))) :hints (("Goal" :in-theory (enable minus-to-lognot))))) (local (defthm minus-ash-1-is-install-bit (implies (and (logbitp n x) (integerp x)) (equal (+ (- (ash 1 (nfix n))) x) (install-bit n 0 x))) :hints (("Goal" :in-theory (enable* ihsext-inductions ihsext-recursive-redefs install-bit**) :induct (logbitp n x)) (and stable-under-simplificationp '(:in-theory (enable equal-logcons-strong logcdr-of-minus plus-1-lognot)))))) (local (defthm install-bit-0-less-than-x (implies (natp x) (<= (install-bit n 0 x) x)) :hints (("Goal" :in-theory (enable* ihsext-inductions install-bit**) :induct (logbitp n x))) :rule-classes :linear)) (local (defthm ash-1-greater-than-loghead (implies (natp n) (< (loghead n x) (ash 1 n))) :hints (("goal" :in-theory (enable* ihsext-inductions ihsext-recursive-redefs))) :rule-classes :linear)) (local (defthmd logbitp-past-width-lemma (implies (and (unsigned-byte-p n x) (natp i)) (not (logbitp (+ i n) x))) :hints (("goal" :induct (logbitp n x) :in-theory (enable* ihsext-inductions ihsext-recursive-redefs))))) (local (defthm not-logbitp-of-var-past-range (implies (and (< (nfix n) numvars) (natp numvars) (not (unsigned-byte-p numvars (nfix i)))) (not (logbitp i (var n numvars)))) :hints (("goal" :use ((:instance var-size) (:instance logbitp-past-width-lemma (n (ash 1 numvars)) (i (- (nfix i) (ash 1 numvars))) (x (var n numvars)))) :in-theory (e/d (unsigned-byte-p expt-2-is-ash) (var-size)))))) (local (defthmd minus-of-logcons (equal (- (logcons a b)) (logcons a (+ (b-not a) (lognot b)))) :hints (("Goal" :in-theory (enable logcons lognot b-not))))) (local (defthm logbitp-n-of-minus-ash-1-n (implies (integerp x) (equal (logbitp n (+ (- (ash 1 (nfix n))) x)) (not (logbitp n x)))) :hints (("Goal" :in-theory (enable* ihsext-inductions ihsext-recursive-redefs minus-of-logcons plus-1-lognot))))) (local (defthm gte-ash-when-logbitp (implies (and (logbitp n x) (natp x)) (<= (ash 1 (nfix n)) x)) :hints (("Goal" :in-theory (enable* ihsext-inductions ihsext-recursive-redefs))))) (defret negative-cofactor-correct (implies (< (nfix n) (nfix numvars)) (equal (truth-eval cofactor env numvars) (truth-eval truth (env-update n nil env) numvars))) :hints ((and stable-under-simplificationp '(:in-theory (enable env-lookup env-update truth-eval logbitp-of-ash-split logbitp-of-loghead-split))) (and stable-under-simplificationp '(:cases ((logbitp n (nfix env))))))) (local (defun size-of-logand-ind (n m a b) (if (zp m) (list n a b) (size-of-logand-ind (1- n) (1- m) (logcdr a) (logcdr b))))) (local (defthmd logand-0-by-loghead-lemma (implies (and (unsigned-byte-p m a) (equal 0 (loghead m b))) (equal (logand a b) 0)) :hints (("goal" :induct (size-of-logand-ind m m a b) :expand ((loghead m b) (unsigned-byte-p m a)))))) (defthmd size-of-logand-by-size-of-loghead (implies (and (unsigned-byte-p m a) (unsigned-byte-p n (loghead m b))) (unsigned-byte-p n (logand a b))) :hints (("goal" :induct (size-of-logand-ind n m a b) :expand ((loghead m b) (:free (n a b) (unsigned-byte-p n (logcons a b)))) :in-theory (enable logand-0-by-loghead-lemma)))) (defret negative-cofactor-size-basic (implies (and (< (nfix n) numvars) (natp numvars)) (unsigned-byte-p (ash 1 numvars) cofactor)) :hints (("goal" :use ((:instance size-of-logand-by-size-of-loghead (a (loghead (ash 1 numvars) truth)) (b (lognot (var n numvars))) (m (ash 1 numvars)) (n (- (ash 1 numvars) (ash 1 (nfix n)))))) :in-theory (enable ash-1-monotonic)))) (defret negative-cofactor-size (implies (and (natp m) (<= (ash 1 numvars) m) (< (nfix n) numvars) (natp numvars)) (unsigned-byte-p m cofactor)) :hints (("goal" :use negative-cofactor-size-basic :in-theory (disable negative-cofactor-size-basic)))) (defthm negative-cofactor-of-truth-norm (equal (negative-cofactor n (truth-norm truth numvars) numvars) (negative-cofactor n truth numvars)) :hints (("Goal" :in-theory (enable truth-norm)))) (defthm truth-norm-of-negative-cofactor (implies (< (nfix n) (nfix numvars)) (equal (truth-norm (negative-cofactor n truth numvars) numvars) (negative-cofactor n truth numvars))) :hints (("Goal" :in-theory (e/d (truth-norm) (negative-cofactor))))))
other
(local (defthmd logcons-logcar-plus-logcdr (implies (and (equal y (+ (logcdr x) z)) (integerp z)) (equal (logcons (logcar x) y) (+ (ifix x) (logcons 0 z)))) :hints (("Goal" :in-theory (enable equal-logcons-strong)))))
other
(local (defthmd plus-ash-1-is-install-bit (implies (and (not (logbitp n x)) (integerp x)) (equal (install-bit n 1 x) (+ (ash 1 (nfix n)) x))) :hints (("Goal" :in-theory (enable* ihsext-inductions ihsext-recursive-redefs install-bit**) :induct (logbitp n x)) (and stable-under-simplificationp '(:in-theory (enable equal-logcons-strong))))))
other
(local (defthmd plus-1-lognot (equal (+ 1 (lognot x)) (- (ifix x))) :hints (("Goal" :in-theory (enable lognot)))))
other
(local (defthmd logcdr-of-minus (implies (integerp x) (equal (logcdr (- x)) (+ (b-not (logcar x)) (lognot (logcdr x))))) :hints (("Goal" :in-theory (enable minus-to-lognot)))))
other
(local (defthmd minus-ash-1-is-install-bit (implies (and (logbitp n x) (integerp x)) (equal (install-bit n 0 x) (+ (- (ash 1 (nfix n))) x))) :hints (("Goal" :in-theory (enable* ihsext-inductions ihsext-recursive-redefs install-bit**) :induct (logbitp n x)) (and stable-under-simplificationp '(:in-theory (enable equal-logcons-strong logcdr-of-minus plus-1-lognot))))))
other
(define depends-on ((n natp) (truth integerp) (numvars natp)) :guard (< n numvars) (b* ((var (var n numvars)) (truth (truth-norm truth numvars))) (not (equal (logand (lognot var) truth) (ash (logand var truth) (- (ash 1 (lnfix n))))))) /// (defthm depends-on-of-truth-norm (equal (depends-on n (truth-norm truth numvars) numvars) (depends-on n truth numvars))) (local (in-theory (enable logcons-logcar-plus-logcdr plus-ash-1-is-install-bit minus-ash-1-is-install-bit))) (local (defthmd equal-implies-logbitp-equal (implies (equal (logand a b) (logand c d)) (iff (and (logbitp n a) (logbitp n b)) (and (logbitp n c) (logbitp n d)))) :hints ((logbitp-reasoning)))) (local (defun find-equal-logand-terms (clause) (if (atom clause) nil (let ((lit (car clause))) (case-match lit (('not ('equal ('binary-logand a b) ('binary-logand c d))) `((a ,TRUTH::A) (b ,TRUTH::B) (c ,TRUTH::C) (d ,TRUTH::D))) (& (find-equal-logand-terms (cdr clause)))))))) (local (in-theory (enable loghead-less-than-ash))) (local (defthm logbitp-n-of-plus-ash-1-n (implies (integerp x) (equal (logbitp n (+ (ash 1 (nfix n)) x)) (not (logbitp n x)))) :hints (("Goal" :in-theory (enable* ihsext-inductions ihsext-recursive-redefs))))) (local (in-theory (enable logbitp-of-loghead-split ash-1-monotonic))) (local (defthm gte-ash-when-logbitp (implies (and (logbitp n x) (natp x)) (<= (ash 1 (nfix n)) x)) :hints (("Goal" :in-theory (enable* ihsext-inductions ihsext-recursive-redefs))))) (local (defthm loghead-plus-ash-lte-ash-when-not-logbitp (implies (and (< (nfix n) numvars) (natp numvars) (not (logbitp n x))) (< (+ (loghead numvars x) (ash 1 (nfix n))) (ash 1 numvars))) :hints (("goal" :use ((:instance plus-ash-1-is-install-bit (x (loghead numvars x))) (:instance unsigned-byte-p-of-install-bit (i n) (n numvars) (x (loghead numvars x)) (v 1))) :in-theory (e/d (unsigned-byte-p expt-2-is-ash) (plus-ash-1-is-install-bit unsigned-byte-p-of-install-bit)))) :rule-classes :linear)) (defthm depends-on-correct (implies (and (not (depends-on n truth numvars)) (< (nfix n) (nfix numvars))) (equal (truth-eval truth (env-update n val env) numvars) (truth-eval truth env numvars))) :hints (("Goal" :in-theory (enable truth-eval env-update truth-norm)) (and stable-under-simplificationp '(:cases ((logbitp n (nfix env))))) (and stable-under-simplificationp (let ((conjuncts (find-equal-logand-terms clause))) (and conjuncts `(:use ((:instance equal-implies-logbitp-equal (n (loghead numvars (nfix env))) . ,TRUTH::CONJUNCTS) (:instance equal-implies-logbitp-equal (n (install-bit n (bool->bit val) (loghead numvars (nfix env)))) . ,TRUTH::CONJUNCTS)))))) (and stable-under-simplificationp '(:cases ((eql 1 (bool->bit val)))))) :otf-flg t))
other
(define depends-on-witness ((n natp) (truth integerp) (numvars natp)) :guard (< n numvars) :returns (diff-env natp :rule-classes :type-prescription) (b* ((var (var n numvars)) (truth (truth-norm truth numvars)) (diff (logxor (logand (lognot var) truth) (ash (logand var truth) (- (ash 1 (lnfix n))))))) (trailing-0-count diff)) /// (local (defthmd trailing-0-count-of-logxor-when-not-equal (implies (not (equal (ifix x) (ifix y))) (b* ((count (trailing-0-count (logxor x y)))) (iff (logbitp count x) (not (logbitp count y))))) :hints (("goal" :induct (logxor x y) :in-theory (enable* ihsext-recursive-redefs ihsext-inductions trailing-0-count))))) (local (defthmd trailing-0-count-bound-when-unsigned-byte-p (implies (and (unsigned-byte-p n x) (posp n)) (< (trailing-0-count x) n)) :hints (("goal" :in-theory (enable* ihsext-recursive-redefs ihsext-inductions trailing-0-count))))) (local (defthm var-negated-inverse (implies (and (< (nfix n) numvars) (natp numvars)) (equal (logtail (ash 1 (nfix n)) (var n numvars)) (loghead (ash 1 numvars) (lognot (var n numvars))))))) (local (in-theory (disable var-negated))) (local (defthm loghead-when-less-than-ash (implies (and (natp x) (< x (ash 1 (nfix n)))) (equal (loghead n x) x)) :hints (("Goal" :in-theory (enable* ihsext-inductions ihsext-recursive-redefs))))) (local (in-theory (enable logbitp-of-loghead-split plus-ash-1-is-install-bit ash-1-monotonic))) (local (defthmd plus-ash-overflows-implies-logbitp (implies (and (not (logbitp n x)) (< x (ash 1 numvars)) (< n numvars) (natp x) (natp numvars) (natp n)) (< (+ (ash 1 n) x) (ash 1 numvars))) :hints (("goal" :use ((:instance unsigned-byte-p-of-install-bit (n numvars) (i n) (v 1) (x x))) :in-theory (disable unsigned-byte-p-of-install-bit)) (and stable-under-simplificationp '(:in-theory (enable unsigned-byte-p expt-2-is-ash)))))) (defret depends-on-witness-correct (implies (and (natp numvars) (< (nfix n) numvars) (depends-on n truth numvars)) (not (equal (truth-eval truth (env-update n t diff-env) numvars) (truth-eval truth diff-env numvars)))) :hints (("goal" :in-theory (enable depends-on truth-eval truth-norm env-update)) (use-termhint (b* ((var (var n numvars)) (truth (truth-norm truth numvars)) (var-0-part (logand (lognot var) truth)) (var-1-part (ash (logand var truth) (- (ash 1 (nfix n))))) (diff (logxor var-0-part var-1-part)) (count (trailing-0-count diff)) ((when (<= (ash 1 numvars) count)) `'(:use ((:instance trailing-0-count-bound-when-unsigned-byte-p (n (ash 1 numvars)) (x ,(TRUTH::HQ TRUTH::DIFF)))))) ((when (and (not (logbitp n count)) (<= (+ (ash 1 numvars) (- (ash 1 (nfix n)))) count))) `'(:use ((:instance plus-ash-overflows-implies-logbitp (x ,(TRUTH::HQ COUNT)) (n (nfix n))))))) `'(:use ((:instance trailing-0-count-of-logxor-when-not-equal (x ,(TRUTH::HQ TRUTH::VAR-0-PART)) (y ,(TRUTH::HQ TRUTH::VAR-1-PART))))))))))
other
(defsection depends-on-of-operators (defthm depends-on-of-logand (implies (and (not (depends-on n x numvars)) (not (depends-on n y numvars)) (natp numvars) (< (nfix n) numvars)) (not (depends-on n (logand x y) numvars))) :hints (("goal" :use ((:instance depends-on-witness-correct (truth (logand x y)))) :in-theory (disable depends-on-witness-correct depends-on-correct)) (use-termhint (b* ((env (depends-on-witness n (logand x y) numvars)) (env1 (env-update n t env)) ((unless (equal (truth-eval x env1 numvars) (truth-eval x env numvars))) `'(:use ((:instance depends-on-correct (truth x) (val t) (env ,(TRUTH::HQ TRUTH::ENV)))))) ((unless (equal (truth-eval y env1 numvars) (truth-eval y env numvars))) `'(:use ((:instance depends-on-correct (truth y) (val t) (env ,(TRUTH::HQ TRUTH::ENV))))))) nil)))) (defthm depends-on-of-logior (implies (and (not (depends-on n x numvars)) (not (depends-on n y numvars)) (natp numvars) (< (nfix n) numvars)) (not (depends-on n (logior x y) numvars))) :hints (("goal" :use ((:instance depends-on-witness-correct (truth (logior x y)))) :in-theory (disable depends-on-witness-correct depends-on-correct)) (use-termhint (b* ((env (depends-on-witness n (logior x y) numvars)) (env1 (env-update n t env)) ((unless (equal (truth-eval x env1 numvars) (truth-eval x env numvars))) `'(:use ((:instance depends-on-correct (truth x) (val t) (env ,(TRUTH::HQ TRUTH::ENV)))))) ((unless (equal (truth-eval y env1 numvars) (truth-eval y env numvars))) `'(:use ((:instance depends-on-correct (truth y) (val t) (env ,(TRUTH::HQ TRUTH::ENV))))))) nil)))) (defthm depends-on-of-logxor (implies (and (not (depends-on n x numvars)) (not (depends-on n y numvars)) (natp numvars) (< (nfix n) numvars)) (not (depends-on n (logxor x y) numvars))) :hints (("goal" :use ((:instance depends-on-witness-correct (truth (logxor x y)))) :in-theory (disable depends-on-witness-correct depends-on-correct)) (use-termhint (b* ((env (depends-on-witness n (logxor x y) numvars)) (env1 (env-update n t env)) ((unless (equal (truth-eval x env1 numvars) (truth-eval x env numvars))) `'(:use ((:instance depends-on-correct (truth x) (val t) (env ,(TRUTH::HQ TRUTH::ENV)))))) ((unless (equal (truth-eval y env1 numvars) (truth-eval y env numvars))) `'(:use ((:instance depends-on-correct (truth y) (val t) (env ,(TRUTH::HQ TRUTH::ENV))))))) nil)))) (defthm depends-on-of-lognot (implies (and (natp numvars) (< (nfix n) numvars)) (iff (depends-on n (lognot x) numvars) (depends-on n x numvars))) :hints ((use-termhint (b* (((mv dep indep) (if (depends-on n x numvars) (mv x (lognot x)) (mv (lognot x) x))) (env (depends-on-witness n dep numvars))) `'(:use ((:instance depends-on-witness-correct (truth ,(TRUTH::HQ TRUTH::DEP))) (:instance depends-on-correct (truth ,(TRUTH::HQ TRUTH::INDEP)) (val t) (env ,(TRUTH::HQ TRUTH::ENV)))) :in-theory (disable depends-on-correct depends-on-witness-correct)))))))
other
(define env-mismatch-aux ((n natp) (truth integerp) (env1 natp) (env2 natp) (numvars natp)) :guard (<= n numvars) :measure (nfix (- (nfix numvars) (nfix n))) :returns (var natp :rule-classes :type-prescription) (b* (((when (mbe :logic (zp (- (nfix numvars) (nfix n))) :exec (eql n numvars))) 0) ((when (and (depends-on n truth numvars) (xor (env-lookup n env1) (env-lookup n env2)))) (lnfix n))) (env-mismatch-aux (+ 1 (lnfix n)) truth env1 env2 numvars)) /// (defret env-mismatch-aux-bound (implies (posp numvars) (< var numvars))) (defret env-mismatch-aux-when-mismatch (implies (and (depends-on m truth numvars) (xor (env-lookup m env1) (env-lookup m env2)) (< (nfix m) (nfix numvars)) (<= (nfix n) (nfix m))) (and (depends-on var truth numvars) (iff (env-lookup var env1) (not (env-lookup var env2))) (< var numvars))) :hints (("Goal" :in-theory (enable* arith-equiv-forwarding)))) (local (defthm loghead-plus-1-equal-when-loghead-equal (implies (and (iff (env-lookup n env1) (env-lookup n env2)) (equal (loghead n (nfix env1)) (loghead n (nfix env2)))) (equal (equal (loghead (+ 1 (nfix n)) (nfix env1)) (loghead (+ 1 (nfix n)) (nfix env2))) t)) :hints (("goal" :in-theory (enable env-lookup)) (logbitp-reasoning)))) (local (in-theory (enable logbitp-of-install-bit-split))) (local (defthm loghead-plus-1-equal-when-loghead-equal-update (implies (and (equal (loghead n (nfix env1)) (loghead n (nfix env2))) (equal val (env-lookup n env1))) (equal (equal (loghead (+ 1 (nfix n)) (nfix env1)) (loghead (+ 1 (nfix n)) (env-update n val env2))) t)) :hints (("goal" :in-theory (enable env-lookup env-update)) (logbitp-reasoning)))) (local (defthm env-mismatch-aux-of-env-update-less (implies (< (nfix m) (nfix n)) (equal (env-mismatch-aux n truth env1 (env-update m val env2) numvars) (env-mismatch-aux n truth env1 env2 numvars))))) (local (defun env-mismatch-aux-when-eval-mismatch-ind (n truth env1 env2 numvars) (declare (xargs :measure (nfix (- (nfix numvars) (nfix n))))) (b* (((when (zp (- (nfix numvars) (nfix n)))) (list truth env1 env2)) ((when (and (depends-on n truth numvars) (xor (env-lookup n env1) (env-lookup n env2)))) (lnfix n)) ((when (xor (env-lookup n env1) (env-lookup n env2))) (env-mismatch-aux-when-eval-mismatch-ind (+ 1 (lnfix n)) truth env1 (env-update n (env-lookup n env1) env2) numvars))) (env-mismatch-aux-when-eval-mismatch-ind (+ 1 (lnfix n)) truth env1 env2 numvars)))) (local (defthmd loghead-equal-when-loghead-greater-equal (implies (and (equal (loghead n x) (loghead n y)) (<= (nfix m) (nfix n))) (equal (loghead m x) (loghead m y))) :hints ((logbitp-reasoning)))) (local (defthm truth-eval-equal-when-loghead-equal (implies (and (<= (nfix numvars) (nfix n)) (equal (loghead n (nfix env1)) (loghead n (nfix env2)))) (equal (equal (truth-eval truth env1 numvars) (truth-eval truth env2 numvars)) t)) :hints (("goal" :in-theory (enable truth-eval) :use ((:instance loghead-equal-when-loghead-greater-equal (m numvars) (x (nfix env1)) (y (nfix env2)))))))) (defret env-mismatch-aux-when-eval-mismatch (implies (and (not (equal (truth-eval truth env1 numvars) (truth-eval truth env2 numvars))) (equal (loghead n (nfix env1)) (loghead n (nfix env2)))) (and (depends-on var truth numvars) (iff (env-lookup var env1) (not (env-lookup var env2))) (< var (nfix numvars)) (implies (natp numvars) (< var numvars)))) :hints (("goal" :induct (env-mismatch-aux-when-eval-mismatch-ind n truth env1 env2 numvars)))))
other
(define env-mismatch ((truth integerp) (env1 natp) (env2 natp) (numvars natp)) :returns (var natp :rule-classes :type-prescription) (env-mismatch-aux 0 truth env1 env2 numvars) /// (defret env-mismatch-bound (implies (posp numvars) (< var numvars)) :rule-classes (:rewrite :linear)) (defret env-mismatch-when-mismatch (implies (and (depends-on m truth numvars) (xor (env-lookup m env1) (env-lookup m env2)) (< (nfix m) (nfix numvars))) (and (depends-on var truth numvars) (iff (env-lookup var env1) (not (env-lookup var env2))) (< var (nfix numvars)) (implies (natp numvars) (< var numvars))))) (defret env-mismatch-when-eval-mismatch (implies (and (not (equal (truth-eval truth env1 numvars) (truth-eval truth env2 numvars)))) (and (depends-on var truth numvars) (iff (env-lookup var env1) (not (env-lookup var env2))) (< var (nfix numvars)) (implies (natp numvars) (< var numvars))))))
other
(define is-xor-with-var ((n natp) (truth integerp) (numvars natp)) :short "Checks whether the given truth table is the xor of variable n with something. If so, the other input to the xor is the negative cofactor of the truth table with n." :guard (< n numvars) (equal (truth-norm (positive-cofactor n truth numvars) numvars) (truth-norm (lognot (negative-cofactor n truth numvars)) numvars)) /// (defthm is-xor-with-var-correct (implies (and (is-xor-with-var n truth numvars) (< (nfix n) (nfix numvars))) (equal (truth-eval (logxor (negative-cofactor n truth numvars) (var n numvars)) env numvars) (truth-eval truth env numvars))) :hints (("goal" :use ((:instance truth-eval-of-truth-norm (truth (positive-cofactor n truth numvars))) (:instance truth-eval-of-truth-norm (truth (lognot (negative-cofactor n truth numvars))))) :in-theory (disable truth-eval-of-truth-norm) :cases ((env-lookup n env))))) (defthm is-xor-with-var-of-truth-norm (equal (is-xor-with-var n (truth-norm truth numvars) numvars) (is-xor-with-var n truth numvars))))
other
(defsection logbitp-loghead-of-add-theory (local (defun logbitp-of-plus-ind (n c a b) (if (zp n) (list a b c) (logbitp-of-plus-ind (1- n) (b-ior (b-and (logcar a) (logcar b)) (b-ior (b-and c (logcar a)) (b-and c (logcar b)))) (logcdr a) (logcdr b))))) (local (defthm logbitp-of-plus-lemma (implies (and (integerp a) (integerp b) (bitp c)) (equal (logbitp n (+ c a b)) (equal 1 (b-xor (logbit n a) (b-xor (logbit n b) (bool->bit (<= (ash 1 (nfix n)) (+ c (loghead n a) (loghead n b))))))))) :hints (("goal" :induct (logbitp-of-plus-ind n c a b) :in-theory (e/d* (logcons bool->bit b-and bitp) (loghead-identity logbitp-when-bitmaskp)) :expand ((:free (x) (logbitp n x)) (:free (x) (loghead n x)) (:free (x) (logbitp 0 x)) (ash 1 (nfix n)) (ash 1 n)))))) (defthmd logbitp-of-plus (implies (and (integerp a) (integerp b)) (equal (logbitp n (+ a b)) (equal 1 (b-xor (logbit n a) (b-xor (logbit n b) (bool->bit (<= (ash 1 (nfix n)) (+ (loghead n a) (loghead n b))))))))) :hints (("Goal" :use ((:instance logbitp-of-plus-lemma (c 0)))))) (local (defthm loghead-of-plus-lemma (implies (and (integerp a) (integerp b) (bitp c)) (equal (loghead n (+ c a b)) (let ((sum (+ c (loghead n a) (loghead n b)))) (if (<= (ash 1 (nfix n)) sum) (- sum (ash 1 (nfix n))) sum)))) :hints (("goal" :induct (logbitp-of-plus-ind n c a b) :in-theory (e/d* (logcons bool->bit b-and bitp) (loghead-identity)) :expand ((:free (x) (loghead n x)) (ash 1 (nfix n)) (ash 1 n)))))) (defthmd loghead-of-plus (implies (and (integerp a) (integerp b)) (equal (loghead n (+ a b)) (let ((sum (+ (loghead n a) (loghead n b)))) (if (<= (ash 1 (nfix n)) sum) (- sum (ash 1 (nfix n))) sum)))) :hints (("Goal" :use ((:instance loghead-of-plus-lemma (c 0)))))))
other
(local (defsection logbitp-of-plus-nonoverlap-theory (local (defun logbitp-ash-ind (n m x) (if (zp n) (list m x) (logbitp-ash-ind (1- n) (1- m) (logcdr x))))) (defthm logbitp-of-plus-ash-unset (implies (and (integerp x) (natp m) (not (logbitp (double-rewrite m) x))) (equal (logbitp n (+ x (ash 1 m))) (or (equal (nfix n) m) (logbitp n x)))) :hints (("goal" :induct (logbitp-ash-ind n m x) :in-theory (enable* ihsext-recursive-redefs)))) (local (defthm logcdr-minus-logcons-0 (equal (logcdr (- (logcons 0 x))) (- (ifix x))) :hints (("Goal" :in-theory (enable minus-to-lognot))))) (defthm logbitp-of-plus-ash-unset-2 (implies (and (integerp x) (natp m) (not (logbitp (double-rewrite m) x))) (equal (logbitp n (+ (ash 1 m) x)) (or (equal (nfix n) m) (logbitp n x))))) (defthm logbitp-of-plus-ash-unset-3 (implies (and (integerp x) (integerp y) (natp m) (not (logbitp (double-rewrite m) (+ x y)))) (equal (logbitp n (+ x (ash 1 m) y)) (or (equal (nfix n) m) (logbitp n (+ x y))))) :hints (("Goal" :use ((:instance logbitp-of-plus-ash-unset-2 (x (+ x y))))))) (defthm logbitp-of-minus-ash-set (implies (and (integerp x) (natp m) (logbitp (double-rewrite m) x)) (equal (logbitp n (+ x (- (ash 1 m)))) (and (not (equal (nfix n) m)) (logbitp n x)))) :hints (("goal" :induct (logbitp-ash-ind n m x) :in-theory (enable* ihsext-recursive-redefs) :expand ((:free (x) (logbitp n x)) (:free (x) (logbitp m x)))))) (defthm logbitp-of-minus-ash-set-2 (implies (and (integerp x) (natp m) (logbitp (double-rewrite m) x)) (equal (logbitp n (+ (- (ash 1 m)) x)) (and (not (equal (nfix n) m)) (logbitp n x))))) (defthm logbitp-of-minus-ash-set-3 (implies (and (integerp x) (integerp y) (natp m) (logbitp (double-rewrite m) (+ x y))) (equal (logbitp n (+ x (- (ash 1 m)) y)) (and (not (equal (nfix n) m)) (logbitp n (+ x y))))) :hints (("Goal" :use ((:instance logbitp-of-minus-ash-set-2 (x (+ x y))))))) (defthm loghead-of-plus-ash-unset (implies (and (integerp x) (natp m) (not (logbitp (double-rewrite m) x))) (equal (loghead n (+ x (ash 1 m))) (+ (if (<= (nfix n) m) 0 (ash 1 m)) (loghead n x)))) :hints (("goal" :induct (logbitp-ash-ind n m x) :in-theory (enable* ihsext-recursive-redefs logcons)))) (defthm loghead-of-plus-ash-unset-2 (implies (and (integerp x) (natp m) (not (logbitp (double-rewrite m) x))) (equal (loghead n (+ (ash 1 m) x)) (+ (if (<= (nfix n) m) 0 (ash 1 m)) (loghead n x))))) (defthm loghead-of-plus-ash-unset-3 (implies (and (integerp x) (integerp y) (natp m) (not (logbitp (double-rewrite m) (+ x y)))) (equal (loghead n (+ x (ash 1 m) y)) (+ (if (<= (nfix n) m) 0 (ash 1 m)) (loghead n (+ x y))))) :hints (("Goal" :use ((:instance loghead-of-plus-ash-unset-2 (x (+ x y))))))) (local (defthm logcdr-minus-2x (implies (integerp x) (equal (logcdr (- (* 2 x))) (- x))) :hints (("Goal" :use ((:instance logcdr-of-logcons (x (- x)) (b 0))) :in-theory (e/d (logcons) (logcdr-of-logcons)))))) (defthm loghead-of-minus-ash-set (implies (and (integerp x) (natp m) (logbitp (double-rewrite m) x)) (equal (loghead n (+ x (- (ash 1 m)))) (+ (if (<= (nfix n) m) 0 (- (ash 1 m))) (loghead n x)))) :hints (("goal" :induct (logbitp-ash-ind n m x) :in-theory (enable* ihsext-recursive-redefs logcons) :expand ((:free (x) (loghead n x)) (:free (x) (loghead m x)))))) (defthm loghead-of-minus-ash-set-2 (implies (and (integerp x) (natp m) (logbitp (double-rewrite m) x)) (equal (loghead n (+ (- (ash 1 m)) x)) (+ (if (<= (nfix n) m) 0 (- (ash 1 m))) (loghead n x))))) (defthm loghead-of-minus-ash-set-3 (implies (and (integerp x) (integerp y) (natp m) (logbitp (double-rewrite m) (+ x y))) (equal (loghead n (+ x (- (ash 1 m)) y)) (+ (if (<= (nfix n) m) 0 (- (ash 1 m))) (loghead n (+ x y))))) :hints (("Goal" :use ((:instance loghead-of-minus-ash-set-2 (x (+ x y)))))))))
other
(local (defsection logbitp-of-plus-ash-same-theory (local (defthm logbitp-of-plus-ash-base (implies (and (integerp x)) (equal (logbitp m (+ x (ash 1 (nfix m)))) (not (logbitp m x)))) :hints (("Goal" :in-theory (enable* ihsext-inductions ihsext-recursive-redefs))))) (defthm logbitp-of-plus-ash (implies (and (equal mm (nfix m)) (integerp x)) (equal (logbitp m (+ x (ash 1 mm))) (not (logbitp m x))))) (defthm logbitp-of-plus-ash-1 (implies (and (equal mm (nfix m)) (integerp x)) (equal (logbitp m (+ (ash 1 mm) x)) (not (logbitp m x)))) :hints (("Goal" :use ((:instance logbitp-of-plus-ash (x x))) :in-theory (disable logbitp-of-plus-ash)))) (defthm logbitp-of-plus-ash-2 (implies (and (equal mm (nfix m)) (integerp x) (integerp y)) (equal (logbitp m (+ x (ash 1 mm) y)) (not (logbitp m (+ x y))))) :hints (("Goal" :use ((:instance logbitp-of-plus-ash (x (+ x y)))) :in-theory (disable logbitp-of-plus-ash)))) (defthm logbitp-of-plus-ash-3 (implies (and (equal mm (nfix m)) (integerp x) (integerp y)) (equal (logbitp m (+ x y (ash 1 mm))) (not (logbitp m (+ x y))))) :hints (("Goal" :use ((:instance logbitp-of-plus-ash (x (+ x y)))) :in-theory (disable logbitp-of-plus-ash)))) (defthm logbitp-of-minus-ash-base (implies (and (integerp x)) (equal (logbitp m (+ x (- (ash 1 (nfix m))))) (not (logbitp m x)))) :hints (("Goal" :use ((:instance logbitp-of-plus-ash-base (x (+ x (- (ash 1 (nfix m))))))) :in-theory (disable logbitp-of-plus-ash-base)))) (defthm logbitp-of-minus-ash (implies (and (equal mm (nfix m)) (integerp x)) (equal (logbitp m (+ x (- (ash 1 mm)))) (not (logbitp m x))))) (defthm logbitp-of-minus-ash-1 (implies (and (equal mm (nfix m)) (integerp x)) (equal (logbitp m (+ (- (ash 1 mm)) x)) (not (logbitp m x)))) :hints (("Goal" :use ((:instance logbitp-of-minus-ash (x x))) :in-theory (disable logbitp-of-minus-ash)))) (defthm logbitp-of-minus-ash-2 (implies (and (equal mm (nfix m)) (integerp x)) (equal (logbitp m (+ (- (ash 1 mm)) x)) (not (logbitp m x)))) :hints (("Goal" :use ((:instance logbitp-of-plus-ash (x (+ x (- (ash 1 m)))))) :in-theory (disable logbitp-of-plus-ash)))) (defthm logbitp-of-minus-ash-3 (implies (and (equal mm (nfix m)) (integerp x) (integerp y)) (equal (logbitp m (+ x (- (ash 1 mm)) y)) (not (logbitp m (+ x y))))) :hints (("Goal" :use ((:instance logbitp-of-minus-ash (x (+ x y)) (m mm))) :in-theory (disable logbitp-of-minus-ash)))) (defthmd logbitp-when-less-than-ash (implies (and (natp n) (< n (ash 1 m)) (natp m)) (not (logbitp m n))) :hints (("Goal" :in-theory (enable* ihsext-inductions ihsext-recursive-redefs))))))
other
(defsection complements-related-by-shift (local (defun loghead-of-plus-ash-ind (m n x) (if (zp m) (list x n) (loghead-of-plus-ash-ind (1- m) (1- (nfix n)) (logcdr x))))) (local (defthm logbitp-of-plus-ash-greater (implies (and (< (nfix m) n) (natp n) (integerp x)) (equal (logbitp m (+ x (ash 1 n))) (logbitp m x))) :hints (("Goal" :induct (loghead-of-plus-ash-ind m n x) :in-theory (enable* ihsext-recursive-redefs))))) (local (defthm logbitp-of-minus-ash-greater (implies (and (< (nfix m) n) (natp n) (integerp x)) (equal (logbitp m (+ x (- (ash 1 n)))) (logbitp m x))) :hints (("Goal" :use ((:instance logbitp-of-plus-ash-greater (x (+ x (- (ash 1 n)))))) :in-theory (disable logbitp-of-plus-ash-greater))))) (local (defthm logbitp-of-plus-lesser-when-not-logbitp (implies (and (< (nfix m) n) (natp n) (integerp x) (not (logbitp (double-rewrite m) x))) (equal (logbitp n (+ x (ash 1 m))) (logbitp n x))) :hints (("goal" :induct (loghead-of-plus-ash-ind m n x) :in-theory (enable* ihsext-recursive-redefs) :expand ((:free (x) (logbitp n x))))))) (local (in-theory (enable ash-1-monotonic))) (local (defthm loghead-by-bounds (implies (and (<= (ash 1 num) b) (< b (* 2 (ash 1 num))) (natp num) (integerp b)) (equal (loghead num b) (- b (ash 1 num)))) :hints (("Goal" :in-theory (enable loghead ash-is-expt-*-x))))) (local (defthm logbitp-when-bounded-lemma (implies (and (< b (+ (ash 1 n) (- (ash 1 m)))) (natp b) (natp n) (natp m) (not (logbitp (double-rewrite m) b))) (not (logbitp n b))) :hints (("Goal" :induct (loghead-of-plus-ash-ind m n b) :in-theory (enable* ihsext-recursive-redefs logcons logbitp-when-less-than-ash))))) (local (defthm logbitp-when-bounded-lemma2 (implies (and (< (+ b (- (ash 1 n)) (ash 1 m)) (ash 1 num)) (natp b) (natp n) (natp m) (< m n) (natp num) (< n num) (<= (ash 1 num) b) (not (logbitp (double-rewrite m) b))) (not (logbitp n b))) :hints (("goal" :use ((:instance logbitp-of-loghead-in-bounds (pos m) (i b) (size num)) (:instance logbitp-of-loghead-in-bounds (pos n) (i b) (size num)) (:instance logbitp-when-bounded-lemma (b (loghead num b)))) :in-theory (e/d (ash-1-monotonic) (logbitp-of-loghead-in-bounds)))))) (defthmd complements-related-by-shift (implies (and (< (nfix n) numvars) (natp numvars) (< (nfix m) (nfix n))) (equal (logand (var n numvars) (lognot (var m numvars))) (ash (logand (var m numvars) (lognot (var n numvars))) (- (ash 1 (nfix n)) (ash 1 (nfix m)))))) :hints ((logbitp-reasoning) (and stable-under-simplificationp '(:cases ((< wbit0 (- (ash 1 n) (ash 1 (nfix m)))))))) :otf-flg t) (local (defthm ash-of-logand (equal (ash (logand a b) sh) (logand (ash a sh) (ash b sh))) :hints (("Goal" :in-theory (enable* ihsext-inductions ihsext-recursive-redefs))))) (defthm complements-related-by-shift-unshift (implies (and (< (nfix n) numvars) (natp numvars) (equal mm (nfix m)) (< (nfix m) (nfix n))) (equal (logand (ash (var m numvars) (+ (ash 1 n) (- (ash 1 mm)))) (ash (lognot (var n numvars)) (+ (ash 1 n) (- (ash 1 mm))))) (logand (var n numvars) (lognot (var m numvars))))) :hints (("goal" :use ((:instance complements-related-by-shift)) :in-theory (disable complements-related-by-shift))) :otf-flg t) (defthm complements-related-by-shift-unshift2 (implies (and (< (nfix n) numvars) (natp numvars) (equal mm (nfix m)) (< (nfix m) (nfix n))) (equal (logand (ash (var m numvars) (+ (- (ash 1 mm)) (ash 1 n))) (ash (lognot (var n numvars)) (+ (- (ash 1 mm)) (ash 1 n)))) (logand (var n numvars) (lognot (var m numvars))))) :hints (("goal" :use ((:instance complements-related-by-shift)) :in-theory (disable complements-related-by-shift))) :otf-flg t) (defthm complements-related-by-shift-unshift3 (implies (and (< (nfix n) numvars) (natp numvars) (equal mm (nfix m)) (< (nfix m) (nfix n))) (equal (logand (ash (var m numvars) (+ (ash 1 n) (- (ash 1 mm)))) (ash (lognot (var n numvars)) (+ (ash 1 n) (- (ash 1 mm)))) z) (logand (var n numvars) (lognot (var m numvars)) z))) :hints (("goal" :use ((:instance complements-related-by-shift)) :in-theory (disable complements-related-by-shift))) :otf-flg t) (defthm complements-related-by-shift-untail (implies (and (< (nfix n) numvars) (natp numvars) (< (nfix m) (nfix n))) (equal (logand (logtail (+ (ash 1 n) (- (ash 1 (nfix m)))) (var n numvars)) (lognot (logtail (+ (ash 1 n) (- (ash 1 (nfix m)))) (var m numvars)))) (logand (var m numvars) (lognot (var n numvars))))) :hints (("goal" :use ((:instance ash-of-logand (a (var n numvars)) (b (lognot (var m numvars))) (sh (- (+ (ash 1 n) (- (ash 1 (nfix m)))))))) :in-theory (e/d (complements-related-by-shift)))) :otf-flg t) (defthm complements-related-by-shift-untail3 (implies (and (< (nfix n) numvars) (natp numvars) (< (nfix m) (nfix n))) (equal (logand (logtail (+ (ash 1 n) (- (ash 1 (nfix m)))) (var n numvars)) (lognot (logtail (+ (ash 1 n) (- (ash 1 (nfix m)))) (var m numvars))) z) (logand (var m numvars) (lognot (var n numvars)) z))) :hints (("goal" :use ((:instance complements-related-by-shift-untail)) :in-theory (disable complements-related-by-shift-untail))) :otf-flg t))
other
(define index-swap ((n natp "first element to swap") (m natp "second element to swap") (x natp "index to apply the swap to")) :returns (swap natp :rule-classes :type-prescription) (b* ((x (lnfix x)) (n (lnfix n)) (m (lnfix m))) (cond ((eql x n) m) ((eql x m) n) (t x))) /// (defthm index-swap-commute (equal (index-swap m n x) (index-swap n m x)) :rule-classes ((:rewrite :loop-stopper ((n m))))) (defthm index-swap-inverse (equal (index-swap n m (index-swap n m x)) (nfix x))) (defthm index-swap-n (equal (index-swap n m n) (nfix m))) (defthm index-swap-m (equal (index-swap n m m) (nfix n))) (defthm index-swap-unaffected (implies (and (not (nat-equiv n x)) (not (nat-equiv m x))) (equal (index-swap n m x) (nfix x)))) (defthm index-swap-self (equal (index-swap n n x) (nfix x))) (defthm index-swap-unique (iff (equal (index-swap n m x) (index-swap n m y)) (equal (nfix x) (nfix y)))))
other
(define env-swap-vars ((n natp "first element to swap") (m natp "second element to swap") (env natp "env to apply the swap to")) :returns (swap-env natp :rule-classes :type-prescription) (b* ((env (lnfix env)) (n (lnfix n)) (m (lnfix m))) (env-update n (env-lookup m env) (env-update m (env-lookup n env) env))) /// (local (in-theory (enable* logbitp-of-install-bit-split arith-equiv-forwarding))) (defthm env-swap-vars-commute (equal (env-swap-vars m n x) (env-swap-vars n m x)) :hints (("Goal" :in-theory (enable env-update env-lookup)) (logbitp-reasoning)) :rule-classes ((:rewrite :loop-stopper ((n m))))) (defret lookup-in-env-swap-vars (equal (env-lookup k swap-env) (env-lookup (index-swap n m k) env)) :hints (("Goal" :in-theory (enable* arith-equiv-forwarding)))) (defthm env-swap-vars-inverse (equal (env-swap-vars n m (env-swap-vars n m env)) (nfix env)) :hints (("Goal" :in-theory (enable* arith-equiv-forwarding)))) (defthm env-swap-vars-self (equal (env-swap-vars n n env) (nfix env))))
other
(define swap-vars-aux ((n natp) (m natp) (truth integerp) (numvars natp)) :guard (and (< n numvars) (< m n)) :returns (swapped-truth integerp :rule-classes :type-prescription) (b* ((truth (loghead (ash 1 (lnfix numvars)) truth)) (varn (var n numvars)) (varm (var m numvars)) (same (logeqv varn varm)) (n&~m (logand varn (lognot varm))) (m&~n (logand varm (lognot varn))) (shift (- (ash 1 (lnfix n)) (ash 1 (lnfix m))))) (logior (logand same truth) (ash (logand n&~m truth) (- shift)) (ash (logand m&~n truth) shift))) /// (local (defthm loghead-over-install-bit (implies (< (nfix n) (nfix w)) (equal (loghead w (install-bit n b x)) (install-bit n b (loghead w x)))) :hints ((logbitp-reasoning) (and stable-under-simplificationp '(:in-theory (enable logbitp-of-install-bit-split logbitp-of-loghead-split)))))) (local (defthmd logcdr-when-not-integerp (implies (not (integerp x)) (equal (logcdr x) 0)) :hints (("Goal" :in-theory (enable logcdr))))) (local (defthmd logcar-when-not-integerp (implies (not (integerp x)) (equal (logcar x) 0)) :hints (("Goal" :in-theory (enable logcar))))) (local (defthmd install-bit-1-when-not-set (implies (not (logbitp n x)) (equal (install-bit n 1 x) (+ (ash 1 (nfix n)) (ifix x)))) :hints (("Goal" :in-theory (enable* ihsext-inductions ihsext-recursive-redefs install-bit** logcons logcar-when-not-integerp logcdr-when-not-integerp))))) (local (defthmd install-bit-0-when-set (implies (logbitp n x) (equal (install-bit n 0 x) (+ (- (ash 1 (nfix n))) (ifix x)))) :hints (("Goal" :in-theory (enable* ihsext-inductions ihsext-recursive-redefs install-bit** logcons logcar-when-not-integerp logcdr-when-not-integerp))))) (local (defthm loghead->=-ash-when-logbitp (implies (and (logbitp n env) (natp n) (natp numvars) (< n numvars)) (<= (ash 1 n) (loghead numvars env))) :hints (("goal" :use ((:instance logbitp-of-loghead-in-bounds (pos n) (i env) (size numvars))) :in-theory (e/d (logbitp-when-less-than-ash) (logbitp-of-loghead-in-bounds)))) :rule-classes :linear)) (local (defthmd swap-bits-is-add (implies (and (equal b1 (bool->bit (logbitp m x))) (equal b2 (bool->bit (logbitp n x)))) (equal (install-bit n b1 (install-bit m b2 x)) (if (xor (logbitp n x) (logbitp m x)) (if (logbitp n x) (+ (- (ash 1 (nfix n))) (ash 1 (nfix m)) (ifix x)) (+ (ash 1 (nfix n)) (- (ash 1 (nfix m))) (ifix x))) (ifix x)))) :hints (("goal" :use ((:instance install-bit-0-when-set (x (install-bit m (bool->bit (logbitp n x)) x))) (:instance install-bit-1-when-not-set (x (install-bit m (bool->bit (logbitp n x)) x)))) :in-theory (enable logbitp-of-install-bit-split)) (and stable-under-simplificationp '(:use ((:instance install-bit-0-when-set (n m)) (:instance install-bit-1-when-not-set (n m)))))))) (local (defthm ash-of-logand (equal (ash (logand a b) sh) (logand (ash a sh) (ash b sh))) :hints (("Goal" :in-theory (enable* ihsext-inductions ihsext-recursive-redefs))))) (local (in-theory (disable install-bit-of-install-bit-diff logtail-of-loghead))) (local (defthmd truth-eval-with-loghead (equal (truth-eval truth env numvars) (logbitp (loghead (nfix numvars) (nfix env)) (loghead (ash 1 (nfix numvars)) truth))) :hints (("Goal" :use truth-eval-of-truth-norm :in-theory (e/d (truth-eval truth-norm) (truth-eval-of-truth-norm)))) :rule-classes ((:definition :install-body t)))) (defret eval-of-swap-vars-aux (implies (and (< (nfix n) (nfix numvars)) (< (nfix m) (nfix n))) (equal (truth-eval swapped-truth env numvars) (truth-eval truth (env-swap-vars n m env) numvars))) :hints (("Goal" :in-theory (e/d (ash-1-monotonic env-swap-vars) (truth-eval-of-logand truth-eval-of-logior truth-eval-of-lognot truth-eval-of-logxor))) (and stable-under-simplificationp '(:in-theory (enable env-update env-lookup loghead-less-than-ash ash-1-monotonic) :expand ((:with truth-eval (:free (x) (truth-eval x env numvars))) (:with truth-eval-with-loghead (:free (env) (truth-eval truth env numvars)))))) (and stable-under-simplificationp '(:in-theory (enable swap-bits-is-add logbitp-of-loghead-split loghead-less-than-ash ash-1-monotonic))) (and stable-under-simplificationp '(:in-theory (enable loghead-less-than-ash) :use ((:instance ash-1-monotonic (a (nfix m)) (b n)))))) :otf-flg t) (local (defret size-of-swap-vars-lemma (implies (and (< (nfix n) (nfix numvars)) (< (nfix m) (nfix n))) (unsigned-byte-p (ash 1 numvars) swapped-truth)) :hints (("Goal" :in-theory (enable ash-1-monotonic))))) (defret size-of-swap-vars-aux (implies (and (< (nfix n) (nfix numvars)) (< (nfix m) (nfix n)) (natp size) (<= (ash 1 (nfix numvars)) size)) (unsigned-byte-p size swapped-truth)) :hints (("goal" :use size-of-swap-vars-lemma :in-theory (disable size-of-swap-vars-lemma swap-vars-aux)))) (defret truth-norm-of-swap-vars-aux (implies (and (< (nfix n) (nfix numvars)) (< (nfix m) (nfix n))) (equal (truth-norm swapped-truth numvars) swapped-truth)) :hints (("Goal" :in-theory (e/d (truth-norm loghead-identity) (swap-vars-aux))))) (defthm swap-vars-aux-of-truth-norm (equal (swap-vars-aux n m (truth-norm truth numvars) numvars) (swap-vars-aux n m truth numvars)) :hints (("Goal" :in-theory (enable truth-norm)))))
other
(define swap-vars ((n natp) (m natp) (truth integerp) (numvars natp)) :guard (and (< n numvars) (< m numvars)) :returns (swapped-truth integerp :rule-classes :type-prescription) (cond ((< (lnfix n) (lnfix m)) (swap-vars-aux m n truth numvars)) ((< (lnfix m) (lnfix n)) (swap-vars-aux n m truth numvars)) (t (truth-norm truth numvars))) /// (defret swap-vars-commute (equal (swap-vars m n truth numvars) (swap-vars n m truth numvars)) :rule-classes ((:rewrite :loop-stopper ((n m))))) (defret eval-of-swap-vars (implies (and (< (nfix n) (nfix numvars)) (< (nfix m) (nfix numvars))) (equal (truth-eval swapped-truth env numvars) (truth-eval truth (env-swap-vars n m env) numvars))) :hints (("Goal" :in-theory (enable* arith-equiv-forwarding)))) (defret size-of-swap-vars (implies (and (< (nfix n) (nfix numvars)) (< (nfix m) (nfix numvars)) (natp size) (<= (ash 1 numvars) size)) (unsigned-byte-p size swapped-truth))) (defret swap-vars-self (equal (swap-vars n n truth numvars) (truth-norm truth numvars))) (defret truth-norm-of-swap-vars (implies (and (< (nfix n) (nfix numvars)) (< (nfix m) (nfix numvars))) (equal (truth-norm swapped-truth numvars) swapped-truth))) (defthm swap-vars-of-truth-norm (equal (swap-vars n m (truth-norm truth numvars) numvars) (swap-vars n m truth numvars))))
other
(local (defthm logcount-of-loghead-+-1 (implies (natp n) (equal (logcount (loghead (+ 1 n) mask)) (+ (logbit n mask) (logcount (loghead n mask))))) :hints (("Goal" :in-theory (enable* ihsext-inductions ihsext-recursive-redefs)))))
other
(local (defthm logcount-of-loghead-bound (<= (logcount (loghead n x)) (nfix n)) :hints (("Goal" :in-theory (enable* ihsext-inductions ihsext-recursive-redefs))) :rule-classes :linear))
other
(define index-move-up ((m natp) (n natp) (x natp)) :guard (<= m n) :measure (nfix (- (nfix n) (nfix m))) :returns (perm-idx natp :rule-classes :type-prescription) (b* (((when (mbe :logic (zp (- (nfix n) (nfix m))) :exec (eql n m))) (lnfix x)) (next (1+ (lnfix m))) (x (lnfix x)) (x (index-swap next m x))) (index-move-up next n x)) /// (local (in-theory (disable inequality-with-nfix-hyp-1))) (defthmd index-move-up-redef (equal (index-move-up m n x) (b* ((x (nfix x)) (m (nfix m)) (n (nfix n))) (cond ((<= n m) x) ((< x m) x) ((eql x m) n) ((<= x n) (1- x)) (t x)))) :hints (("Goal" :in-theory (enable index-swap)))))
other
(define index-move-down ((m natp) (n natp) (x natp)) :guard (<= m n) :measure (nfix (- (nfix n) (nfix m))) :returns (perm-idx natp :rule-classes :type-prescription) (b* (((when (mbe :logic (zp (- (nfix n) (nfix m))) :exec (eql n m))) (lnfix x)) (next (1+ (lnfix m))) (x (lnfix x)) (x (index-move-down next n x))) (index-swap next m x)) /// (local (in-theory (disable inequality-with-nfix-hyp-2 inequality-with-nfix-hyp-1 nfix-equal-to-nonzero))) (defthmd index-move-down-redef (equal (index-move-down m n x) (b* ((x (nfix x)) (m (nfix m)) (n (nfix n))) (cond ((<= n m) x) ((< x m) x) ((< x n) (1+ x)) ((eql x n) m) (t x)))) :hints (("Goal" :in-theory (enable index-swap)))) (defthm index-move-up-of-index-move-down (equal (index-move-up n m (index-move-down n m x)) (nfix x)) :hints (("Goal" :in-theory (enable index-move-up-redef index-move-down-redef)))) (local (defthm posp-of-nfix-when-greater (implies (and (<= (nfix x) (nfix y)) (not (equal (nfix x) (nfix y)))) (posp (nfix y))))) (defthm index-move-down-of-index-move-up (equal (index-move-down n m (index-move-up n m x)) (nfix x)) :hints (("Goal" :in-theory (enable index-move-up-redef index-move-down-redef) :do-not-induct t))))
other
(define index-permute-stretch ((n natp) (count) (mask natp) (x natp) (numvars natp)) :measure (nfix (- (nfix numvars) (nfix n))) :guard (and (<= n numvars) (eql count (logcount (loghead n mask)))) :returns (perm-index natp :rule-classes :type-prescription) (b* (((when (mbe :logic (zp (- (nfix numvars) (nfix n))) :exec (eql n numvars))) (lnfix x)) (n (lnfix n)) (count (mbe :logic (logcount (loghead n (lnfix mask))) :exec count)) (bit (logbit n (lnfix mask))) (x (index-permute-stretch (1+ n) (+ bit count) mask x numvars))) (if (eql bit 1) (index-move-up count n x) x)) /// (defret index-permute-stretch-bound (implies (< (nfix x) (nfix numvars)) (< perm-index (nfix numvars))) :hints (("Goal" :in-theory (enable index-move-up-redef))) :rule-classes :linear) (defthm index-permute-stretch-normalize-count (implies (syntaxp (not (equal count ''nil))) (equal (index-permute-stretch n count mask x numvars) (index-permute-stretch n nil mask x numvars))) :hints (("goal" :expand ((:free (count) (index-permute-stretch n count mask x numvars)))))))
other
(define index-permute-shrink ((n natp) (count) (mask natp) (x natp) (numvars natp)) :measure (nfix (- (nfix numvars) (nfix n))) :guard (and (<= n numvars) (eql count (logcount (loghead n mask)))) :returns (perm-index natp :rule-classes :type-prescription) (b* (((when (mbe :logic (zp (- (nfix numvars) (nfix n))) :exec (eql n numvars))) (lnfix x)) (n (lnfix n)) (count (mbe :logic (logcount (loghead n (lnfix mask))) :exec count)) (bit (logbit n (lnfix mask))) (x (if (eql bit 1) (index-move-down count n x) x))) (index-permute-shrink (1+ n) (+ bit count) mask x numvars)) /// (defret index-permute-shrink-bound (implies (< (nfix x) (nfix numvars)) (< perm-index (nfix numvars))) :hints (("Goal" :in-theory (enable index-move-down-redef))) :rule-classes :linear) (defthm index-permute-shrink-normalize-count (implies (syntaxp (not (equal count ''nil))) (equal (index-permute-shrink n count mask x numvars) (index-permute-shrink n nil mask x numvars))) :hints (("goal" :expand ((:free (count) (index-permute-shrink n count mask x numvars)))))) (defthm index-permute-shrink-of-index-permute-stretch (equal (index-permute-shrink n count mask (index-permute-stretch n count2 mask x numvars) numvars) (nfix x)) :hints (("Goal" :in-theory (enable index-permute-stretch) :induct (index-permute-stretch n count2 mask x numvars) :expand ((:free (count2) (index-permute-stretch n count2 mask x numvars)) (:free (count x) (index-permute-shrink n count mask x numvars)))))) (defthm index-permute-stretch-of-index-permute-shrink (equal (index-permute-stretch n count mask (index-permute-shrink n count2 mask x numvars) numvars) (nfix x)) :hints (("Goal" :in-theory (enable index-permute-stretch) :induct (index-permute-shrink n count2 mask x numvars) :expand ((:free (count x) (index-permute-stretch n count mask x numvars)) (:free (count2) (index-permute-shrink n count2 mask x numvars)))))) (defthm index-permute-stretch-one-to-one (implies (not (equal (nfix x) (nfix y))) (not (equal (index-permute-stretch n count mask x numvars) (index-permute-stretch n count2 mask y numvars)))) :hints (("goal" :use ((:instance index-permute-shrink-of-index-permute-stretch (count2 count) (x x)) (:instance index-permute-shrink-of-index-permute-stretch (count2 count2) (x y))) :in-theory (disable index-permute-shrink-of-index-permute-stretch index-permute-shrink)))) (defthm index-permute-shrink-one-to-one (implies (not (equal (nfix x) (nfix y))) (not (equal (index-permute-shrink n count mask x numvars) (index-permute-shrink n count2 mask y numvars)))) :hints (("goal" :use ((:instance index-permute-stretch-of-index-permute-shrink (count2 count) (x x)) (:instance index-permute-stretch-of-index-permute-shrink (count2 count2) (x y))) :in-theory (disable index-permute-stretch-of-index-permute-shrink index-permute-shrink)))) (defretd index-permute-shrink-redef (implies (<= (nfix n) (nfix numvars)) (equal perm-index (cond ((< (nfix x) (logcount (loghead n (nfix mask)))) (nfix x)) ((< (nfix x) (nfix n)) (+ (nfix x) (- (logcount (loghead numvars (nfix mask))) (logcount (loghead n (nfix mask)))))) ((and (< (nfix x) (nfix numvars)) (logbitp x (nfix mask))) (logcount (loghead x (nfix mask)))) (t (+ (nfix x) (- (logcount (loghead x (loghead numvars (nfix mask))))) (logcount (loghead numvars (nfix mask)))))))) :hints (("goal" :induct <call> :in-theory (enable* arith-equiv-forwarding index-move-down-redef) :expand ((:free (count) <call>))))) (local (defthm logcount-loghead-lognot (equal (logcount (loghead n (lognot x))) (- (nfix n) (logcount (loghead n x)))) :hints (("Goal" :in-theory (enable* ihsext-inductions loghead** logcount**))))) (defthmd index-permute-shrink-redef-base (equal (index-permute-shrink 0 count mask x numvars) (b* ((x (nfix x)) (numvars (nfix numvars)) (mask (nfix mask))) (cond ((and (< x numvars) (logbitp x mask)) (logcount (loghead x mask))) ((<= numvars x) x) (t (+ (logcount (loghead x (lognot mask))) (logcount (loghead numvars mask))))))) :hints (("Goal" :in-theory (enable index-permute-shrink-redef)))))
other
(define nth-set-bit-pos ((n natp) (x integerp)) :returns (pos (or (natp pos) (not pos)) :rule-classes ((:type-prescription :typed-term pos))) :measure (+ (integer-length x) (nfix n)) :hints (("Goal" :in-theory (enable integer-length**))) (if (zip x) nil (b* ((bit (logcar x)) ((when (and (zp n) (eql bit 1))) 0) (rest (nth-set-bit-pos (- (lnfix n) bit) (logcdr x)))) (and rest (+ 1 rest)))) /// (defthm nth-set-bit-pos-of-negp (implies (negp x) (nth-set-bit-pos k x)) :hints (("Goal" :in-theory (enable nth-set-bit-pos))) :rule-classes (:rewrite :type-prescription)) (defthm nth-set-bit-pos-exists-when-logcount (implies (< (nfix n) (logcount x)) (nth-set-bit-pos n x)) :hints (("Goal" :in-theory (enable logcount**) :induct (nth-set-bit-pos n x)))) (defthm nth-set-bit-pos-types (and (iff (acl2-numberp (nth-set-bit-pos n x)) (nth-set-bit-pos n x)) (iff (rationalp (nth-set-bit-pos n x)) (nth-set-bit-pos n x)) (iff (integerp (nth-set-bit-pos n x)) (nth-set-bit-pos n x)) (iff (natp (nth-set-bit-pos n x)) (nth-set-bit-pos n x)))) (defthm logcount-of-nth-set-bit-pos (implies (nth-set-bit-pos k x) (equal (logcount (loghead (nth-set-bit-pos k x) x)) (nfix k))) :hints (("Goal" :induct (nth-set-bit-pos k x) :expand ((:with nth-set-bit-pos (nth-set-bit-pos k x))) :in-theory (e/d* ((:i nth-set-bit-pos) loghead** logcount** arith-equiv-forwarding))))) (local (defthm logcount-of-loghead-lte-full-logcount (implies (natp x) (<= (logcount (loghead n x)) (logcount x))) :hints (("Goal" :in-theory (enable* ihsext-inductions logcount** loghead**))) :rule-classes :linear)) (defthm logbitp-of-nth-set-bit-pos (implies (nth-set-bit-pos n x) (logbitp (nth-set-bit-pos n x) x)) :hints (("Goal" :in-theory (enable (:i nth-set-bit-pos) logbitp**) :expand ((:with nth-set-bit-pos (nth-set-bit-pos n x)))))) (defthm logbitp-of-nth-set-bit-pos-lognot (implies (nth-set-bit-pos n (lognot x)) (not (logbitp (nth-set-bit-pos n (lognot x)) x))) :hints (("Goal" :use ((:instance logbitp-of-nth-set-bit-pos (x (lognot x)))) :in-theory (disable logbitp-of-nth-set-bit-pos)))) (local (defun nth-set-bit-pos-bound-by-logcount-ind (k n x) (if (zp n) (list k x) (nth-set-bit-pos-bound-by-logcount-ind (- (nfix k) (logcar x)) (1- n) (logcdr x))))) (local (defthm nth-set-bit-pos-bound-by-logcount (implies (and (< (nfix k) (logcount (loghead (double-rewrite n) x))) (natp n)) (< (nth-set-bit-pos k x) n)) :hints (("goal" :induct (nth-set-bit-pos-bound-by-logcount-ind k n x) :in-theory (enable loghead** logcount**) :expand ((nth-set-bit-pos k x)))))) (deffixequiv nth-set-bit-pos) (local (defthm logcount-loghead-of-lognot (equal (logcount (loghead n (lognot x))) (- (nfix n) (logcount (loghead n x)))) :hints (("Goal" :induct (loghead n x) :in-theory (enable* ihsext-inductions) :expand ((loghead n (lognot x)) (loghead n x) (:free (a b) (logcount (logcons a b)))))))) (local (defun index-permute-stretch-alt (x mask numvars) (b* ((x (nfix x)) (mask (nfix mask)) (numvars (nfix numvars))) (cond ((< x (logcount (loghead numvars mask))) (nth-set-bit-pos x mask)) ((< x numvars) (nth-set-bit-pos (- x (logcount (loghead numvars mask))) (lognot mask))) (t x))))) (local (defthm natp-of-index-permute-stretch-alt (natp (index-permute-stretch-alt x mask numvars)) :rule-classes :type-prescription)) (local (defthm index-permute-shrink-of-stretch-alt-def (b* ((stretch (index-permute-stretch-alt x mask numvars))) (equal (index-permute-shrink 0 count mask stretch numvars) (nfix x))) :hints (("Goal" :in-theory (e/d (index-permute-shrink-redef-base) (logcount-of-nth-set-bit-pos)) :do-not-induct t) (use-termhint (b* ((x (nfix x)) (mask (nfix mask)) (numvars (nfix numvars)) ((when (< x (logcount (loghead numvars mask)))) `'(:use ((:instance logcount-of-nth-set-bit-pos (x ,(TRUTH::HQ TRUTH::MASK)) (k ,(TRUTH::HQ TRUTH::X)))))) ((when (< x numvars)) `'(:use ((:instance logcount-of-nth-set-bit-pos (x ,(TRUTH::HQ (LOGNOT TRUTH::MASK))) (k ,(TRUTH::HQ (- TRUTH::X (LOGCOUNT (TRUTH::LOGHEAD TRUTH::NUMVARS TRUTH::MASK)))))))))) nil))) :otf-flg t :rule-classes nil)) (local (defthm index-permute-stretch-alt-def1 (equal (index-permute-stretch 0 count mask x numvars) (index-permute-stretch-alt x mask numvars)) :hints (("goal" :in-theory (disable index-permute-stretch-of-index-permute-shrink index-permute-stretch-alt index-permute-shrink-redef-base)) (use-termhint (b* ((?spec (index-permute-stretch 0 count mask x numvars)) (impl (index-permute-stretch-alt x mask numvars)) (shrink-impl (index-permute-shrink 0 count mask impl numvars)) ((unless (equal shrink-impl (nfix x))) `'(:use ((:instance index-permute-shrink-of-stretch-alt-def)))) (stretch-shrink (index-permute-stretch 0 count mask shrink-impl numvars)) ((unless (equal stretch-shrink impl)) `'(:use ((:instance index-permute-stretch-of-index-permute-shrink (n 0) (x ,(TRUTH::HQ TRUTH::IMPL))))))) nil))))) (defthmd index-permute-stretch-redef (equal (index-permute-stretch 0 count mask x numvars) (b* ((x (nfix x)) (mask (nfix mask)) (numvars (nfix numvars))) (cond ((< x (logcount (loghead numvars mask))) (nth-set-bit-pos x mask)) ((< x numvars) (nth-set-bit-pos (- x (logcount (loghead numvars mask))) (lognot mask))) (t x)))) :hints (("Goal" :in-theory (enable index-permute-stretch-alt)))))
other
(define env-move-var-up ((m natp) (n natp) (env natp)) :guard (<= m n) :measure (nfix (- (nfix n) (nfix m))) :returns (perm-env natp :rule-classes :type-prescription) (b* (((when (mbe :logic (zp (- (nfix n) (nfix m))) :exec (eql n m))) (lnfix env)) (next (1+ (lnfix m))) (env (env-update next (env-lookup m env) (env-update m (env-lookup next env) env)))) (env-move-var-up next n env)) /// (defret lookup-in-env-move-var-up (equal (env-lookup k perm-env) (env-lookup (index-move-down m n k) env)) :hints (("Goal" :in-theory (enable index-move-down)))))
other
(define env-move-var-down ((m natp) (n natp) (env natp)) :guard (<= m n) :measure (nfix (- (nfix n) (nfix m))) :returns (perm-env natp :rule-classes :type-prescription) (b* (((when (mbe :logic (zp (- (nfix n) (nfix m))) :exec (eql n m))) (lnfix env)) (next (1+ (lnfix m))) (env (env-move-var-down next n env))) (env-update next (env-lookup m env) (env-update m (env-lookup next env) env))) /// (defret lookup-in-env-move-var-down (equal (env-lookup k perm-env) (env-lookup (index-move-up m n k) env)) :hints (("Goal" :in-theory (enable index-move-up index-swap)))) (defthm env-move-var-down-of-env-move-var-up (implies (<= (nfix m) (nfix n)) (equal (env-move-var-down m n (env-move-var-up m n env)) (nfix env))) :hints (("goal" :induct (env-move-var-up m n env) :in-theory (enable (:i env-move-var-up)) :expand ((env-move-var-up m n env) (:free (env) (env-move-var-up m n env)))))) (defthm env-move-var-up-of-env-move-var-down (implies (<= (nfix m) (nfix n)) (equal (env-move-var-up m n (env-move-var-down m n env)) (nfix env))) :hints (("goal" :induct (env-move-var-down m n env) :expand ((env-move-var-down m n env) (:free (env) (env-move-var-up m n env)))))))
other
(define permute-var-up ((m natp) (n natp) (truth integerp) (numvars natp)) :guard (and (<= m n) (< n numvars)) :measure (nfix (- (nfix n) (nfix m))) :returns (perm-truth natp :rule-classes :type-prescription) (b* (((when (mbe :logic (zp (- (nfix n) (nfix m))) :exec (eql n m))) (truth-norm truth numvars)) (next (1+ (lnfix m))) (truth (swap-vars next m truth numvars))) (permute-var-up next n truth numvars)) /// (defret eval-of-permute-var-up-with-env-move-var-up (implies (and (<= (nfix m) (nfix n)) (< (nfix n) (nfix numvars))) (equal (truth-eval perm-truth (env-move-var-up m n env) numvars) (truth-eval truth env numvars))) :hints (("Goal" :in-theory (enable env-move-var-up env-swap-vars)))) (defret eval-of-permute-var-up (implies (and (<= (nfix m) (nfix n)) (< (nfix n) (nfix numvars))) (equal (truth-eval perm-truth env numvars) (truth-eval truth (env-move-var-down m n env) numvars))) :hints (("Goal" :in-theory (e/d nil (permute-var-up eval-of-permute-var-up-with-env-move-var-up)) :use ((:instance eval-of-permute-var-up-with-env-move-var-up (env (env-move-var-down m n env))))))) (defret size-of-permute-var-up (implies (and (< (nfix n) (nfix numvars)) (natp size) (<= (ash 1 numvars) size)) (unsigned-byte-p size perm-truth)) :hints (("Goal" :in-theory (enable truth-norm)))) (defthm permute-var-up-of-truth-norm (equal (permute-var-up m n (truth-norm truth numvars) numvars) (permute-var-up m n truth numvars))))
other
(define permute-var-down ((m natp) (n natp) (truth integerp) (numvars natp)) :guard (and (<= m n) (< n numvars)) :measure (nfix (- (nfix n) (nfix m))) :returns (perm-truth natp :rule-classes :type-prescription) (b* (((when (mbe :logic (zp (- (nfix n) (nfix m))) :exec (eql n m))) (truth-norm truth numvars)) (next (1+ (lnfix m))) (truth (permute-var-down next n truth numvars))) (swap-vars next m truth numvars)) /// (defret eval-of-permute-var-down-with-env-move-var-down (implies (and (<= (nfix m) (nfix n)) (< (nfix n) (nfix numvars))) (equal (truth-eval perm-truth (env-move-var-down m n env) numvars) (truth-eval truth env numvars))) :hints (("Goal" :in-theory (enable env-move-var-down env-swap-vars)))) (defret eval-of-permute-var-down (implies (and (<= (nfix m) (nfix n)) (< (nfix n) (nfix numvars))) (equal (truth-eval perm-truth env numvars) (truth-eval truth (env-move-var-up m n env) numvars))) :hints (("Goal" :in-theory (e/d nil (permute-var-down eval-of-permute-var-down-with-env-move-var-down)) :use ((:instance eval-of-permute-var-down-with-env-move-var-down (env (env-move-var-up m n env))))))) (defret size-of-permute-var-down (implies (and (< (nfix n) (nfix numvars)) (natp size) (<= (ash 1 numvars) size)) (unsigned-byte-p size perm-truth)) :hints (("Goal" :in-theory (enable truth-norm)))) (defthm permute-var-down-of-truth-norm (equal (permute-var-down m n (truth-norm truth numvars) numvars) (permute-var-down m n truth numvars))))
other
(define env-diff-index ((env1 natp) (env2 natp)) :returns (idx natp :rule-classes :type-prescription) :prepwork ((defchoose env-diff-index1 (idx) (env1 env2) (not (equal (env-lookup idx env1) (env-lookup idx env2))))) (b* ((idx (nfix (env-diff-index1 (lnfix env1) (lnfix env2))))) (if (equal (env-lookup idx env1) (env-lookup idx env2)) 0 idx)) /// (local (include-book "centaur/bitops/logbitp-mismatch" :dir :system)) (defthm env-diff-index-correct (implies (not (equal (nfix env1) (nfix env2))) (b* ((idx (env-diff-index env1 env2))) (equal (env-lookup idx env1) (not (env-lookup idx env2))))) :hints (("Goal" :in-theory (enable env-lookup) :use ((:instance env-diff-index1 (idx (logbitp-mismatch (nfix env1) (nfix env2))) (env1 (nfix env1)) (env2 (nfix env2))))))))
other
(define env-permute-stretch ((n natp) (count) (mask natp) (env natp) (numvars natp)) :measure (nfix (- (nfix numvars) (nfix n))) :guard (and (<= n numvars) (eql count (logcount (loghead n mask)))) :returns (perm-env natp :rule-classes :type-prescription) (b* (((when (mbe :logic (zp (- (nfix numvars) (nfix n))) :exec (eql n numvars))) (lnfix env)) (n (lnfix n)) (count (mbe :logic (logcount (loghead n (lnfix mask))) :exec count)) (bit (logbit n (lnfix mask))) (env (env-permute-stretch (1+ n) (+ bit count) mask env numvars))) (if (eql bit 1) (env-move-var-up count n env) env)) /// (defret normalize-count-of-env-permute-stretch (implies (syntaxp (not (equal count ''nil))) (equal <call> (let ((count nil)) <call>)))) (defret lookup-in-env-permute-stretch (equal (env-lookup k perm-env) (env-lookup (index-permute-shrink n nil mask k numvars) env)) :hints (("Goal" :in-theory (enable index-permute-shrink)))) (local (defthm equals-of-index-permute-shrink (iff (equal (index-permute-shrink n count mask x numvars) y) (and (natp y) (equal (nfix x) (index-permute-stretch n nil mask y numvars)))) :hints (("goal" :in-theory (e/d* (arith-equiv-forwarding) (index-permute-shrink-of-index-permute-stretch)) :use ((:instance index-permute-shrink-of-index-permute-stretch (x y))))) :otf-flg t)) (defret env-permute-stretch-of-env-update (equal (env-permute-stretch n count mask (env-update k val env) numvars) (env-update (index-permute-stretch n nil mask k numvars) val (env-permute-stretch n count mask env numvars))) :hints (("goal" :use ((:instance env-diff-index-correct (env1 (env-permute-stretch n count mask (env-update k val env) numvars)) (env2 (env-update (index-permute-stretch n nil mask k numvars) val (env-permute-stretch n count mask env numvars))))) :in-theory (disable env-diff-index-correct env-permute-stretch)))))
other
(define env-permute-shrink ((n natp) (count) (mask natp) (env natp) (numvars natp)) :measure (nfix (- (nfix numvars) (nfix n))) :guard (and (<= n numvars) (eql count (logcount (loghead n mask)))) :returns (perm-env natp :rule-classes :type-prescription) (b* (((when (mbe :logic (zp (- (nfix numvars) (nfix n))) :exec (eql n numvars))) (lnfix env)) (n (lnfix n)) (count (mbe :logic (logcount (loghead n (lnfix mask))) :exec count)) (bit (logbit n (lnfix mask))) (env (if (eql bit 1) (env-move-var-down count n env) env))) (env-permute-shrink (1+ n) (+ bit count) mask env numvars)) /// (defret normalize-count-of-env-permute-shrink (implies (syntaxp (not (equal count ''nil))) (equal <call> (let ((count nil)) <call>)))) (defthm env-permute-shrink-of-env-permute-stretch (equal (env-permute-shrink n count1 mask (env-permute-stretch n count mask env numvars) numvars) (nfix env)) :hints (("Goal" :in-theory (enable (:i env-permute-stretch)) :induct (env-permute-stretch n count mask env numvars) :expand ((:free (count) (env-permute-stretch n count mask env numvars)) (:free (count env) (env-permute-shrink n count mask env numvars)))))) (defthm env-permute-stretch-of-env-permute-shrink (equal (env-permute-stretch n count1 mask (env-permute-shrink n count mask env numvars) numvars) (nfix env)) :hints (("Goal" :induct (env-permute-shrink n count mask env numvars) :expand ((:free (count env) (env-permute-stretch n count mask env numvars)) (:free (count) (env-permute-shrink n count mask env numvars)))))) (defret lookup-in-env-permute-shrink (equal (env-lookup k perm-env) (env-lookup (index-permute-stretch n nil mask k numvars) env)) :hints (("Goal" :in-theory (enable index-permute-stretch)))) (local (defthm equals-of-index-permute-shrink (iff (equal (index-permute-shrink n count mask x numvars) y) (and (natp y) (equal (nfix x) (index-permute-stretch n nil mask y numvars)))) :hints (("goal" :in-theory (e/d* (arith-equiv-forwarding) (index-permute-shrink-of-index-permute-stretch)) :use ((:instance index-permute-shrink-of-index-permute-stretch (x y))))) :otf-flg t)) (defret env-permute-shrink-of-env-update (equal (env-permute-shrink n count mask (env-update k val env) numvars) (env-update (index-permute-shrink n nil mask k numvars) val (env-permute-shrink n count mask env numvars))) :hints (("goal" :use ((:instance env-diff-index-correct (env1 (env-permute-shrink n count mask (env-update k val env) numvars)) (env2 (env-update (index-permute-shrink n nil mask k numvars) val (env-permute-shrink n count mask env numvars))))) :in-theory (disable env-diff-index-correct env-permute-shrink)))))
other
(define permute-stretch ((n natp) (count) (mask natp) (truth integerp) (numvars natp)) :measure (nfix (- (nfix numvars) (nfix n))) :guard (and (<= n numvars) (eql count (logcount (loghead n mask)))) :returns (perm-truth natp :rule-classes :type-prescription) (b* (((when (mbe :logic (zp (- (nfix numvars) (nfix n))) :exec (eql n numvars))) (truth-norm truth numvars)) (n (lnfix n)) (count (mbe :logic (logcount (loghead n (lnfix mask))) :exec count)) (bit (logbit n (lnfix mask))) (truth (permute-stretch (1+ n) (+ bit count) mask truth numvars))) (if (eql bit 1) (permute-var-up count n truth numvars) truth)) /// (defret normalize-count-of-permute-stretch (implies (syntaxp (not (equal count ''nil))) (equal <call> (let ((count nil)) <call>)))) (defret eval-of-permute-stretch-with-env-permute-stretch (implies (<= (nfix n) (nfix numvars)) (equal (truth-eval perm-truth (env-permute-stretch n count mask env numvars) numvars) (truth-eval truth env numvars))) :hints (("Goal" :in-theory (enable env-permute-stretch) :induct <call> :expand ((:free (count) <call>) (:free (count) (env-permute-stretch n count mask env numvars)))))) (defret eval-of-permute-stretch (implies (<= (nfix n) (nfix numvars)) (equal (truth-eval perm-truth env numvars) (truth-eval truth (env-permute-shrink n count mask env numvars) numvars))) :hints (("Goal" :use ((:instance eval-of-permute-stretch-with-env-permute-stretch (env (env-permute-shrink n count mask env numvars)))) :in-theory (disable eval-of-permute-stretch-with-env-permute-stretch)))) (defret size-of-permute-stretch (implies (and (natp size) (<= (ash 1 (nfix numvars)) size)) (unsigned-byte-p size perm-truth)) :hints (("Goal" :in-theory (enable truth-norm)))) (defthm depends-on-of-permute-stretch (implies (and (natp numvars) (< (nfix n) numvars) (not (depends-on (index-permute-shrink 0 nil mask n numvars) truth numvars))) (not (depends-on n (permute-stretch 0 count mask truth numvars) numvars))) :hints ((use-termhint (b* ((perm (permute-stretch 0 count mask truth numvars)) (env (depends-on-witness n perm numvars)) (env1 (env-update n t env)) (?shr-env (env-permute-shrink 0 nil mask env numvars)) (?shr-env1 (env-permute-shrink 0 nil mask env1 numvars))) `'(:use ((:instance depends-on-witness-correct (truth ,(TRUTH::HQ TRUTH::PERM)))) :in-theory (disable depends-on-witness-correct)))))) (defthm permute-stretch-of-truth-norm (equal (permute-stretch n count mask (truth-norm truth numvars) numvars) (permute-stretch n count mask truth numvars))))
other
(define permute-shrink ((n natp) (count) (mask natp) (truth integerp) (numvars natp)) :measure (nfix (- (nfix numvars) (nfix n))) :guard (and (<= n numvars) (eql count (logcount (loghead n mask)))) :returns (perm-truth natp :rule-classes :type-prescription) (b* (((when (mbe :logic (zp (- (nfix numvars) (nfix n))) :exec (eql n numvars))) (truth-norm truth numvars)) (n (lnfix n)) (count (mbe :logic (logcount (loghead n (lnfix mask))) :exec count)) (bit (logbit n (lnfix mask))) (truth (if (eql bit 1) (permute-var-down count n truth numvars) truth))) (permute-shrink (1+ n) (+ bit count) mask truth numvars)) /// (defret normalize-count-of-permute-shrink (implies (syntaxp (not (equal count ''nil))) (equal <call> (let ((count nil)) <call>)))) (local (defun eval-of-permute-shrink-ind (n mask env truth numvars) (declare (xargs :measure (nfix (- (nfix numvars) (nfix n))))) (b* (((when (mbe :logic (zp (- (nfix numvars) (nfix n))) :exec (eql n numvars))) (list truth numvars env)) (n (lnfix n)) (count (logcount (loghead n (lnfix mask)))) (bit (logbit n (lnfix mask))) (truth (if (eql bit 1) (permute-var-down count n truth numvars) truth)) (env (if (eql bit 1) (env-move-var-down count n env) env))) (eval-of-permute-shrink-ind (1+ n) mask env truth numvars)))) (defret eval-of-permute-shrink-with-env-permute-shrink (implies (<= (nfix n) (nfix numvars)) (equal (truth-eval perm-truth (env-permute-shrink n count mask env numvars) numvars) (truth-eval truth env numvars))) :hints (("Goal" :in-theory (enable env-permute-shrink) :induct (eval-of-permute-shrink-ind n mask env truth numvars) :expand ((:free (count) <call>) (:free (count) (env-permute-shrink n count mask env numvars)))))) (defret eval-of-permute-shrink (implies (<= (nfix n) (nfix numvars)) (equal (truth-eval perm-truth env numvars) (truth-eval truth (env-permute-stretch n count mask env numvars) numvars))) :hints (("Goal" :use ((:instance eval-of-permute-shrink-with-env-permute-shrink (env (env-permute-stretch n count mask env numvars)))) :in-theory (disable eval-of-permute-shrink-with-env-permute-shrink)))) (defret size-of-permute-shrink (implies (and (natp size) (<= (ash 1 (nfix numvars)) size)) (unsigned-byte-p size perm-truth)) :hints (("Goal" :in-theory (enable truth-norm)))) (defthm depends-on-of-permute-shrink (implies (and (natp numvars) (< (nfix n) numvars) (not (depends-on (index-permute-stretch 0 nil mask n numvars) truth numvars))) (not (depends-on n (permute-shrink 0 count mask truth numvars) numvars))) :hints ((use-termhint (b* ((perm (permute-shrink 0 count mask truth numvars)) (env (depends-on-witness n perm numvars)) (env1 (env-update n t env)) (?shr-env (env-permute-stretch 0 nil mask env numvars)) (?shr-env1 (env-permute-stretch 0 nil mask env1 numvars))) `'(:use ((:instance depends-on-witness-correct (truth ,(TRUTH::HQ TRUTH::PERM)))) :in-theory (disable depends-on-witness-correct)))))) (defthm permute-shrink-of-truth-norm (equal (permute-shrink n count mask (truth-norm truth numvars) numvars) (permute-shrink n count mask truth numvars))))
other
(define index-listp (x (numvars natp)) (if (atom x) (eq x nil) (and (natp (car x)) (< (car x) (lnfix numvars)) (index-listp (cdr x) numvars))) /// (defthmd natp-nth-of-index-listp (implies (and (index-listp x numvars) (< (nfix n) (len x))) (natp (nth n x)))) (defthmd nfix-nth-in-index-list-bound (implies (and (index-listp x numvars) (posp numvars)) (< (nfix (nth n x)) numvars)) :rule-classes (:rewrite :linear)) (defthmd nth-in-index-list-bound (implies (and (index-listp x numvars) (natp numvars) (natp (nth n x))) (< (nth n x) numvars)) :rule-classes (:rewrite :linear)) (defthmd nat-listp-when-index-listp (implies (index-listp x numvars) (nat-listp x))) (defthm true-listp-when-index-listp (implies (index-listp x numvars) (true-listp x)) :rule-classes :forward-chaining))
other
(local (in-theory (enable nfix-nth-in-index-list-bound nth-in-index-list-bound nat-listp-when-index-listp natp-nth-of-index-listp)))
other
(define index-perm ((n natp "current position in the list") (perm nat-listp "indices to permute") (x natp "index to permute") (numvars natp)) :guard (and (<= n numvars) (eql (len perm) numvars)) :returns (perm-idx natp :rule-classes :type-prescription) :measure (nfix (- (nfix numvars) (nfix n))) (b* (((when (mbe :logic (zp (- (nfix numvars) (nfix n))) :exec (eql n numvars))) (lnfix x)) (x (index-swap n (nth n perm) x))) (index-perm (1+ (lnfix n)) perm x numvars)) /// (defret bound-of-index-perm (implies (and (< (nfix x) (nfix numvars)) (index-listp perm numvars)) (< perm-idx (nfix numvars))) :hints (("Goal" :in-theory (enable* index-swap arith-equiv-forwarding))) :rule-classes :linear) (defthm index-perm-unique (iff (equal (index-perm n perm x numvars) (index-perm n perm y numvars)) (equal (nfix x) (nfix y)))))
other
(define index-perm-rev ((n natp "current position in the list") (perm nat-listp "indices to permute") (x natp "index to permute") (numvars natp)) :guard (and (<= n numvars) (eql (len perm) numvars)) :returns (perm-idx natp :rule-classes :type-prescription) :measure (nfix (- (nfix numvars) (nfix n))) (b* (((when (mbe :logic (zp (- (nfix numvars) (nfix n))) :exec (eql n numvars))) (lnfix x)) (x (index-perm-rev (1+ (lnfix n)) perm x numvars))) (index-swap n (nth n perm) x)) /// (defthm index-perm-of-index-perm-rev (equal (index-perm n perm (index-perm-rev n perm x numvars) numvars) (nfix x)) :hints (("Goal" :in-theory (enable index-perm)))) (defthm index-perm-rev-of-index-perm (equal (index-perm-rev n perm (index-perm n perm x numvars) numvars) (nfix x)) :hints (("Goal" :in-theory (enable index-perm)))) (defret bound-of-index-perm-rev (implies (and (< (nfix x) (nfix numvars)) (index-listp perm numvars)) (< perm-idx (nfix numvars))) :hints (("Goal" :in-theory (enable* index-swap arith-equiv-forwarding))) :rule-classes :linear) (defthm index-perm-rev-unique (iff (equal (index-perm-rev n perm x numvars) (index-perm-rev n perm y numvars)) (equal (nfix x) (nfix y)))))
other
(define env-perm ((n natp "current position in the list") (perm nat-listp "indices to permute") (x natp "env to permute") (numvars natp)) :guard (and (<= n numvars) (eql (len perm) numvars)) :returns (perm-env natp :rule-classes :type-prescription) :measure (nfix (- (nfix numvars) (nfix n))) (b* (((when (mbe :logic (zp (- (nfix numvars) (nfix n))) :exec (eql n numvars))) (lnfix x)) (x (env-swap-vars n (nth n perm) x))) (env-perm (1+ (lnfix n)) perm x numvars)) /// (defthm lookup-index-perm-in-env-perm (equal (env-lookup (index-perm n perm k numvars) (env-perm n perm env numvars)) (env-lookup k env)) :hints (("Goal" :in-theory (enable index-perm)))) (defthm lookup-in-env-perm (equal (env-lookup k (env-perm n perm env numvars)) (env-lookup (index-perm-rev n perm k numvars) env)) :hints (("Goal" :in-theory (enable index-perm-rev)))))
other
(define env-perm-rev ((n natp "current position in the list") (perm nat-listp "indices to permute") (x natp "env to permute") (numvars natp)) :guard (and (<= n numvars) (eql (len perm) numvars)) :returns (perm-env natp :rule-classes :type-prescription) :measure (nfix (- (nfix numvars) (nfix n))) (b* (((when (mbe :logic (zp (- (nfix numvars) (nfix n))) :exec (eql n numvars))) (lnfix x)) (x (env-perm-rev (1+ (lnfix n)) perm x numvars))) (env-swap-vars n (nth n perm) x)) /// (defthm lookup-index-perm-rev-in-env-perm-rev (equal (env-lookup (index-perm-rev n perm k numvars) (env-perm-rev n perm env numvars)) (env-lookup k env)) :hints (("Goal" :in-theory (enable index-perm-rev)))) (defthm lookup-in-env-perm-rev (equal (env-lookup k (env-perm-rev n perm env numvars)) (env-lookup (index-perm n perm k numvars) env)) :hints (("Goal" :in-theory (enable index-perm)))) (defthm env-perm-of-env-perm-rev (equal (env-perm n perm (env-perm-rev n perm x numvars) numvars) (nfix x)) :hints (("Goal" :in-theory (enable env-perm)))) (defthm env-perm-rev-of-env-perm (equal (env-perm-rev n perm (env-perm n perm x numvars) numvars) (nfix x)) :hints (("Goal" :in-theory (enable env-perm)))))
other
(define truth-perm ((n natp "current position in the list") (perm (index-listp perm numvars) "indices to permute") (truth integerp "truth table to permute") (numvars natp)) :guard (and (<= n numvars) (eql (len perm) numvars)) :returns (perm-truth integerp :rule-classes :type-prescription) :measure (nfix (- (nfix numvars) (nfix n))) (b* (((when (mbe :logic (zp (- (nfix numvars) (nfix n))) :exec (eql n numvars))) (truth-norm truth numvars)) (truth (swap-vars n (nth n perm) truth numvars))) (truth-perm (1+ (lnfix n)) perm truth numvars)) /// (defthm eval-of-truth-perm-with-env-perm (implies (index-listp perm numvars) (equal (truth-eval (truth-perm n perm truth numvars) (env-perm n perm env numvars) numvars) (truth-eval truth env numvars))) :hints (("Goal" :in-theory (enable env-perm)))) (defthm eval-of-truth-perm (implies (index-listp perm numvars) (equal (truth-eval (truth-perm n perm truth numvars) env numvars) (truth-eval truth (env-perm-rev n perm env numvars) numvars))) :hints (("Goal" :in-theory (enable env-perm-rev)))) (defret size-of-truth-perm-basic (unsigned-byte-p (ash 1 (nfix numvars)) perm-truth)) (defret size-of-truth-perm (implies (and (natp size) (<= (ash 1 (nfix numvars)) size)) (unsigned-byte-p size perm-truth)) :hints (("goal" :use size-of-truth-perm-basic :in-theory (disable size-of-truth-perm-basic) :do-not-induct t))))
other
(define truth-perm-rev ((n natp "current position in the list") (perm (index-listp perm numvars) "indices to permute") (truth integerp "truth table to permute") (numvars natp)) :guard (and (<= n numvars) (eql (len perm) numvars)) :returns (perm-truth integerp :rule-classes :type-prescription) :measure (nfix (- (nfix numvars) (nfix n))) (b* (((when (mbe :logic (zp (- (nfix numvars) (nfix n))) :exec (eql n numvars))) (truth-norm truth numvars)) (truth (truth-perm-rev (1+ (lnfix n)) perm truth numvars))) (swap-vars n (nth n perm) truth numvars)) /// (defthm eval-of-truth-perm-rev-with-env-perm-rev (implies (index-listp perm numvars) (equal (truth-eval (truth-perm-rev n perm truth numvars) (env-perm-rev n perm env numvars) numvars) (truth-eval truth env numvars))) :hints (("Goal" :in-theory (enable env-perm-rev)))) (defthm eval-of-truth-perm-rev (implies (index-listp perm numvars) (equal (truth-eval (truth-perm-rev n perm truth numvars) env numvars) (truth-eval truth (env-perm n perm env numvars) numvars))) :hints (("Goal" :in-theory (enable env-perm)))) (defret size-of-truth-perm-rev-basic (implies (index-listp perm numvars) (unsigned-byte-p (ash 1 (nfix numvars)) perm-truth))) (defret size-of-truth-perm-rev (implies (and (natp size) (<= (ash 1 (nfix numvars)) size) (index-listp perm numvars)) (unsigned-byte-p size perm-truth)) :hints (("goal" :use size-of-truth-perm-rev-basic :in-theory (disable size-of-truth-perm-rev-basic) :do-not-induct t))))
other
(define env-swap-polarity ((n natp) (env natp)) :returns (new-env natp :rule-classes :type-prescription) (env-update n (not (env-lookup n env)) env) /// (defret lookup-in-env-swap-polarity-same (equal (env-lookup n new-env) (not (env-lookup n env)))) (defret lookup-in-env-swap-polarity-diff (implies (not (nat-equiv n m)) (equal (env-lookup m new-env) (env-lookup m env)))) (defret lookup-in-env-swap-polarity-split (equal (env-lookup m new-env) (if (nat-equiv n m) (not (env-lookup n env)) (env-lookup m env)))) (defret env-swap-polarity-reverse (equal (env-swap-polarity n new-env) (nfix env))) (local (in-theory (enable* logbitp-of-install-bit-split arith-equiv-forwarding))) (defret env-swap-polarity-commute (equal (env-swap-polarity n (env-swap-polarity m env)) (env-swap-polarity m (env-swap-polarity n env))) :hints (("Goal" :in-theory (enable env-update env-lookup) :cases ((equal (nfix n) (nfix m)))) (logbitp-reasoning)) :rule-classes ((:rewrite :loop-stopper ((n m))))))
other
(define swap-polarity ((n natp) (truth integerp) (numvars natp)) :guard (< n numvars) :returns (new-truth integerp :rule-classes :type-prescription) (b* ((truth (truth-norm truth numvars)) (var (var n numvars)) (shift (ash 1 (lnfix n)))) (logior (ash (logand var truth) (- shift)) (ash (logand (lognot var) (loghead (ash 1 (lnfix numvars)) truth)) shift))) /// (local (defthm minus-ash-1-is-install-bit-rev (implies (and (logbitp (double-rewrite n) x) (integerp x) (natp n)) (equal (+ (- (ash 1 n)) x) (install-bit n 0 x))) :hints (("Goal" :in-theory (enable minus-ash-1-is-install-bit))))) (local (defthm plus-ash-1-is-install-bit-rev (implies (and (not (logbitp (double-rewrite n) x)) (integerp x) (natp n)) (equal (+ (ash 1 n) x) (install-bit n 1 x))) :hints (("Goal" :in-theory (enable plus-ash-1-is-install-bit))))) (local (in-theory (enable loghead-less-than-ash))) (local (defthm lower-bound-by-logbitp (implies (and (logbitp n x) (natp x)) (<= (ash 1 (nfix n)) x)) :hints (("goal" :induct (logbitp n x) :in-theory (enable* ihsext-inductions ihsext-recursive-redefs))))) (local (defthm install-bit-bound (implies (and (< x (ash 1 size)) (natp x) (natp size) (< (nfix n) size)) (< (install-bit n v x) (ash 1 size))) :hints (("goal" :use ((:instance unsigned-byte-p-of-install-bit (n size) (i n) (v v) (x x))) :in-theory (e/d (unsigned-byte-p expt-2-is-ash) (unsigned-byte-p-of-install-bit)))))) (defret swap-polarity-correct (implies (< (nfix n) (nfix numvars)) (equal (truth-eval new-truth env numvars) (truth-eval truth (env-swap-polarity n env) numvars))) :hints ((and stable-under-simplificationp '(:in-theory (enable env-lookup env-swap-polarity env-update truth-eval logbitp-of-ash-split truth-norm))))) (defthmd size-of-logand-by-size-of-loghead-2 (implies (and (unsigned-byte-p m a) (unsigned-byte-p n (loghead m b))) (unsigned-byte-p n (logand b a))) :hints (("Goal" :in-theory (enable size-of-logand-by-size-of-loghead)))) (defthmd size-of-logand-with-loghead (implies (unsigned-byte-p n (loghead m b)) (unsigned-byte-p n (logand b (loghead m a)))) :hints (("goal" :use ((:instance size-of-logand-by-size-of-loghead-2 (a (loghead m a)) (m (nfix m))))))) (defret swap-polarity-size-basic (implies (< (nfix n) (nfix numvars)) (unsigned-byte-p (ash 1 numvars) new-truth)) :hints (("Goal" :in-theory (enable size-of-logand-with-loghead ash-1-monotonic truth-norm) :do-not-induct t))) (defret swap-polarity-size (implies (and (natp size) (<= (ash 1 (nfix numvars)) size) (< (nfix n) (nfix numvars))) (unsigned-byte-p size new-truth)) :hints (("goal" :use swap-polarity-size-basic :in-theory (disable swap-polarity-size-basic)))) (defthm swap-polarity-of-truth-norm (equal (swap-polarity n (truth-norm truth numvars) numvars) (swap-polarity n truth numvars)) :hints (("Goal" :in-theory (enable truth-norm)))))
other
(define env-permute-polarity ((n natp) (mask integerp) (env natp) (numvars natp)) :guard (<= n numvars) :measure (nfix (- (nfix numvars) (nfix n))) :returns (new-env natp :rule-classes :type-prescription) (b* (((when (mbe :logic (zp (- (nfix numvars) (nfix n))) :exec (eql n numvars))) (lnfix env)) (env (if (logbitp n mask) (env-swap-polarity n env) env))) (env-permute-polarity (1+ (lnfix n)) mask env numvars)) /// (local (in-theory (enable* arith-equiv-forwarding))) (defret lookup-in-env-permute-polarity-split (equal (env-lookup m new-env) (if (and (<= (nfix n) (nfix m)) (< (nfix m) (nfix numvars))) (xor (env-lookup m env) (logbitp m mask)) (env-lookup m env)))) (defret lookup-in-env-permute-polarity-set (implies (and (logbitp m mask) (< (nfix m) (nfix numvars))) (equal (env-lookup m (env-permute-polarity 0 mask env numvars)) (not (env-lookup m env))))) (defret lookup-in-env-permute-polarity-unset (implies (and (not (logbitp m mask)) (< (nfix m) (nfix numvars))) (equal (env-lookup m (env-permute-polarity n mask env numvars)) (env-lookup m env)))) (defret env-permute-polarity-of-swap-polarity (equal (env-permute-polarity n mask (env-swap-polarity m env) numvars) (env-swap-polarity m (env-permute-polarity n mask env numvars)))) (local (defthm equal-of-env-swap-polarity (equal (equal (env-swap-polarity n x) (env-swap-polarity n y)) (nat-equiv x y)) :hints (("goal" :use ((:instance env-swap-polarity-reverse (env x)) (:instance env-swap-polarity-reverse (env y))) :in-theory (disable env-swap-polarity-reverse))))) (defret env-permute-polarity-reverse (equal (env-permute-polarity n mask new-env numvars) (nfix env)) :hints (("goal" :induct <call> :expand ((:free (env) <call>))))))
other
(define permute-polarity ((n natp) (mask integerp) (truth integerp) (numvars natp)) :guard (<= n numvars) :measure (nfix (- (nfix numvars) (nfix n))) :returns (new-truth integerp :rule-classes :type-prescription) (b* (((when (mbe :logic (zp (- (nfix numvars) (nfix n))) :exec (eql n numvars))) (truth-norm truth numvars)) (truth (if (logbitp n mask) (swap-polarity n truth numvars) truth))) (permute-polarity (1+ (lnfix n)) mask truth numvars)) /// (defret eval-of-permute-polarity-with-env-permute-polarity (equal (truth-eval new-truth (env-permute-polarity n mask env numvars) numvars) (truth-eval truth env numvars)) :hints (("Goal" :in-theory (enable env-permute-polarity)))) (defret eval-of-permute-polarity (equal (truth-eval new-truth env numvars) (truth-eval truth (env-permute-polarity n mask env numvars) numvars)) :hints (("goal" :use ((:instance eval-of-permute-polarity-with-env-permute-polarity (env (env-permute-polarity n mask env numvars)))) :in-theory (disable eval-of-permute-polarity-with-env-permute-polarity)))) (defret permute-polarity-size-basic (unsigned-byte-p (ash 1 (nfix numvars)) new-truth) :hints (("goal" :induct <call> :expand (<call>)))) (defret permute-polarity-size (implies (and (natp size) (<= (ash 1 (nfix numvars)) size)) (unsigned-byte-p size new-truth)) :hints (("goal" :use permute-polarity-size-basic :in-theory (disable permute-polarity-size-basic)))) (defret permute-polarity-identity (equal (permute-polarity n 0 truth numvars) (truth-norm truth numvars))) (defthm permute-polarity-of-truth-norm (equal (permute-polarity n mask (truth-norm truth numvars) numvars) (permute-polarity n mask truth numvars))))