Skip to content

Instantly share code, notes, and snippets.

@jorpic
Last active August 29, 2015 14:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jorpic/bf37de156f48ea438076 to your computer and use it in GitHub Desktop.
Save jorpic/bf37de156f48ea438076 to your computer and use it in GitHub Desktop.
constructive pigeonhole proof
Require Import Omega.
Require Import Coq.Arith.Peano_dec. (* eq_nat_dec *)
Lemma nex_to_forall : forall k n x : nat, forall f,
(~exists k, k < n /\ f k = x) -> k < n -> f k <> x.
Proof.
intros k n x f H_nex H_P H_Q.
apply H_nex; exists k; auto.
Qed.
Lemma exists_or_not :
forall n x : nat, forall f : nat -> nat,
(exists k, k < n /\ f k = x) \/ (~exists k, k < n /\ f k = x).
Proof.
intros n x f.
induction n.
- right.
intro H_ex.
destruct H_ex as [k [Hk Hf]].
contradict Hk.
apply lt_n_0.
- destruct IHn as [H_ex | H_nex].
+ destruct H_ex as [k [H_kn H_fk]].
left; exists k; auto.
+ destruct (eq_nat_dec (f n) x) as [H_fn_eqx | H_fn_neq_x].
* left; exists n; auto.
* right. {
intro H_nex'.
destruct H_nex' as [k [H_kn H_fk]].
apply H_fn_neq_x.
apply lt_n_Sm_le in H_kn.
apply le_lt_or_eq in H_kn.
destruct H_kn as [H_lt | H_eq].
- contradict H_fk.
apply (nex_to_forall k n x f H_nex H_lt).
- rewrite <- H_eq; assumption.
}
Qed.
Theorem pigeonhole
: forall n : nat, forall f : nat -> nat, (forall i, i <= n -> f i < n)
-> exists i j, i <= n /\ j < i /\ f i = f j.
Proof.
induction n.
- intros f Hf.
specialize (Hf 0 (le_refl 0)).
inversion Hf.
- intros f Hf.
destruct (exists_or_not (n+1) (f (n+1)) f) as [H_ex_k | H_nex_k].
+ destruct H_ex_k as [k [Hk_le_Sn Hfk]].
exists (n+1), k.
split; [omega | split; [assumption | rewrite Hfk; reflexivity]].
+ set (g := fun x => if eq_nat_dec (f x) n then f (n+1) else f x).
assert (forall i : nat, i <= n -> g i < n).
{ intros.
unfold g.
destruct (eq_nat_dec (f i) n).
- apply nex_to_forall with (k := i) in H_nex_k.
+ specialize (Hf (n+1)); omega.
+ omega.
- specialize (Hf i); omega.
}
destruct (IHn g H) as [x H0].
destruct H0 as [y [H1 [H2 H3]]].
exists x, y.
split; [omega | split ; [assumption | idtac]].
(* lemma g x = g y -> f x = f y *)
unfold g in H3.
destruct eq_nat_dec in H3.
{ destruct eq_nat_dec in H3.
- rewrite e; rewrite e0. reflexivity.
- contradict H3.
apply not_eq_sym.
apply nex_to_forall with (n := n+1).
apply H_nex_k.
omega.
}
{ destruct eq_nat_dec in H3.
- contradict H3.
apply nex_to_forall with (n := n+1).
+ apply H_nex_k.
+ omega.
- assumption.
}
Qed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment