• Top
    • Documentation
    • Books
    • Boolean-reasoning
    • Projects
    • Debugging
    • Std
      • Std/lists
        • Std/lists/abstract
        • Rev
        • Defsort
          • Alphanum-sort
        • List-fix
        • Std/lists/nth
        • Hons-remove-duplicates
        • Std/lists/update-nth
        • Set-equiv
        • Duplicity
        • Prefixp
        • Std/lists/take
        • Std/lists/intersection$
        • Nats-equiv
        • Repeat
        • Index-of
        • All-equalp
        • Sublistp
        • Std/lists/nthcdr
        • Listpos
        • List-equiv
        • Final-cdr
        • Std/lists/append
        • Std/lists/remove
        • Subseq-list
        • Rcons
        • Std/lists/revappend
        • Std/lists/remove-duplicates-equal
        • Std/lists/reverse
        • Std/lists/last
        • Std/lists/resize-list
        • Flatten
        • Suffixp
        • Std/lists/butlast
        • Std/lists/set-difference
        • Std/lists/len
        • Std/lists/intersectp
        • Std/lists/true-listp
        • Intersectp-witness
        • Subsetp-witness
        • Std/lists/remove1-equal
        • Rest-n
        • First-n
        • Std/lists/union
        • Std/lists/add-to-set
        • Append-without-guard
        • Std/lists/subsetp
        • Std/lists/member
      • Std/alists
      • Obags
      • Std/util
      • Std/strings
      • Std/osets
      • Std/io
      • Std/basic
      • Std/system
      • Std/typed-lists
      • Std/bitsets
      • Std/testing
      • Std/typed-alists
      • Std/stobjs
    • Proof-automation
    • Macro-libraries
    • ACL2
    • Interfacing-tools
    • Hardware-verification
    • Software-verification
    • Math
    • Testing-utilities
  • Std/lists

Defsort

Define a sorting function for a given comparator.

NOTE: Defsort's interface has a greater than average likelihood of changing incompatibly in the future.

Defsort creates a relatively-high-performance sorting function for a given comparison function, and proves that its output is an ordered (with respect to the comparison function) permutation of the input list. It is currently implemented as a mergesort on lists with some fixnum optimizations.

It also may optionally prove the generated mergesort function equivalent to an insertion sort; this requires some extra properties to be proved about the comparison function beforehand; see the discussion of :weak below.

Usage

These forms show various ways of invoking defsort:

(defsort sort-by-foo<
         :prefix foosort
         :compare< foo<
         :comparablep foo-p
         :comparable-listp foolist-p
         :true-listp nil
         :weak t)

(defsort :comparablep rationalp
         :compare< <
         :prefix <
         :comparable-listp rational-listp
         :true-listp t
         :weak nil)

(defsort intalist-sort
         :extra-args (alist)
         :extra-args-guard (intalistp alist)
         :compare< intalist-<
         :comparablep (lambda (x alist) (consp (assoc-equal x alist))))

(defsort intalist-sort2 (x alist)
         :extra-args-guard (intalistp alist)
         :compare< intalist2-<
         :comparablep (lambda (x alist) (stringp x)))

The first form is a new syntax that gives the name of the sorting function explicitly; it is also good for etags generation since it is of the form (def... name ...). In the first form, the prefix is optional; if it is not provided, the sort name will be used as the prefix for generating other function names.

The second form shows an older syntax in which the sort name is omitted and every function name is generated from the prefix, so the name of the sorting function will in this case be <-sort.

The third form shows the use of :extra-args to define a parameterized sort.

The fourth form shows a different syntax for specifying extra-args by giving a formals list before the keyword arguments, which looks a bit nicer. (Note: In this syntax the first formal must be the symbol X, although it can be in any package.) Additionally, it shows how to use extra-args in conjunction with a comparablep predicate that doesn't use them.

Keyword Arguments

  • :compare< gives the function to use to compare elements; this may be a binary function name or a lambda such as (lambda (x y) (< y x)). Defsort needs to prove that this is a transitive relation.
  • :prefix defaults to the sort name when it is provided, but otherwise is required. It is used to generate function and theorem names.
  • :comparablep gives the type of element to be compared. The comparison function's guards should be satisfied by any two elements that both satisfy this predicate. This may be a unary function symbol or lambda. If it is omitted, then it is treated as (lambda (x) t), i.e. all objects are comparable.
  • :comparable-listp gives the name of a function that recognizes a list of comparable elements. This may be omitted, in which case such a function will be defined (named <prefix>-list-p).
  • :true-listp defaults to NIL and determines whether the comparable-listp function requires the final cdr to be NIL. If an existing :comparable-listp function name is provided, then the value of :true-listp must correspond to that function; i.e. true-listp must be true iff the comparable-listp function requires the final cdr to be nil. If :comparable-listp is not provided, then the comparable-listp function will be generated so that this is true.
  • :weak defaults to NIL in the new syntax and T in the old syntax, for historical reasons. When :weak is NIL, defsort will introduce a simple insertion sort function in addition to the optimized mergesort, and prove the two equivalent. To do this, it needs a couple of extra facts about the comparison function, in addition to its transitivity: its negation must also be a transitive relation, and it must be strict, i.e., (not (compare< x x)).
  • :extra-args may be a list of variables that are used as extra parameters to all the functions involved. (If some of your functions don't require all the arguments, you must wrap them in a lambda in order to accept the right arguments.) When using the new syntax with a formals list, extra-args is not accepted since the formals list already specifies them.
  • :extra-args-guard may be a term giving a guard that will be required of the extra-args.
Troubleshooting

Defsort allows you to specify a lambda rather than a function for most arguments, and doesn't require that (e.g.) the :extra-args-guard be just a function call. But things may break if you use, e.g., a lambda containing an IF (or AND or OR) as, say, the comparablep predicate. It is best for everything to be a simple function call.

There may also be some bad cases when the setting of :comparablep is a built-in function that ACL2 treats specially or that is in minimal-theory. For example, :comparablep atom used to cause defsort to fail, though now it has a special hack for that particular case.

Subtopics

Alphanum-sort
Sorts lists using alphanumeric comparison.