;; Given n holes and more than n pigeons, can we put pigeons into holes
;; so that every hole has at most one pigeon? Alternatively, can we
;; have a list of length n containing positive integers and whose sum
;; is greater than n?
;; Returns the sum of all numbers in list l. A list l element represents
;; the number of pigeons in the hole that number corresponds to. Hence,
;; (sum-list l) is the total number of pigeons placed in holes.
(defun sum-list (l)
(if (endp l)
0
(+ (car l) (sum-list (cdr l)))))
;; Returns T iff list l only has elements equal to 1 or 0.
;; Assign each number in l to a hole and let its value be the number
;; of pigeons in that hole. If (posn-one-listp l) is T then we
;; have successfully placed pigeons in holes so that no hole contains
;; more than one pigeon.
(defun posn-one-listp (l)
(if (endp l)
t
(if (or (equal 0 (car l)) (equal (car l) 1))
(posn-one-listp (cdr l))
nil)))
;; Note: (len l) is the number of holes.
;; This theorem says that if the number of pigeons (sum-list l) is
;; greater than the number of holes (len l), then some hole must have
;; greater than 1 pigeon in it (not (posn-one-listp l)).
(defthm pigeon-hole-violation-proved
(implies
(and (< 0 (len l)) (< (len l) (sum-list l)))
(not (posn-one-listp l))))
;; But the following version could not be proved - even after proving
;; lemma-1 and lemma-2. However, after proving the theorem, this does
;; prove...
(defthm attempted-pigeon-hole-violation
(implies
(and (< 0 n) (equal (len l) n) (equal (+ n 1) (sum-list l)))
(not (posn-one-listp l))))
;; If at most one pigeon can be assigned per hole, then the number of
;; pigeons assigned must be no greater than the number of holes.
;; Unfortunately, the theorem following does not prove without this
;; begin proved first. But this is just a restatement of the theorem
;; as a contrapositive.
(defthm lemma-1
(implies
(posn-one-listp l)
(<= (sum-list l) (len l))))
;; If lemma-1 is not proved first, the theorem is not proved with
;; the following result needed by ACL2:
;; (IMPLIES (AND (EQUAL (LEN (CDR L)) 0)
;; (CONSP L)
;; (EQUAL 0 (CAR L))
;; (NAT-LISTP (CDR L))
;; (ACL2-NUMBERP (SUM-LIST (CDR L)))
;; (< 1 (SUM-LIST (CDR L))))
;; (NOT (POSN-ONE-LISTP (CDR L))))
;;
;; But this is always true because the sum of all numbers in an
;; empty list cannot be greater than 1 so the hypothesis is always
;; false.
;;
;; This could be proved with the following
;; (defthm lemma-2
;; (implies
;; (and (nat-listp l) (equal (len (cdr l)) 0))
;; (not (< 1 (sum-list (cdr l))))))
;;
;; But this one (the one above) works as well
;; (defthm lemma-1
;; (implies
;; (and (nat-listp l) (posn-one-listp l))
;; (<= (sum-list l) (len l))))
;;