(duplicity a x) counts how many times the element
This function is much nicer to reason about than ACL2's built-in count function because it is much more limited:
Reasoning about duplicity is useful when trying to show two lists are permutations of one another (sometimes called multiset- or bag-equivalence). A classic exercise for new ACL2 users is to prove that a permutation function is symmetric. Hint: a duplicity-based argument may compare quite favorably to induction on the definition of permutation.
This function can also be useful when trying to establish no-duplicatesp, e.g., see no-duplicatesp-equal-same-by-duplicity.
Function:
(defun duplicity-exec (a x n) (declare (xargs :guard (natp n))) (if (atom x) n (duplicity-exec a (cdr x) (if (equal (car x) a) (+ 1 n) n))))
Function:
(defun duplicity (a x) (declare (xargs :guard t)) (mbe :logic (cond ((atom x) 0) ((equal (car x) a) (+ 1 (duplicity a (cdr x)))) (t (duplicity a (cdr x)))) :exec (duplicity-exec a x 0)))
Theorem:
(defthm duplicity-exec-removal (implies (natp n) (equal (duplicity-exec a x n) (+ (duplicity a x) n))))
Theorem:
(defthm duplicity-when-not-consp (implies (not (consp x)) (equal (duplicity a x) 0)))
Theorem:
(defthm duplicity-of-cons (equal (duplicity a (cons b x)) (if (equal a b) (+ 1 (duplicity a x)) (duplicity a x))))
Theorem:
(defthm duplicity-of-list-fix (equal (duplicity a (list-fix x)) (duplicity a x)))
Theorem:
(defthm list-equiv-implies-equal-duplicity-2 (implies (list-equiv x x-equiv) (equal (duplicity a x) (duplicity a x-equiv))) :rule-classes (:congruence))
Theorem:
(defthm duplicity-of-append (equal (duplicity a (append x y)) (+ (duplicity a x) (duplicity a y))))
Theorem:
(defthm duplicity-of-rev (equal (duplicity a (rev x)) (duplicity a x)))
Theorem:
(defthm duplicity-of-revappend (equal (duplicity a (revappend x y)) (+ (duplicity a x) (duplicity a y))))
Theorem:
(defthm duplicity-of-reverse (equal (duplicity a (reverse x)) (duplicity a x)))
Theorem:
(defthm duplicity-when-non-member-equal (implies (not (member-equal a x)) (equal (duplicity a x) 0)))
Theorem:
(defthm duplicity-when-member-equal (implies (member-equal a x) (< 0 (duplicity a x))) :rule-classes ((:rewrite) (:linear)))
Theorem:
(defthm duplicity-zero-to-member-equal (iff (equal 0 (duplicity a x)) (not (member-equal a x))))
Theorem:
(defthm no-duplicatesp-equal-when-high-duplicity (implies (> (duplicity a x) 1) (not (no-duplicatesp-equal x))))
Theorem:
(defthm duplicity-of-flatten-of-rev (equal (duplicity a (flatten (rev x))) (duplicity a (flatten x))))