Filtering...

intersection

books/std/lists/intersection

Included Books

other
(in-package "ACL2")
include-book
(include-book "list-defuns")
include-book
(include-book "xdoc/top" :dir :system)
local
(local (include-book "sets"))
local
(local (in-theory (enable intersection$ intersectp)))
other
(defsection std/lists/intersection$
  :parents (std/lists intersection$)
  :short "Lemmas about @(see intersection$) available in the @(see std/lists)
library."
  "<p>We'll take @(see intersectp) as the desired normal form for asking
  whether intersections are empty.</p>"
  (defthm intersection$-under-iff
    (iff (intersection$ x y) (intersectp x y)))
  (defthm consp-of-intersection$
    (equal (consp (intersection$ x y)) (intersectp x y)))
  "<p>Basic atom/cons rules.</p>"
  (defthm intersection$-when-atom-left
    (implies (atom x) (equal (intersection$ x y) nil)))
  (defthm intersection$-of-cons-left
    (equal (intersection$ (cons a x) y)
      (if (member a y)
        (cons a (intersection$ x y))
        (intersection$ x y))))
  (defthm intersection$-when-atom-right
    (implies (atom y) (equal (intersection$ x y) nil)))
  "<p>We don't have a very nice rule for @(see cons) on the right if we're
  trying to maintain @('equal'), because we don't know where in @('x') the
  element occurs.  However, if we're only maintaining @(see set-equiv), then we
  can just put the element on the front and we get a perfectly nice rule:</p>"
  (defthm intersection$-of-cons-right-under-set-equiv
    (set-equiv (intersection$ x (cons a y))
      (if (member a x)
        (cons a (intersection$ x y))
        (intersection$ x y)))
    :hints (("Goal" :in-theory (enable set-equiv))))
  "<h5>Basic set reasoning</h5>"
  (defthm member-of-intersection$
    (iff (member a (intersection$ x y))
      (and (member a x) (member a y)))
    :rule-classes (:rewrite (:type-prescription :corollary (implies (not (member a x))
          (not (member a (intersection$ x y)))))
      (:type-prescription :corollary (implies (not (member a y))
          (not (member a (intersection$ x y)))))))
  (defthm subsetp-equal-of-intersection$-1
    (subsetp-equal (intersection$ x y) x))
  (defthm subsetp-equal-of-intersection$-2
    (subsetp-equal (intersection$ x y) y))
  (defthm subsetp-intersection-equal
    (iff (subsetp a (intersection-equal b c))
      (and (subsetp a b) (subsetp a c))))
  (defthm intersection$-commutes-under-set-equiv
    (set-equiv (intersection$ x y) (intersection$ y x))
    :hints (("Goal" :in-theory (enable set-equiv))))
  (defcong set-equiv equal (intersection-equal x y) 2)
  (defcong set-equiv set-equiv (intersection-equal x y) 1)
  "<h5>Length bound</h5>

  <p>Here is a nice bounding theorem.  Note that there is no analogous rule for
  @('-right'), because, e.g., X could have multiple copies of some member in Y,
  and if so we end up reproducing them.  Consider for instance:</p>

    @({ (intersection$ '(a a a) '(a)) ==> '(a a a) })"
  (defthm len-of-intersection$-upper-bound
    (<= (len (intersection$ x y)) (len x))
    :rule-classes ((:rewrite) (:linear))))