File: Mathlib/Data/Fin/Tuple/Sort.lean

full_name: Tuple.graph
code: /-- `graph f` produces the finset of pairs `(f i, i)`
equipped with the lexicographic order.
-/
def graph (f : Fin n → α) : Finset (α ×ₗ Fin n) 
goal: Finset (Lex (α × Fin n))

full_name: Tuple.graph.proj
code: /-- Given `p : α ×ₗ (Fin n) := (f i, i)` with `p ∈ graph f`,
`graph.proj p` is defined to be `f i`.
-/
def graph.proj {f : Fin n → α} : graph f → α 
goal: { x // x ∈ Tuple.graph f } → α

full_name: Tuple.graph.card
code: @[simp]
theorem graph.card (f : Fin n → α) : (graph f).card = n 
goal: (Tuple.graph f).card = n

full_name: Tuple.graphEquiv₁
code: /-- `graphEquiv₁ f` is the natural equivalence between `Fin n` and `graph f`,
mapping `i` to `(f i, i)`. -/
def graphEquiv₁ (f : Fin n → α) : Fin n ≃ graph f 
goal: Fin n ≃ { x // x ∈ Tuple.graph f }

full_name: Tuple.proj_equiv₁'
code: @[simp]
theorem proj_equiv₁' (f : Fin n → α) : graph.proj ∘ graphEquiv₁ f = f 
goal: Tuple.graph.proj ∘ ⇑(Tuple.graphEquiv₁ f) = f

full_name: Tuple.graphEquiv₂
code: /-- `graphEquiv₂ f` is an equivalence between `Fin n` and `graph f` that respects the order.
-/
def graphEquiv₂ (f : Fin n → α) : Fin n ≃o graph f 
goal: Fin n ≃o { x // x ∈ Tuple.graph f }

full_name: Tuple.sort
code: /-- `sort f` is the permutation that orders `Fin n` according to the order of the outputs of `f`. -/
def sort (f : Fin n → α) : Equiv.Perm (Fin n) 
goal: Equiv.Perm (Fin n)

full_name: Tuple.graphEquiv₂_apply
code: theorem graphEquiv₂_apply (f : Fin n → α) (i : Fin n) :
    graphEquiv₂ f i = graphEquiv₁ f (sort f i) 
goal: (Tuple.graphEquiv₂ f) i = (Tuple.graphEquiv₁ f) ((Tuple.sort f) i)

full_name: Tuple.self_comp_sort
code: theorem self_comp_sort (f : Fin n → α) : f ∘ sort f = graph.proj ∘ graphEquiv₂ f 
goal: f ∘ ⇑(Tuple.sort f) = Tuple.graph.proj ∘ ⇑(Tuple.graphEquiv₂ f)

full_name: Tuple.monotone_proj
code: theorem monotone_proj (f : Fin n → α) : Monotone (graph.proj : graph f → α) 
goal: Monotone Tuple.graph.proj

full_name: Tuple.monotone_sort
code: theorem monotone_sort (f : Fin n → α) : Monotone (f ∘ sort f) 
goal: Monotone (f ∘ ⇑(Tuple.sort f))

full_name: Tuple.lt_card_le_iff_apply_le_of_monotone
code: /-- If `f₀ ≤ f₁ ≤ f₂ ≤ ⋯` is a sorted `m`-tuple of elements of `α`, then for any `j : Fin m` and
`a : α` we have `j < #{i | fᵢ ≤ a}` iff `fⱼ ≤ a`. -/
theorem lt_card_le_iff_apply_le_of_monotone [PartialOrder α] [DecidableRel (α := α) LE.le]
    {m : ℕ} (f : Fin m → α) (a : α) (h_sorted : Monotone f) (j : Fin m) :
    j < Fintype.card {i // f i ≤ a} ↔ f j ≤ a 
goal: ↑j < Fintype.card { i // f i ≤ a } ↔ f j ≤ a

full_name: Tuple.lt_card_ge_iff_apply_ge_of_antitone
code: theorem lt_card_ge_iff_apply_ge_of_antitone [PartialOrder α] [DecidableRel (α := α) LE.le]
    {m : ℕ} (f : Fin m → α) (a : α) (h_sorted : Antitone f) (j : Fin m) :
    j < Fintype.card {i // a ≤ f i} ↔ a ≤ f j 
goal: ↑j < Fintype.card { i // a ≤ f i } ↔ a ≤ f j

full_name: Tuple.unique_monotone
code: /-- If two permutations of a tuple `f` are both monotone, then they are equal. -/
theorem unique_monotone [PartialOrder α] {f : Fin n → α} {σ τ : Equiv.Perm (Fin n)}
    (hfσ : Monotone (f ∘ σ)) (hfτ : Monotone (f ∘ τ)) : f ∘ σ = f ∘ τ 
goal: f ∘ ⇑σ = f ∘ ⇑τ

full_name: Tuple.eq_sort_iff'
code: /-- A permutation `σ` equals `sort f` if and only if the map `i ↦ (f (σ i), σ i)` is
strictly monotone (w.r.t. the lexicographic ordering on the target). -/
theorem eq_sort_iff' : σ = sort f ↔ StrictMono (σ.trans <| graphEquiv₁ f) 
goal: σ = Tuple.sort f ↔ StrictMono ⇑(Equiv.trans σ (Tuple.graphEquiv₁ f))

full_name: Tuple.eq_sort_iff
code: /-- A permutation `σ` equals `sort f` if and only if `f ∘ σ` is monotone and whenever `i < j`
and `f (σ i) = f (σ j)`, then `σ i < σ j`. This means that `sort f` is the lexicographically
smallest permutation `σ` such that `f ∘ σ` is monotone. -/
theorem eq_sort_iff :
    σ = sort f ↔ Monotone (f ∘ σ) ∧ ∀ i j, i < j → f (σ i) = f (σ j) → σ i < σ j 
goal: σ = Tuple.sort f ↔ Monotone (f ∘ ⇑σ) ∧ ∀ (i j : Fin n), i < j → f (σ i) = f (σ j) → σ i < σ j

full_name: Tuple.sort_eq_refl_iff_monotone
code: /-- The permutation that sorts `f` is the identity if and only if `f` is monotone. -/
theorem sort_eq_refl_iff_monotone : sort f = Equiv.refl _ ↔ Monotone f 
goal: Tuple.sort f = Equiv.refl (Fin n) ↔ Monotone f

full_name: Tuple.comp_sort_eq_comp_iff_monotone
code: /-- A permutation of a tuple `f` is `f` sorted if and only if it is monotone. -/
theorem comp_sort_eq_comp_iff_monotone : f ∘ σ = f ∘ sort f ↔ Monotone (f ∘ σ) 
goal: f ∘ ⇑σ = f ∘ ⇑(Tuple.sort f) ↔ Monotone (f ∘ ⇑σ)

full_name: Tuple.comp_perm_comp_sort_eq_comp_sort
code: /-- The sorted versions of a tuple `f` and of any permutation of `f` agree. -/
theorem comp_perm_comp_sort_eq_comp_sort : (f ∘ σ) ∘ sort (f ∘ σ) = f ∘ sort f 
goal: (f ∘ ⇑σ) ∘ ⇑(Tuple.sort (f ∘ ⇑σ)) = f ∘ ⇑(Tuple.sort f)

full_name: Tuple.antitone_pair_of_not_sorted'
code: /-- If a permutation `f ∘ σ` of the tuple `f` is not the same as `f ∘ sort f`, then `f ∘ σ`
has a pair of strictly decreasing entries. -/
theorem antitone_pair_of_not_sorted' (h : f ∘ σ ≠ f ∘ sort f) :
    ∃ i j, i < j ∧ (f ∘ σ) j < (f ∘ σ) i 
goal: ∃ i j, i < j ∧ (f ∘ ⇑σ) j < (f ∘ ⇑σ) i

full_name: Tuple.antitone_pair_of_not_sorted
code: /-- If the tuple `f` is not the same as `f ∘ sort f`, then `f` has a pair of strictly decreasing
entries. -/
theorem antitone_pair_of_not_sorted (h : f ≠ f ∘ sort f) : ∃ i j, i < j ∧ f j < f i 
goal: ∃ i j, i < j ∧ f j < f i