Filtering...

sublistp

books/std/lists/sublistp

Included Books

other
(in-package "ACL2")
include-book
(include-book "prefixp")
local
(local (include-book "nthcdr"))
other
(defsection sublistp
  :parents (std/lists search)
  :short "@(call sublistp) checks whether the list @('x') ever occurs within
the list @('y')."
  :long "<p>ACL2 has a built-in @(see search) function, but it's very
complicated; it can operate on either lists or strings, using either equality
or case-insensitive character comparison, and can stop early, and can search
from the front or end, and so on.</p>

<p>In comparison, @('sublistp') is much simpler.  It only operates on lists,
always considers only equality, and always searches the whole list from the
front.  This makes it generally much more pleasant to reason about.</p>"
  (defund sublistp
    (x y)
    (declare (xargs :guard t))
    (cond ((prefixp x y) t)
      ((atom y) nil)
      (t (sublistp x (cdr y)))))
  (local (in-theory (enable sublistp)))
  (defthm sublistp-when-atom-left
    (implies (atom x) (equal (sublistp x y) t)))
  (defthm sublistp-when-atom-right
    (implies (atom y) (equal (sublistp x y) (atom x))))
  (defthm sublistp-of-cons-right
    (equal (sublistp x (cons a y))
      (or (prefixp x (cons a y)) (sublistp x y))))
  (defthm sublistp-when-prefixp
    (implies (prefixp x y) (sublistp x y)))
  (defthm sublistp-of-list-fix-left
    (equal (sublistp (list-fix x) y) (sublistp x y)))
  (defthm sublistp-of-list-fix-right
    (equal (sublistp x (list-fix y)) (sublistp x y)))
  (defcong list-equiv
    equal
    (sublistp x y)
    1
    :hints (("Goal" :in-theory (disable sublistp sublistp-of-list-fix-left)
       :use ((:instance sublistp-of-list-fix-left (x x)) (:instance sublistp-of-list-fix-left (x x-equiv))))))
  (defcong list-equiv
    equal
    (sublistp x y)
    2
    :hints (("Goal" :in-theory (disable sublistp sublistp-of-list-fix-right)
       :use ((:instance sublistp-of-list-fix-right (y y)) (:instance sublistp-of-list-fix-right (y y-equiv))))))
  (defthm lower-bound-of-len-when-sublistp
    (implies (sublistp x y) (<= (len x) (len y)))
    :rule-classes ((:rewrite) (:linear))))
other
(defsection listpos
  :parents (std/lists position)
  :short "@(call listpos) returns the starting position of the first occurrence
of the sublist @('x') within the list @('y'), or @('NIL') if there is no such
occurrence."
  :long "<p>See also @(see sublistp), which is closely related.</p>"
  (defund listpos
    (x y)
    (declare (xargs :guard t))
    (cond ((prefixp x y) 0)
      ((atom y) nil)
      (t (let ((pos-in-cdr (listpos x (cdr y))))
          (and pos-in-cdr (+ 1 pos-in-cdr))))))
  (local (in-theory (enable listpos)))
  (defthm listpos-when-atom-left
    (implies (atom x) (equal (listpos x y) 0)))
  (defthm listpos-when-atom-right
    (implies (atom y)
      (equal (listpos x y)
        (if (atom x)
          0
          nil))))
  (defthm listpos-of-list-fix-left
    (equal (listpos (list-fix x) y) (listpos x y)))
  (defthm listpos-of-list-fix-right
    (equal (listpos x (list-fix y)) (listpos x y)))
  (defcong list-equiv equal (listpos x y) 1)
  (defcong list-equiv
    equal
    (listpos x y)
    2
    :hints (("Goal" :in-theory (disable listpos-of-list-fix-right)
       :use ((:instance listpos-of-list-fix-right) (:instance listpos-of-list-fix-right (y y-equiv))))))
  (defthm listpos-under-iff
    (iff (listpos x y) (sublistp x y))
    :hints (("Goal" :in-theory (enable sublistp))))
  (encapsulate nil
    (defthm natp-of-listpos
      (equal (natp (listpos x y)) (sublistp x y)))
    (defthm integerp-of-listpos
      (equal (integerp (listpos x y)) (sublistp x y)))
    (defthm rationalp-of-listpos
      (equal (rationalp (listpos x y)) (sublistp x y)))
    (defthm acl2-numberp-of-listpos
      (equal (acl2-numberp (listpos x y)) (sublistp x y))))
  (defthm listpos-lower-bound-weak
    (<= 0 (listpos x y))
    :rule-classes (:linear))
  (defthm listpos-upper-bound-weak
    (<= (listpos x y) (len y))
    :rule-classes ((:rewrite) (:linear)))
  (defthm listpos-upper-bound-strong-1
    (equal (< (listpos x y) (len y)) (consp y))
    :rule-classes ((:rewrite) (:linear :corollary (implies (consp y) (< (listpos x y) (len y))))))
  (defthm listpos-upper-bound-strong-2
    (implies (sublistp x y)
      (<= (listpos x y) (- (len y) (len x))))
    :rule-classes ((:rewrite) (:linear)))
  (local (defthm l0
      (implies (and (prefixp x (nthcdr n y)) (natp n))
        (<= (listpos x y) n))))
  (defthm listpos-complete
    (implies (prefixp x (nthcdr n y))
      (and (listpos x y) (<= (listpos x y) (nfix n))))
    :rule-classes ((:rewrite) (:linear :corollary (implies (prefixp x (nthcdr n y))
          (<= (listpos x y) (nfix n)))))))
other
(defsection sublistp-correctness
  :extension sublistp
  (local (in-theory (enable sublistp listpos)))
  (defthm sublistp-sound
    (implies (sublistp x y)
      (let ((n (listpos x y)))
        (prefixp x (nthcdr n y))))
    :hints (("Goal" :induct (sublistp x y))))
  (defthm sublistp-complete
    (implies (prefixp x (nthcdr n y)) (sublistp x y))))