\import Arith.Fin \import Arith.Nat \import Data.Fin \import Data.Or \import Equiv \import Function \import Function.Meta ($) \import Logic \import Logic.Meta \import Order.LinearOrder \import Order.StrictOrder \import Paths \import Set \import Set.Fin \import Set.Fin.DFin \open FinLinearOrder \class PigeonholeSet \extends BaseSet { | pigeonhole (f : Nat -> E) : ∃ (i j : Nat) (i /= j) (f i = f j) \lemma pigeonhole< (f : Nat -> E) : ∃ (i j : Nat) (i < j) (f i = f j) => TruncP.map (pigeonhole f) \lam t => \case LinearOrder.trichotomy t.1 t.2 \with { | less c => (t.1, t.2, c, t.4) | equals c => absurd (t.3 c) | greater c => (t.2, t.1, c, inv t.4) } \lemma isEquiv (f : E -> E) (inj : isInj f) : Equiv f => isDFin.isEquiv (isDFin.fromPigeonhole \this) f inj } \class BoundedPigeonholeSet \extends PigeonholeSet { | finCard : Nat | boundedPigeonhole (f : Fin (suc finCard) -> E) : ∃ (i j : Fin (suc finCard)) (i /= j) (f i = f j) | pigeonhole f => TruncP.map (boundedPigeonhole (\lam j => f j)) \lam t => (t.1, t.2, fin_nat_/= t.3, t.4) \lemma boundedPigeonhole< (f : Fin (suc finCard) -> E) : ∃ (i j : Fin (suc finCard)) (i < j) (f i = f j) => TruncP.map (boundedPigeonhole f) \lam t => \case LinearOrder.trichotomy t.1 t.2 \with { | less c => (t.1, t.2, c, t.4) | equals c => absurd (t.3 c) | greater c => (t.2, t.1, c, inv t.4) } } \lemma pigeonhole-surj (A : BoundedPigeonholeSet) {B : \Set} (f : A -> B) (s : isSurj f) : BoundedPigeonholeSet B A.finCard \cowith | boundedPigeonhole g =>\have | (inP t) => FinSet.finiteAC (\lam j => s (g j)) | (inP r) => boundedPigeonhole (\lam j => (t j).1) \in inP (r.1, r.2, r.3, inv (t r.1).2 *> pmap f r.4 *> (t r.2).2) \lemma pigeonhole-fin {n m : Nat} (f : Fin m -> Fin n) (p : n < m) : ∃ (i j : Fin m) (i /= j) (f i = f j) => aux f \lam inj => <-irreflexive $ p <∘l FinSet.FinCardInj f inj \where { \lemma search-pair {n : Nat} {A : DecSet} (f : Fin n -> A) : Dec (∃ (i j : Fin n) (i /= j) (f i = f j)) => \have t i : Dec (∃ (j : Fin n) (i /= j) (f i = f j)) => \case FinSet.searchFin (\lam j => \Sigma (i /= j) (f i = f j)) (\lam j => decide) \with { | inl (j,p,_) => yes (inP (j, p.1, p.2)) | inr q => no \lam (inP (j, s, p)) => q j (s,p) } \in \case FinSet.searchFin _ t \with { | inl (i,p,_) => yes $ TruncP.map p (\lam q => (i, q.1, q.2, q.3)) | inr q => no \lam (inP (i,j,e,p)) => q i (inP (j, e, p)) } \lemma aux {n : Nat} {A : DecSet} (f : Fin n -> A) (p : Not (isInj f)) : ∃ (i j : Fin n) (i /= j) (f i = f j) => \case search-pair f \with { | yes e => e | no q => absurd $ p \lam {i} {j} p => \case decideEq i j \with { | yes e => e | no r => absurd $ q $ inP (i, j, r, p) } } }