|
| 1 | +From Stdlib Require Import PeanoNat Peano_dec. |
| 2 | +Local Open Scope nat_scope. |
| 3 | + |
| 4 | +Inductive fin : nat -> Type := |
| 5 | +| finO {n} : fin (S n) |
| 6 | +| finS {n} (_ : fin n) : fin (S n). |
| 7 | +Notation t := fin (only parsing). |
| 8 | +Notation fin0 := finO (only parsing). |
| 9 | + |
| 10 | +Fixpoint to_nat {n} (i : fin n) : nat := |
| 11 | + match i with |
| 12 | + | finO => 0 |
| 13 | + | finS i => S (to_nat i) |
| 14 | + end. |
| 15 | +Coercion to_nat : fin >-> nat. |
| 16 | + |
| 17 | +Definition cast {m} (v: t m) {n} : m = n -> t n := |
| 18 | + match Nat.eq_dec m n with |
| 19 | + | left Heq => fun _ => eq_rect m _ v n Heq |
| 20 | + | right Hneq => fun Heq => False_rect _ (Hneq Heq) |
| 21 | + end. |
| 22 | + |
| 23 | +Fixpoint add_nat (n : nat) [m] (i : fin m) {struct n} : fin (n + m) := |
| 24 | + match n with |
| 25 | + | 0 => i |
| 26 | + | S n => finS (add_nat n i) |
| 27 | + end. |
| 28 | + |
| 29 | +Section Relax. |
| 30 | +Context (n : nat). |
| 31 | +#[deprecated(since="9.1", note="Please open an issue if you would like stdlib to keep this definition.")] |
| 32 | +Fixpoint relax {m} (i : fin m) : fin (m + n) := |
| 33 | + match i in fin m return fin (m + n) with |
| 34 | + | finO => finO |
| 35 | + | finS i => finS (relax i) |
| 36 | + end. |
| 37 | +End Relax. |
| 38 | + |
| 39 | +Require Import Lia. |
| 40 | +Definition of_nat n (i : nat) (_ : i < n) : fin n. |
| 41 | + refine (cast (add_nat i (@fin0 (n-S i))) _). |
| 42 | +Proof. abstract lia. Defined. |
| 43 | + |
| 44 | +Lemma inj_0 (i : fin 0) : False. |
| 45 | +Proof. exact (match i with end). Qed. |
| 46 | + |
| 47 | +Lemma inj_S {n} (i : t (S n)) : i = finO \/ exists j, i = finS j. |
| 48 | +Proof. |
| 49 | + pattern i; refine ( (* destruct i, but using elaborator's small inversions *) |
| 50 | + match i in fin (S n) return forall P, P finO -> (forall i, P (finS i)) -> P i with |
| 51 | + | finO | _ => _ end _ _ _); eauto. |
| 52 | +Qed. |
| 53 | + |
| 54 | +Lemma to_nat_inj [n] (i j : fin n) : to_nat i = to_nat j -> i = j. |
| 55 | +Proof. |
| 56 | + induction i; pose proof inj_S j; firstorder subst; try discriminate; |
| 57 | + cbn [to_nat] in *; eauto using f_equal. |
| 58 | +Qed. |
| 59 | + |
| 60 | +Lemma to_nat_inj_iff [n] (i j : fin n) : to_nat i = to_nat j <-> i = j. |
| 61 | +Proof. split; try apply to_nat_inj; congruence. Qed. |
| 62 | + |
| 63 | +Lemma to_nat_inj_dep [n] (i : fin n) [m] (j : fin m) : n = m -> to_nat i = to_nat j -> |
| 64 | + existT _ _ i = existT _ _ j. |
| 65 | +Proof. destruct 1; auto using f_equal, to_nat_inj. Qed. |
| 66 | + |
| 67 | +Lemma to_nat_0 n : to_nat (@finO n) = 0. |
| 68 | +Proof. trivial. Qed. |
| 69 | + |
| 70 | +Lemma to_nat_S [n] (i : fin n) : to_nat (finS i) = S (to_nat i). |
| 71 | +Proof. trivial. Qed. |
| 72 | + |
| 73 | +Lemma to_nat_bound [n] (i : fin n) : to_nat i < n. |
| 74 | +Proof. |
| 75 | + induction i; cbn [to_nat]. { apply Nat.lt_0_succ. } |
| 76 | + rewrite <-Nat.succ_lt_mono. apply IHi. |
| 77 | +Qed. |
| 78 | + |
| 79 | + |
| 80 | +Lemma to_nat_eq_rect [m n] (p : m = n) i : to_nat (eq_rect m fin i n p) = to_nat i. |
| 81 | +Proof. case p; trivial. Qed. |
| 82 | + |
| 83 | +Lemma to_nat_cast [m n] (p : m = n) (i : fin m) : to_nat (cast i p) = to_nat i. |
| 84 | +Proof. cbv[cast]. case Nat.eq_dec; intros; [apply to_nat_eq_rect|contradiction]. Qed. |
| 85 | + |
| 86 | +Lemma cast_ext [m n] (p q : m = n) (i : fin m) : cast i p = cast i q. |
| 87 | +Proof. apply to_nat_inj; rewrite 2 to_nat_cast; trivial. Qed. |
| 88 | + |
| 89 | + |
| 90 | +Lemma to_nat_add_nat n [m] (i : fin m) : to_nat (add_nat n i) = n+i. |
| 91 | +Proof. induction n; cbn [to_nat add_nat Nat.add]; auto. Qed. |
| 92 | + |
| 93 | +Lemma to_nat_of_nat i n p : to_nat (of_nat n i p) = i. |
| 94 | +Proof. |
| 95 | + cbv [of_nat]. |
| 96 | + rewrite to_nat_cast, to_nat_add_nat, to_nat_0, Nat.add_0_r; trivial. |
| 97 | +Qed. |
| 98 | + |
| 99 | +Lemma of_nat_to_nat [n] i p : of_nat n (to_nat i) p = i. |
| 100 | +Proof. apply to_nat_inj, to_nat_of_nat. Qed. |
| 101 | + |
| 102 | +Lemma of_nat_ext [n i] (p q : i < n) : of_nat n i p = of_nat n i q. |
| 103 | +Proof. apply cast_ext. Qed. |
| 104 | + |
| 105 | + |
| 106 | + |
| 107 | +Lemma finS_inj {n} (x y : fin n) : finS x = finS y -> x = y. |
| 108 | +Proof. rewrite <-!to_nat_inj_iff; cbn [to_nat]; congruence. Qed. |
| 109 | + |
| 110 | + |
| 111 | + |
| 112 | +Fixpoint of_nat' (i : nat) : fin (S i) := |
| 113 | + match i with |
| 114 | + | O => finO |
| 115 | + | S i => finS (of_nat' i) |
| 116 | + end. |
| 117 | + |
| 118 | +Lemma to_nat_of_nat' i : to_nat (of_nat' i) = i. |
| 119 | +Proof. induction i; cbn [to_nat of_nat']; auto. Qed. |
0 commit comments