Last active
August 29, 2015 14:05
-
-
Save jorpic/bf37de156f48ea438076 to your computer and use it in GitHub Desktop.
constructive pigeonhole proof
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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