• Top
    • Documentation
    • Books
    • Boolean-reasoning
    • Projects
    • Debugging
    • Std
    • Proof-automation
    • Macro-libraries
    • ACL2
      • Theories
      • Rule-classes
      • Proof-builder
      • Recursion-and-induction
      • Hons-and-memoization
      • Events
      • Parallelism
      • History
      • Programming
        • Defun
        • Declare
        • System-utilities
        • Stobj
        • State
        • Mutual-recursion
        • Memoize
        • Mbe
        • Io
        • Defpkg
        • Apply$
        • Loop$
        • Programming-with-state
        • Arrays
        • Characters
        • Time$
        • Defmacro
        • Loop$-primer
        • Fast-alists
        • Defconst
        • Evaluation
        • Guard
        • Equality-variants
        • Compilation
        • Hons
        • ACL2-built-ins
        • Developers-guide
        • System-attachments
        • Advanced-features
        • Set-check-invariant-risk
        • Numbers
        • Efficiency
        • Irrelevant-formals
        • Introduction-to-programming-in-ACL2-for-those-who-know-lisp
        • Redefining-programs
        • Lists
          • Member
          • Append
          • List
          • Nth
          • Len
          • True-listp
          • String-listp
          • Nat-listp
          • Character-listp
          • Symbol-listp
          • True-list-listp
          • Length
          • Search
          • Intersection$
          • Union$
          • Remove-duplicates
          • Position
          • Update-nth
          • Take
          • Nthcdr
          • Set-difference$
          • Subsetp
          • No-duplicatesp
            • Duplicity
            • Uniquep
              • No-adjacent-duplicates-p
          • Concatenate
          • Remove
          • Remove1
          • Intersectp
          • Endp
          • Keyword-value-listp
          • Integer-listp
          • Reverse
          • Add-to-set
          • List-utilities
          • Set-size
          • Revappend
          • Subseq
          • Make-list
          • Last
          • Lists-light
          • Boolean-listp
          • Butlast
          • Pairlis$
          • Substitute
          • Count
          • Keyword-listp
          • List*
          • Eqlable-listp
          • Pos-listp
          • Integer-range-listp
          • Rational-listp
          • Evens
          • Atom-listp
          • ACL2-number-listp
          • Typed-list-utilities
          • Odds
          • List$
          • Listp
          • Standard-char-listp
          • Last-cdr
          • Pairlis
          • Proper-consp
          • Improper-consp
          • Pairlis-x2
          • Pairlis-x1
          • Merge-sort-lexorder
          • Fix-true-list
          • Real-listp
        • Invariant-risk
        • Errors
        • Defabbrev
        • Conses
        • Alists
        • Set-register-invariant-risk
        • Strings
        • Program-wrapper
        • Get-internal-time
        • Basics
        • Packages
        • Oracle-eval
        • Defmacro-untouchable
        • <<
        • Primitive
        • Revert-world
        • Unmemoize
        • Set-duplicate-keys-action
        • Symbols
        • Def-list-constructor
        • Easy-simplify-term
        • Defiteration
        • Fake-oracle-eval
        • Defopen
        • Sleep
      • Operational-semantics
      • Real
      • Start-here
      • Debugging
      • Miscellaneous
      • Output-controls
      • Macros
      • Interfacing-tools
    • Interfacing-tools
    • Hardware-verification
    • Software-verification
    • Math
    • Testing-utilities
  • No-duplicatesp

Uniquep

Sometimes better than no-duplicatesp: first sorts the list and then looks for adjacent duplicates.

Signature
(uniquep x) → *

(uniquep x) is provably equal to (no-duplicatesp x), but has different performance characteristics. It operates by sorting its argument and then scanning for adjacent duplicates.

Note: we leave this function enabled. You should never write a theorem about uniquep. Reason about no-duplicatesp instead.

Since we use a mergesort, the complexity of uniquep is O(n log n). By comparison, no-duplicatesp is O(n^2).

It is not always better to use uniquep than no-duplicatesp:

  • It uses far more memory than no-duplicatesp because it sorts the list.
  • On a list with lots of duplicates, no-duplicatesp may find a duplicate very quickly and stop early, but uniquep has to sort the whole list before it looks for any duplicates.

However, if your lists are sometimes long with few duplicates, uniquep is probably a much better function to use.

Definitions and Theorems

Function: uniquep$inline

(defun uniquep$inline (x)
  (declare (xargs :guard t))
  (let ((__function__ 'uniquep))
    (declare (ignorable __function__))
    (mbe :logic (no-duplicatesp x)
         :exec (no-adjacent-duplicates-p (<<-sort x)))))

Subtopics

No-adjacent-duplicates-p