Skip to content

Commit

Permalink
feat(data/fin): there is at most one order_iso from fin n to α (#…
Browse files Browse the repository at this point in the history
…5499)

* Define a `bounded_lattice` instance on `fin (n + 1)`.
* Prove that there is at most one `order_iso` from `fin n` to `α`.
  • Loading branch information
urkud committed Jan 2, 2021
1 parent 8aa2332 commit c32efea
Showing 1 changed file with 64 additions and 9 deletions.
73 changes: 64 additions & 9 deletions src/data/fin.lean
Expand Up @@ -254,13 +254,34 @@ lemma lt_iff_coe_lt_coe : a < b ↔ (a : ℕ) < b := iff.rfl

lemma le_iff_coe_le_coe : a ≤ b ↔ (a : ℕ) ≤ b := iff.rfl

lemma mk_lt_of_lt_coe {a : ℕ} (h : a < b) : (⟨a, h.trans b.is_lt⟩ : fin n) < b := h

lemma mk_le_of_le_coe {a : ℕ} (h : a ≤ b) : (⟨a, h.trans_lt b.is_lt⟩ : fin n) ≤ b := h

lemma zero_le (a : fin (n + 1)) : 0 ≤ a := zero_le a.1

@[simp] lemma coe_succ (j : fin n) : (j.succ : ℕ) = j + 1 :=
by cases j; simp [fin.succ]

lemma succ_pos (a : fin n) : (0 : fin (n + 1)) < a.succ := by simp [lt_iff_coe_lt_coe]

/-- The greatest value of `fin (n+1)` -/
def last (n : ℕ) : fin (n+1) := ⟨_, n.lt_succ_self⟩

@[simp, norm_cast] lemma coe_last (n : ℕ) : (last n : ℕ) = n := rfl

lemma last_val (n : ℕ) : (last n).val = n := rfl

theorem le_last (i : fin (n+1)) : i ≤ last n :=
le_of_lt_succ i.is_lt

instance : bounded_lattice (fin (n + 1)) :=
{ top := last n,
le_top := le_last,
bot := 0,
bot_le := zero_le,
.. fin.linear_order, .. lattice_of_linear_order }

/-- `fin.succ` as an `order_embedding` -/
def succ_embedding (n : ℕ) : fin n ↪o fin (n + 1) :=
order_embedding.of_strict_mono fin.succ $ λ ⟨i, hi⟩ ⟨j, hj⟩ h, succ_lt_succ h
Expand Down Expand Up @@ -332,11 +353,6 @@ def coe_embedding (n) : (fin n) ↪o ℕ :=
instance fin.lt.is_well_order (n) : is_well_order (fin n) (<) :=
(coe_embedding n).is_well_order

/-- The greatest value of `fin (n+1)` -/
def last (n : ℕ) : fin (n+1) := ⟨_, n.lt_succ_self⟩

@[simp, norm_cast] lemma coe_last (n : ℕ) : (last n : ℕ) = n := rfl

/-- `cast_lt i h` embeds `i` into a `fin` where `h` proves it belongs into. -/
def cast_lt (i : fin m) (h : i.1 < n) : fin n := ⟨i.1, h⟩

Expand All @@ -355,7 +371,7 @@ def cast (eq : n = m) : fin n ≃o fin m :=

@[simp] lemma symm_cast (h : n = m) : (cast h).symm = cast h.symm := rfl

@[simp] lemma coe_cast (h : n = m) (i : fin n) : (cast h i : ℕ) = i := rfl
lemma coe_cast (h : n = m) (i : fin n) : (cast h i : ℕ) = i := rfl

@[simp] lemma cast_trans {k : ℕ} (h : n = m) (h' : m = k) {i : fin n} :
cast h' (cast h i) = cast (eq.trans h h') i := rfl
Expand Down Expand Up @@ -415,10 +431,49 @@ order_embedding.of_strict_mono (λ i, ⟨n + (i : ℕ), add_lt_add_left i.2 _⟩

@[simp] lemma coe_nat_add (n : ℕ) {m : ℕ} (i : fin m) : (nat_add n i : ℕ) = n + i := rfl

theorem le_last (i : fin (n+1)) : i ≤ last n :=
le_of_lt_succ i.is_lt
/-- If `e` is an `order_iso` between `fin n` and `fin m`, then `n = m` and `e` is the identity
map. In this lemma we state that for each `i : fin n` we have `(e i : ℕ) = (i : ℕ)`. -/
@[simp] lemma coe_order_iso_apply (e : fin n ≃o fin m) (i : fin n) : (e i : ℕ) = i :=
begin
rcases i with ⟨i, hi⟩,
rw [subtype.coe_mk],
induction i using nat.strong_induction_on with i h,
refine le_antisymm (forall_lt_iff_le.1 $ λ j hj, _) (forall_lt_iff_le.1 $ λ j hj, _),
{ have := e.symm.apply_lt_apply.2 (mk_lt_of_lt_coe hj),
rw e.symm_apply_apply at this,
convert this,
simpa using h _ this (e.symm _).is_lt },
{ rwa [← h j hj (hj.trans hi), ← lt_iff_coe_lt_coe, e.apply_lt_apply] }
end

lemma last_val (n : ℕ) : (last n).val = n := rfl
section

variables {α : Type*} [preorder α]
open set

instance order_iso_subsingleton : subsingleton (fin n ≃o α) :=
⟨λ e e', by { ext i,
rw [← e.symm.apply_eq_iff_eq, e.symm_apply_apply, ← e'.trans_apply, ext_iff,
coe_order_iso_apply] }⟩

instance order_iso_subsingleton' : subsingleton (α ≃o fin n) :=
order_iso.symm_injective.subsingleton

instance order_iso_unique : unique (fin n ≃o fin n) := unique.mk' _

/-- Two strictly monotone functions from `fin n` are equal provided that their ranges
are equal. -/
lemma strict_mono_unique {f g : fin n → α} (hf : strict_mono f) (hg : strict_mono g)
(h : range f = range g) : f = g :=
have (hf.order_iso f).trans (order_iso.set_congr _ _ h) = hg.order_iso g,
from subsingleton.elim _ _,
congr_arg (function.comp (coe : range g → α)) (funext $ rel_iso.ext_iff.1 this)

/-- Two order embeddings of `fin n` are equal provided that their ranges are equal. -/
lemma order_embedding_eq {f g : fin n ↪o α} (h : range f = range g) : f = g :=
rel_embedding.ext $ funext_iff.1 $ strict_mono_unique f.strict_mono g.strict_mono h

end

@[simp] lemma succ_last (n : ℕ) : (last n).succ = last (n.succ) := rfl

Expand Down

0 comments on commit c32efea

Please sign in to comment.