PigeonHole.agda 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. module Data.PigeonHole where
  2. open import Prelude
  3. open import Data.Nat hiding (_==_; _<_)
  4. open import Data.Fin
  5. open import Data.Vec as Vec
  6. open import Logic.Base
  7. open import Logic.Identity
  8. open Vec.Elem
  9. tooManyPigeons : {n : Nat}(xs : Vec (Fin (suc n)) n) -> ∃ \p -> p ∉ xs
  10. tooManyPigeons {zero} [] = ∃-I fzero nl
  11. tooManyPigeons {suc n} zs = aux zs (find _==_ fzero zs)
  12. where
  13. -- We start by checking whether or not fzero is an element of the list
  14. aux : {n : Nat}(xs : Vec (Fin (suc (suc n))) (suc n)) ->
  15. fzero ∈ xs \/ fzero ∉ xs -> ∃ \p -> p ∉ xs
  16. -- If it's not then we're done
  17. aux xs (\/-IR z∉xs) = ∃-I fzero z∉xs
  18. -- If it is we have to find another element
  19. aux xs (\/-IL z∈xs) = lem₂ ih
  20. where
  21. -- Let's remove the occurrence of fzero from the list and strip a fsuc
  22. -- from each of the other elements (i.e. map pred $ delete fzero xs)
  23. -- We can apply the induction hypothesis, giving us a p which is not in
  24. -- this list.
  25. ih : ∃ \p -> p ∉ map pred (delete fzero xs z∈xs)
  26. ih = tooManyPigeons (map pred $ delete _ xs z∈xs)
  27. -- First observe that if i ∉ map pred xs then fsuc i ∉ xs. Using this
  28. -- lemma we conclude that fsuc p ∉ delete fzero xs.
  29. lem₀ : {n m : Nat}(i : Fin (suc n))(xs : Vec (Fin (suc (suc n))) m) ->
  30. i ∉ map pred xs -> fsuc i ∉ xs
  31. lem₀ i [] nl = nl
  32. lem₀ i (x :: xs) (cns h t) = cns (rem₀ h) (lem₀ i xs t)
  33. where
  34. rem₀ : {n : Nat}{i : Fin (suc n)}{j : Fin (suc (suc n))} ->
  35. i ≢ pred j -> fsuc i ≢ j
  36. rem₀ i≠i refl = i≠i refl
  37. -- Furthermore, if i ∉ delete j xs and i ≠ j then i ∉ xs.
  38. lem₁ : {n m : Nat}{i : Fin (suc n)}{j : Fin n}
  39. (xs : Vec (Fin (suc n)) (suc m))(p : i ∈ xs) ->
  40. thin i j ∉ delete i xs p -> thin i j ∉ xs
  41. lem₁ (x :: xs) hd el = cns (thin-ij≠i _ _) el
  42. lem₁ {m = zero } (x :: xs) (tl ()) _
  43. lem₁ {m = suc _} (x :: xs) (tl p) (cns h t) = cns h (lem₁ xs p t)
  44. -- So we get fsuc p ∉ xs and we're done.
  45. lem₂ : (∃ \p -> p ∉ map pred (delete fzero xs z∈xs)) ->
  46. (∃ \p -> p ∉ xs)
  47. lem₂ (∃-I p h) = ∃-I (fsuc p) (lem₁ xs z∈xs $ lem₀ _ _ h)
  48. -- tooManyHoles : {n : Nat}(xs : Vec (Fin n) (suc n)) ->
  49. -- ∃ \p -> ∃ \i -> ∃ \j -> xs ! i ≡ p /\ xs ! thin i j ≡ p
  50. -- tooManyHoles = ?