File: Mathlib/Order/RelSeries.lean

full_name: RelSeries
code: /--
Let `r` be a relation on `α`, a relation series of `r` of length `n` is a series
`a_0, a_1, ..., a_n` such that `r a_i a_{i+1}` for all `i < n`
-/
structure RelSeries where
  /-- The number of inequalities in the series -/
  length : ℕ
  /-- The underlying function of a relation series -/
  toFun : Fin (length + 1) → α
  /-- Adjacent elements are related -/
  step : ∀ (i : Fin length), r (toFun (Fin.castSucc i)) (toFun i.succ)
goal: Type u_1

full_name: RelSeries.toFun
code: /--
Let `r` be a relation on `α`, a relation series of `r` of length `n` is a series
`a_0, a_1, ..., a_n` such that `r a_i a_{i+1}` for all `i < n`
-/
structure RelSeries where
  /-- The number of inequalities in the series -/
  length : ℕ
  /-- The underlying function of a relation series -/
  toFun : Fin (length + 1) → α
  /-- Adjacent elements are related -/
  step : ∀ (i : Fin length), r (toFun (Fin.castSucc i)) (toFun i.succ)
goal: Fin (self.length + 1) → α

full_name: RelSeries.step
code: /--
Let `r` be a relation on `α`, a relation series of `r` of length `n` is a series
`a_0, a_1, ..., a_n` such that `r a_i a_{i+1}` for all `i < n`
-/
structure RelSeries where
  /-- The number of inequalities in the series -/
  length : ℕ
  /-- The underlying function of a relation series -/
  toFun : Fin (length + 1) → α
  /-- Adjacent elements are related -/
  step : ∀ (i : Fin length), r (toFun (Fin.castSucc i)) (toFun i.succ)
goal: r (self.toFun i.castSucc) (self.toFun i.succ)

full_name: RelSeries.length
code: /--
Let `r` be a relation on `α`, a relation series of `r` of length `n` is a series
`a_0, a_1, ..., a_n` such that `r a_i a_{i+1}` for all `i < n`
-/
structure RelSeries where
  /-- The number of inequalities in the series -/
  length : ℕ
  /-- The underlying function of a relation series -/
  toFun : Fin (length + 1) → α
  /-- Adjacent elements are related -/
  step : ∀ (i : Fin length), r (toFun (Fin.castSucc i)) (toFun i.succ)
goal: ℕ

full_name: RelSeries.instCoeFunForallFinHAddNatLengthOfNat
code: instance : CoeFun (RelSeries r) (fun x ↦ Fin (x.length + 1) → α) 
goal: CoeFun (RelSeries r) fun x => Fin (x.length + 1) → α

full_name: RelSeries.singleton_toFun
code: /--
For any type `α`, each term of `α` gives a relation series with the right most index to be 0.
-/
@[simps!] def singleton (a : α) : RelSeries r 
goal: ∀ (x : Fin (0 + 1)), (RelSeries.singleton r a).toFun x = a

full_name: RelSeries.singleton
code: /--
For any type `α`, each term of `α` gives a relation series with the right most index to be 0.
-/
@[simps!] def singleton (a : α) : RelSeries r 
goal: RelSeries r

full_name: RelSeries.singleton_length
code: /--
For any type `α`, each term of `α` gives a relation series with the right most index to be 0.
-/
@[simps!] def singleton (a : α) : RelSeries r 
goal: (RelSeries.singleton r a).length = 0

full_name: RelSeries.instIsEmpty
code: instance [IsEmpty α] : IsEmpty (RelSeries r) 
goal: IsEmpty (RelSeries r)

full_name: RelSeries.instInhabited
code: instance [Inhabited α] : Inhabited (RelSeries r) 
goal: Inhabited (RelSeries r)

full_name: RelSeries.instNonempty
code: instance [Nonempty α] : Nonempty (RelSeries r) 
goal: Nonempty (RelSeries r)

full_name: RelSeries.ext
code: @[ext]
lemma ext {x y : RelSeries r} (length_eq : x.length = y.length)
    (toFun_eq : x.toFun = y.toFun ∘ Fin.cast (by rw [length_eq])) : x = y 
goal: x = y

full_name: RelSeries.rel_of_lt
code: lemma rel_of_lt [IsTrans α r] (x : RelSeries r) {i j : Fin (x.length + 1)} (h : i < j) :
    r (x i) (x j) 
goal: r (x.toFun i) (x.toFun j)

full_name: RelSeries.rel_or_eq_of_le
code: lemma rel_or_eq_of_le [IsTrans α r] (x : RelSeries r) {i j : Fin (x.length + 1)} (h : i ≤ j) :
    r (x i) (x j) ∨ x i = x j 
goal: r (x.toFun i) (x.toFun j) ∨ x.toFun i = x.toFun j

full_name: RelSeries.ofLE
code: /--
Given two relations `r, s` on `α` such that `r ≤ s`, any relation series of `r` induces a relation
series of `s`
-/
@[simps!]
def ofLE (x : RelSeries r) {s : Rel α α} (h : r ≤ s) : RelSeries s 
goal: RelSeries s

full_name: RelSeries.ofLE_length
code: /--
Given two relations `r, s` on `α` such that `r ≤ s`, any relation series of `r` induces a relation
series of `s`
-/
@[simps!]
def ofLE (x : RelSeries r) {s : Rel α α} (h : r ≤ s) : RelSeries s 
goal: (x.ofLE h).length = x.length

full_name: RelSeries.ofLE_toFun
code: /--
Given two relations `r, s` on `α` such that `r ≤ s`, any relation series of `r` induces a relation
series of `s`
-/
@[simps!]
def ofLE (x : RelSeries r) {s : Rel α α} (h : r ≤ s) : RelSeries s 
goal: ∀ (a : Fin (x.length + 1)), (x.ofLE h).toFun a = x.toFun a

full_name: RelSeries.coe_ofLE
code: lemma coe_ofLE (x : RelSeries r) {s : Rel α α} (h : r ≤ s) :
    (x.ofLE h : _ → _) = x 
goal: (x.ofLE h).toFun = x.toFun

full_name: RelSeries.toList
code: /-- Every relation series gives a list -/
def toList (x : RelSeries r) : List α 
goal: List α

full_name: RelSeries.length_toList
code: @[simp]
lemma length_toList (x : RelSeries r) : x.toList.length = x.length + 1 
goal: x.toList.length = x.length + 1

full_name: RelSeries.toList_chain'
code: lemma toList_chain' (x : RelSeries r) : x.toList.Chain' r 
goal: List.Chain' r x.toList

full_name: RelSeries.toList_ne_nil
code: lemma toList_ne_nil (x : RelSeries r) : x.toList ≠ [] 
goal: x.toList ≠ []

full_name: RelSeries.fromListChain'_length
code: /-- Every nonempty list satisfying the chain condition gives a relation series-/
@[simps]
def fromListChain' (x : List α) (x_ne_nil : x ≠ []) (hx : x.Chain' r) : RelSeries r 
goal: (RelSeries.fromListChain' x x_ne_nil hx).length = x.length.pred

full_name: RelSeries.fromListChain'_toFun
code: /-- Every nonempty list satisfying the chain condition gives a relation series-/
@[simps]
def fromListChain' (x : List α) (x_ne_nil : x ≠ []) (hx : x.Chain' r) : RelSeries r 
goal: ∀ (a : Fin (x.length.pred + 1)), (RelSeries.fromListChain' x x_ne_nil hx).toFun a = (x.get ∘ Fin.cast ⋯) a

full_name: RelSeries.fromListChain'
code: /-- Every nonempty list satisfying the chain condition gives a relation series-/
@[simps]
def fromListChain' (x : List α) (x_ne_nil : x ≠ []) (hx : x.Chain' r) : RelSeries r 
goal: RelSeries r

full_name: RelSeries.Equiv
code: /-- Relation series of `r` and nonempty list of `α` satisfying `r`-chain condition bijectively
corresponds to each other. -/
protected def Equiv : RelSeries r ≃ {x : List α | x ≠ [] ∧ x.Chain' r} 
goal: RelSeries r ≃ ↑{x | x ≠ [] ∧ List.Chain' r x}

full_name: RelSeries.toList_injective
code: lemma toList_injective : Function.Injective (RelSeries.toList (r := r)) 
goal: Function.Injective RelSeries.toList

full_name: Rel.FiniteDimensional
code: /-- A relation `r` is said to be finite dimensional iff there is a relation series of `r` with the
  maximum length. -/
class FiniteDimensional : Prop where
  /-- A relation `r` is said to be finite dimensional iff there is a relation series of `r` with the
    maximum length. -/
  exists_longest_relSeries : ∃ x : RelSeries r, ∀ y : RelSeries r, y.length ≤ x.length
goal: Prop

full_name: Rel.FiniteDimensional.exists_longest_relSeries
code: /-- A relation `r` is said to be finite dimensional iff there is a relation series of `r` with the
  maximum length. -/
class FiniteDimensional : Prop where
  /-- A relation `r` is said to be finite dimensional iff there is a relation series of `r` with the
    maximum length. -/
  exists_longest_relSeries : ∃ x : RelSeries r, ∀ y : RelSeries r, y.length ≤ x.length
goal: ∃ x, ∀ (y : RelSeries r), y.length ≤ x.length

full_name: Rel.InfiniteDimensional
code: /-- A relation `r` is said to be infinite dimensional iff there exists relation series of arbitrary
  length. -/
class InfiniteDimensional : Prop where
  /-- A relation `r` is said to be infinite dimensional iff there exists relation series of
    arbitrary length. -/
  exists_relSeries_with_length : ∀ n : ℕ, ∃ x : RelSeries r, x.length = n
goal: Prop

full_name: Rel.InfiniteDimensional.exists_relSeries_with_length
code: /-- A relation `r` is said to be infinite dimensional iff there exists relation series of arbitrary
  length. -/
class InfiniteDimensional : Prop where
  /-- A relation `r` is said to be infinite dimensional iff there exists relation series of
    arbitrary length. -/
  exists_relSeries_with_length : ∀ n : ℕ, ∃ x : RelSeries r, x.length = n
goal: ∃ x, x.length = n

full_name: RelSeries.longestOf
code: /-- The longest relational series when a relation is finite dimensional -/
protected noncomputable def longestOf [r.FiniteDimensional] : RelSeries r 
goal: RelSeries r

full_name: RelSeries.length_le_length_longestOf
code: lemma length_le_length_longestOf [r.FiniteDimensional] (x : RelSeries r) :
    x.length ≤ (RelSeries.longestOf r).length 
goal: x.length ≤ (RelSeries.longestOf r).length

full_name: RelSeries.withLength
code: /-- A relation series with length `n` if the relation is infinite dimensional -/
protected noncomputable def withLength [r.InfiniteDimensional] (n : ℕ) : RelSeries r 
goal: RelSeries r

full_name: RelSeries.length_withLength
code: @[simp] lemma length_withLength [r.InfiniteDimensional] (n : ℕ) :
    (RelSeries.withLength r n).length = n 
goal: (RelSeries.withLength r n).length = n

full_name: RelSeries.nonempty_of_infiniteDimensional
code: /-- If a relation on `α` is infinite dimensional, then `α` is nonempty. -/
lemma nonempty_of_infiniteDimensional [r.InfiniteDimensional] : Nonempty α 
goal: Nonempty α

full_name: RelSeries.membership
code: instance membership : Membership α (RelSeries r) 
goal: Membership α (RelSeries r)

full_name: RelSeries.mem_def
code: theorem mem_def : x ∈ s ↔ x ∈ Set.range s 
goal: x ∈ s ↔ x ∈ Set.range s.toFun

full_name: RelSeries.mem_toList
code: @[simp] theorem mem_toList : x ∈ s.toList ↔ x ∈ s 
goal: x ∈ s.toList ↔ x ∈ s

full_name: RelSeries.subsingleton_of_length_eq_zero
code: theorem subsingleton_of_length_eq_zero (hs : s.length = 0) : {x | x ∈ s}.Subsingleton 
goal: {x | x ∈ s}.Subsingleton

full_name: RelSeries.length_ne_zero_of_nontrivial
code: theorem length_ne_zero_of_nontrivial (h : {x | x ∈ s}.Nontrivial) : s.length ≠ 0 
goal: s.length ≠ 0

full_name: RelSeries.length_pos_of_nontrivial
code: theorem length_pos_of_nontrivial (h : {x | x ∈ s}.Nontrivial) : 0 < s.length 
goal: 0 < s.length

full_name: RelSeries.length_ne_zero
code: theorem length_ne_zero (irrefl : Irreflexive r) : s.length ≠ 0 ↔ {x | x ∈ s}.Nontrivial 
goal: s.length ≠ 0 ↔ {x | x ∈ s}.Nontrivial

full_name: RelSeries.length_pos
code: theorem length_pos (irrefl : Irreflexive r) : 0 < s.length ↔ {x | x ∈ s}.Nontrivial 
goal: 0 < s.length ↔ {x | x ∈ s}.Nontrivial

full_name: RelSeries.length_eq_zero
code: lemma length_eq_zero (irrefl : Irreflexive r) : s.length = 0 ↔ {x | x ∈ s}.Subsingleton 
goal: s.length = 0 ↔ {x | x ∈ s}.Subsingleton

full_name: RelSeries.head
code: /-- Start of a series, i.e. for `a₀ -r→ a₁ -r→ ... -r→ aₙ`, its head is `a₀`.

Since a relation series is assumed to be non-empty, this is well defined. -/
def head (x : RelSeries r) : α 
goal: α

full_name: RelSeries.last
code: /-- End of a series, i.e. for `a₀ -r→ a₁ -r→ ... -r→ aₙ`, its last element is `aₙ`.

Since a relation series is assumed to be non-empty, this is well defined. -/
def last (x : RelSeries r) : α 
goal: α

full_name: RelSeries.apply_last
code: lemma apply_last (x : RelSeries r) : x (Fin.last <| x.length) = x.last 
goal: x.toFun (Fin.last x.length) = x.last

full_name: RelSeries.head_mem
code: lemma head_mem (x : RelSeries r) : x.head ∈ x 
goal: x.head ∈ x

full_name: RelSeries.last_mem
code: lemma last_mem (x : RelSeries r) : x.last ∈ x 
goal: x.last ∈ x

full_name: RelSeries.append
code: /--
If `a₀ -r→ a₁ -r→ ... -r→ aₙ` and `b₀ -r→ b₁ -r→ ... -r→ bₘ` are two strict series
such that `r aₙ b₀`, then there is a chain of length `n + m + 1` given by
`a₀ -r→ a₁ -r→ ... -r→ aₙ -r→ b₀ -r→ b₁ -r→ ... -r→ bₘ`.
-/
@[simps length]
def append (p q : RelSeries r) (connect : r p.last q.head) : RelSeries r 
goal: RelSeries r

full_name: RelSeries.append_length
code: /--
If `a₀ -r→ a₁ -r→ ... -r→ aₙ` and `b₀ -r→ b₁ -r→ ... -r→ bₘ` are two strict series
such that `r aₙ b₀`, then there is a chain of length `n + m + 1` given by
`a₀ -r→ a₁ -r→ ... -r→ aₙ -r→ b₀ -r→ b₁ -r→ ... -r→ bₘ`.
-/
@[simps length]
def append (p q : RelSeries r) (connect : r p.last q.head) : RelSeries r 
goal: (p.append q connect).length = p.length + q.length + 1

full_name: RelSeries.append_apply_left
code: lemma append_apply_left (p q : RelSeries r) (connect : r p.last q.head)
    (i : Fin (p.length + 1)) :
    p.append q connect ((i.castAdd (q.length + 1)).cast (by dsimp; abel)) = p i 
goal: (p.append q connect).toFun (Fin.cast ⋯ (Fin.castAdd (q.length + 1) i)) = p.toFun i

full_name: RelSeries.append_apply_right
code: lemma append_apply_right (p q : RelSeries r) (connect : r p.last q.head)
    (i : Fin (q.length + 1)) :
    p.append q connect (i.natAdd p.length + 1) = q i 
goal: (p.append q connect).toFun (↑↑(Fin.natAdd p.length i) + 1) = q.toFun i

full_name: RelSeries.head_append
code: @[simp] lemma head_append (p q : RelSeries r) (connect : r p.last q.head) :
    (p.append q connect).head = p.head 
goal: (p.append q connect).head = p.head

full_name: RelSeries.last_append
code: @[simp] lemma last_append (p q : RelSeries r) (connect : r p.last q.head) :
    (p.append q connect).last = q.last 
goal: (p.append q connect).last = q.last

full_name: RelSeries.map
code: /--
For two types `α, β` and relation on them `r, s`, if `f : α → β` preserves relation `r`, then an
`r`-series can be pushed out to an `s`-series by
`a₀ -r→ a₁ -r→ ... -r→ aₙ ↦ f a₀ -s→ f a₁ -s→ ... -s→ f aₙ`
-/
@[simps length]
def map (p : RelSeries r) (f : r →r s) : RelSeries s 
goal: RelSeries s

full_name: RelSeries.map_length
code: /--
For two types `α, β` and relation on them `r, s`, if `f : α → β` preserves relation `r`, then an
`r`-series can be pushed out to an `s`-series by
`a₀ -r→ a₁ -r→ ... -r→ aₙ ↦ f a₀ -s→ f a₁ -s→ ... -s→ f aₙ`
-/
@[simps length]
def map (p : RelSeries r) (f : r →r s) : RelSeries s 
goal: (p.map f).length = p.length

full_name: RelSeries.map_apply
code: @[simp] lemma map_apply (p : RelSeries r) (f : r →r s) (i : Fin (p.length + 1)) :
    p.map f i = f (p i) 
goal: (p.map f).toFun i = f (p.toFun i)

full_name: RelSeries.insertNth_toFun
code: /--
If `a₀ -r→ a₁ -r→ ... -r→ aₙ` is an `r`-series and `a` is such that
`aᵢ -r→ a -r→ a_ᵢ₊₁`, then
`a₀ -r→ a₁ -r→ ... -r→ aᵢ -r→ a -r→ aᵢ₊₁ -r→ ... -r→ aₙ`
is another `r`-series
-/
@[simps]
def insertNth (p : RelSeries r) (i : Fin p.length) (a : α)
    (prev_connect : r (p (Fin.castSucc i)) a) (connect_next : r a (p i.succ)) : RelSeries r 
goal: (p.insertNth i a prev_connect connect_next).toFun j = i.succ.castSucc.insertNth a p.toFun j

full_name: RelSeries.insertNth_length
code: /--
If `a₀ -r→ a₁ -r→ ... -r→ aₙ` is an `r`-series and `a` is such that
`aᵢ -r→ a -r→ a_ᵢ₊₁`, then
`a₀ -r→ a₁ -r→ ... -r→ aᵢ -r→ a -r→ aᵢ₊₁ -r→ ... -r→ aₙ`
is another `r`-series
-/
@[simps]
def insertNth (p : RelSeries r) (i : Fin p.length) (a : α)
    (prev_connect : r (p (Fin.castSucc i)) a) (connect_next : r a (p i.succ)) : RelSeries r 
goal: (p.insertNth i a prev_connect connect_next).length = p.length + 1

full_name: RelSeries.insertNth
code: /--
If `a₀ -r→ a₁ -r→ ... -r→ aₙ` is an `r`-series and `a` is such that
`aᵢ -r→ a -r→ a_ᵢ₊₁`, then
`a₀ -r→ a₁ -r→ ... -r→ aᵢ -r→ a -r→ aᵢ₊₁ -r→ ... -r→ aₙ`
is another `r`-series
-/
@[simps]
def insertNth (p : RelSeries r) (i : Fin p.length) (a : α)
    (prev_connect : r (p (Fin.castSucc i)) a) (connect_next : r a (p i.succ)) : RelSeries r 
goal: RelSeries r

full_name: RelSeries.reverse
code: /--
A relation series `a₀ -r→ a₁ -r→ ... -r→ aₙ` of `r` gives a relation series of the reverse of `r`
by reversing the series `aₙ ←r- aₙ₋₁ ←r- ... ←r- a₁ ←r- a₀`.
-/
@[simps length]
def reverse (p : RelSeries r) : RelSeries (fun (a b : α) ↦ r b a) 
goal: RelSeries fun a b => r b a

full_name: RelSeries.reverse_length
code: /--
A relation series `a₀ -r→ a₁ -r→ ... -r→ aₙ` of `r` gives a relation series of the reverse of `r`
by reversing the series `aₙ ←r- aₙ₋₁ ←r- ... ←r- a₁ ←r- a₀`.
-/
@[simps length]
def reverse (p : RelSeries r) : RelSeries (fun (a b : α) ↦ r b a) 
goal: p.reverse.length = p.length

full_name: RelSeries.reverse_apply
code: @[simp] lemma reverse_apply (p : RelSeries r) (i : Fin (p.length + 1)) :
    p.reverse i = p i.rev 
goal: p.reverse.toFun i = p.toFun i.rev

full_name: RelSeries.cons
code: /--
Given a series `a₀ -r→ a₁ -r→ ... -r→ aₙ` and an `a` such that `a₀ -r→ a` holds, there is
a series of length `n+1`: `a -r→ a₀ -r→ a₁ -r→ ... -r→ aₙ`.
-/
@[simps! length]
def cons (p : RelSeries r) (newHead : α) (rel : r newHead p.head) : RelSeries r 
goal: RelSeries r

full_name: RelSeries.cons_length
code: /--
Given a series `a₀ -r→ a₁ -r→ ... -r→ aₙ` and an `a` such that `a₀ -r→ a` holds, there is
a series of length `n+1`: `a -r→ a₀ -r→ a₁ -r→ ... -r→ aₙ`.
-/
@[simps! length]
def cons (p : RelSeries r) (newHead : α) (rel : r newHead p.head) : RelSeries r 
goal: (p.cons newHead rel).length = p.length + 1

full_name: RelSeries.head_cons
code: @[simp] lemma head_cons (p : RelSeries r) (newHead : α) (rel : r newHead p.head) :
    (p.cons newHead rel).head = newHead 
goal: (p.cons newHead rel).head = newHead

full_name: RelSeries.last_cons
code: @[simp] lemma last_cons (p : RelSeries r) (newHead : α) (rel : r newHead p.head) :
    (p.cons newHead rel).last = p.last 
goal: (p.cons newHead rel).last = p.last

full_name: RelSeries.snoc_length
code: /--
Given a series `a₀ -r→ a₁ -r→ ... -r→ aₙ` and an `a` such that `aₙ -r→ a` holds, there is
a series of length `n+1`: `a₀ -r→ a₁ -r→ ... -r→ aₙ -r→ a`.
-/
@[simps! length]
def snoc (p : RelSeries r) (newLast : α) (rel : r p.last newLast) : RelSeries r 
goal: (p.snoc newLast rel).length = p.length + 1

full_name: RelSeries.snoc
code: /--
Given a series `a₀ -r→ a₁ -r→ ... -r→ aₙ` and an `a` such that `aₙ -r→ a` holds, there is
a series of length `n+1`: `a₀ -r→ a₁ -r→ ... -r→ aₙ -r→ a`.
-/
@[simps! length]
def snoc (p : RelSeries r) (newLast : α) (rel : r p.last newLast) : RelSeries r 
goal: RelSeries r

full_name: RelSeries.head_snoc
code: @[simp] lemma head_snoc (p : RelSeries r) (newLast : α) (rel : r p.last newLast) :
    (p.snoc newLast rel).head = p.head 
goal: (p.snoc newLast rel).head = p.head

full_name: RelSeries.last_snoc
code: @[simp] lemma last_snoc (p : RelSeries r) (newLast : α) (rel : r p.last newLast) :
    (p.snoc newLast rel).last = newLast 
goal: (p.snoc newLast rel).last = newLast

full_name: RelSeries.last_snoc'
code: @[simp] lemma last_snoc' (p : RelSeries r) (newLast : α) (rel : r p.last newLast) :
    p.snoc newLast rel (Fin.last (p.length + 1)) = newLast 
goal: (p.snoc newLast rel).toFun (Fin.last (p.length + 1)) = newLast

full_name: RelSeries.snoc_castSucc
code: @[simp] lemma snoc_castSucc (s : RelSeries r) (a : α) (connect : r s.last a)
    (i : Fin (s.length + 1)) : snoc s a connect (Fin.castSucc i) = s i 
goal: (s.snoc a connect).toFun i.castSucc = s.toFun i

full_name: RelSeries.mem_snoc
code: lemma mem_snoc {p : RelSeries r} {newLast : α} {rel : r p.last newLast} {x : α} :
    x ∈ p.snoc newLast rel ↔ x ∈ p ∨ x = newLast 
goal: x ∈ p.snoc newLast rel ↔ x ∈ p ∨ x = newLast

full_name: RelSeries.tail_length
code: /--
If a series `a₀ -r→ a₁ -r→ ...` has positive length, then `a₁ -r→ ...` is another series
-/
@[simps]
def tail (p : RelSeries r) (len_pos : p.length ≠ 0) : RelSeries r 
goal: (p.tail len_pos).length = p.length - 1

full_name: RelSeries.tail
code: /--
If a series `a₀ -r→ a₁ -r→ ...` has positive length, then `a₁ -r→ ...` is another series
-/
@[simps]
def tail (p : RelSeries r) (len_pos : p.length ≠ 0) : RelSeries r 
goal: RelSeries r

full_name: RelSeries.tail_toFun
code: /--
If a series `a₀ -r→ a₁ -r→ ...` has positive length, then `a₁ -r→ ...` is another series
-/
@[simps]
def tail (p : RelSeries r) (len_pos : p.length ≠ 0) : RelSeries r 
goal: ∀ (a : Fin (p.length - 1 + 1)), (p.tail len_pos).toFun a = (Fin.tail p.toFun ∘ Fin.cast ⋯) a

full_name: RelSeries.head_tail
code: @[simp] lemma head_tail (p : RelSeries r) (len_pos : p.length ≠ 0) :
    (p.tail len_pos).head = p 1 
goal: (p.tail len_pos).head = p.toFun 1

full_name: RelSeries.last_tail
code: @[simp] lemma last_tail (p : RelSeries r) (len_pos : p.length ≠ 0) :
    (p.tail len_pos).last = p.last 
goal: (p.tail len_pos).last = p.last

full_name: RelSeries.eraseLast_length
code: /--
If a series ``a₀ -r→ a₁ -r→ ... -r→ aₙ``, then `a₀ -r→ a₁ -r→ ... -r→ aₙ₋₁` is
another series -/
@[simps]
def eraseLast (p : RelSeries r) : RelSeries r 
goal: p.eraseLast.length = p.length - 1

full_name: RelSeries.eraseLast_toFun
code: /--
If a series ``a₀ -r→ a₁ -r→ ... -r→ aₙ``, then `a₀ -r→ a₁ -r→ ... -r→ aₙ₋₁` is
another series -/
@[simps]
def eraseLast (p : RelSeries r) : RelSeries r 
goal: p.eraseLast.toFun i = p.toFun ⟨↑i, ⋯⟩

full_name: RelSeries.eraseLast
code: /--
If a series ``a₀ -r→ a₁ -r→ ... -r→ aₙ``, then `a₀ -r→ a₁ -r→ ... -r→ aₙ₋₁` is
another series -/
@[simps]
def eraseLast (p : RelSeries r) : RelSeries r 
goal: RelSeries r

full_name: RelSeries.head_eraseLast
code: @[simp] lemma head_eraseLast (p : RelSeries r) : p.eraseLast.head = p.head 
goal: p.eraseLast.head = p.head

full_name: RelSeries.last_eraseLast
code: @[simp] lemma last_eraseLast (p : RelSeries r) :
    p.eraseLast.last = p ⟨p.length.pred, Nat.lt_succ_iff.2 (Nat.pred_le _)⟩ 
goal: p.eraseLast.last = p.toFun ⟨p.length.pred, ⋯⟩

full_name: RelSeries.smash_length
code: /--
Given two series of the form `a₀ -r→ ... -r→ X` and `X -r→ b ---> ...`,
then `a₀ -r→ ... -r→ X -r→ b ...` is another series obtained by combining the given two.
-/
@[simps]
def smash (p q : RelSeries r) (connect : p.last = q.head) : RelSeries r 
goal: (p.smash q connect).length = p.length + q.length

full_name: RelSeries.smash_toFun
code: /--
Given two series of the form `a₀ -r→ ... -r→ X` and `X -r→ b ---> ...`,
then `a₀ -r→ ... -r→ X -r→ b ...` is another series obtained by combining the given two.
-/
@[simps]
def smash (p q : RelSeries r) (connect : p.last = q.head) : RelSeries r 
goal: (p.smash q connect).toFun i = if H : ↑i < p.length then p.toFun ⟨↑i, ⋯⟩ else q.toFun ⟨↑i - p.length, ⋯⟩

full_name: RelSeries.smash
code: /--
Given two series of the form `a₀ -r→ ... -r→ X` and `X -r→ b ---> ...`,
then `a₀ -r→ ... -r→ X -r→ b ...` is another series obtained by combining the given two.
-/
@[simps]
def smash (p q : RelSeries r) (connect : p.last = q.head) : RelSeries r 
goal: RelSeries r

full_name: RelSeries.smash_castAdd
code: lemma smash_castAdd {p q : RelSeries r} (connect : p.last = q.head) (i : Fin p.length) :
    p.smash q connect (Fin.castSucc <| i.castAdd q.length) = p (Fin.castSucc i) 
goal: (p.smash q connect).toFun (Fin.castAdd q.length i).castSucc = p.toFun i.castSucc

full_name: RelSeries.smash_succ_castAdd
code: lemma smash_succ_castAdd {p q : RelSeries r} (h : p.last = q.head)
    (i : Fin p.length) : p.smash q h (i.castAdd q.length).succ = p i.succ 
goal: (p.smash q h).toFun (Fin.castAdd q.length i).succ = p.toFun i.succ

full_name: RelSeries.smash_natAdd
code: lemma smash_natAdd {p q : RelSeries r} (h : p.last = q.head) (i : Fin q.length) :
    smash p q h (Fin.castSucc <| i.natAdd p.length) = q (Fin.castSucc i) 
goal: (p.smash q h).toFun (Fin.natAdd p.length i).castSucc = q.toFun i.castSucc

full_name: RelSeries.smash_succ_natAdd
code: lemma smash_succ_natAdd {p q : RelSeries r} (h : p.last = q.head) (i : Fin q.length) :
    smash p q h (i.natAdd p.length).succ = q i.succ 
goal: (p.smash q h).toFun (Fin.natAdd p.length i).succ = q.toFun i.succ

full_name: RelSeries.head_smash
code: @[simp] lemma head_smash {p q : RelSeries r} (h : p.last = q.head) :
    (smash p q h).head = p.head 
goal: (p.smash q h).head = p.head

full_name: RelSeries.last_smash
code: @[simp] lemma last_smash {p q : RelSeries r} (h : p.last = q.head) :
    (smash p q h).last = q.last 
goal: (p.smash q h).last = q.last

full_name: FiniteDimensionalOrder
code: /-- A type is finite dimensional if its `LTSeries` has bounded length. -/
abbrev FiniteDimensionalOrder (γ : Type*) [Preorder γ] 
goal: Prop

full_name: FiniteDimensionalOrder.ofUnique
code: instance FiniteDimensionalOrder.ofUnique (γ : Type*) [Preorder γ] [Unique γ] :
    FiniteDimensionalOrder γ 
goal: FiniteDimensionalOrder γ

full_name: InfiniteDimensionalOrder
code: /-- A type is infinite dimensional if it has `LTSeries` of at least arbitrary length -/
abbrev InfiniteDimensionalOrder (γ : Type*) [Preorder γ] 
goal: Prop

full_name: LTSeries
code: /--
If `α` is a preorder, a LTSeries is a relation series of the less than relation.
-/
abbrev LTSeries 
goal: Type u_1

full_name: LTSeries.longestOf
code: /-- The longest `<`-series when a type is finite dimensional -/
protected noncomputable def longestOf [FiniteDimensionalOrder α] : LTSeries α 
goal: LTSeries α

full_name: LTSeries.withLength
code: /-- A `<`-series with length `n` if the relation is infinite dimensional -/
protected noncomputable def withLength [InfiniteDimensionalOrder α] (n : ℕ) : LTSeries α 
goal: LTSeries α

full_name: LTSeries.length_withLength
code: @[simp] lemma length_withLength [InfiniteDimensionalOrder α] (n : ℕ) :
    (LTSeries.withLength α n).length = n 
goal: (LTSeries.withLength α n).length = n

full_name: LTSeries.nonempty_of_infiniteDimensionalType
code: /-- if `α` is infinite dimensional, then `α` is nonempty. -/
lemma nonempty_of_infiniteDimensionalType [InfiniteDimensionalOrder α] : Nonempty α 
goal: Nonempty α

full_name: LTSeries.longestOf_is_longest
code: lemma longestOf_is_longest [FiniteDimensionalOrder α] (x : LTSeries α) :
    x.length ≤ (LTSeries.longestOf α).length 
goal: x.length ≤ (LTSeries.longestOf α).length

full_name: LTSeries.longestOf_len_unique
code: lemma longestOf_len_unique [FiniteDimensionalOrder α] (p : LTSeries α)
    (is_longest : ∀ (q : LTSeries α), q.length ≤ p.length) :
    p.length = (LTSeries.longestOf α).length 
goal: p.length = (LTSeries.longestOf α).length

full_name: LTSeries.strictMono
code: lemma strictMono (x : LTSeries α) : StrictMono x 
goal: StrictMono x.toFun

full_name: LTSeries.monotone
code: lemma monotone (x : LTSeries α) : Monotone x 
goal: Monotone x.toFun

full_name: LTSeries.mk_toFun
code: /-- An alternative constructor of `LTSeries` from a strictly monotone function. -/
@[simps]
def mk (length : ℕ) (toFun : Fin (length + 1) → α) (strictMono : StrictMono toFun) :
    LTSeries α 
goal: ∀ (a : Fin (length + 1)), (LTSeries.mk length toFun strictMono).toFun a = toFun a

full_name: LTSeries.mk_length
code: /-- An alternative constructor of `LTSeries` from a strictly monotone function. -/
@[simps]
def mk (length : ℕ) (toFun : Fin (length + 1) → α) (strictMono : StrictMono toFun) :
    LTSeries α 
goal: (LTSeries.mk length toFun strictMono).length = length

full_name: LTSeries.mk
code: /-- An alternative constructor of `LTSeries` from a strictly monotone function. -/
@[simps]
def mk (length : ℕ) (toFun : Fin (length + 1) → α) (strictMono : StrictMono toFun) :
    LTSeries α 
goal: LTSeries α

full_name: LTSeries.map
code: /--
For two preorders `α, β`, if `f : α → β` is strictly monotonic, then a strict chain of `α`
can be pushed out to a strict chain of `β` by
`a₀ < a₁ < ... < aₙ ↦ f a₀ < f a₁ < ... < f aₙ`
-/
@[simps!]
def map (p : LTSeries α) (f : α → β) (hf : StrictMono f) : LTSeries β 
goal: LTSeries β

full_name: LTSeries.map_toFun
code: /--
For two preorders `α, β`, if `f : α → β` is strictly monotonic, then a strict chain of `α`
can be pushed out to a strict chain of `β` by
`a₀ < a₁ < ... < aₙ ↦ f a₀ < f a₁ < ... < f aₙ`
-/
@[simps!]
def map (p : LTSeries α) (f : α → β) (hf : StrictMono f) : LTSeries β 
goal: ∀ (a : Fin (p.length + 1)), (p.map f hf).toFun a = f (p.toFun a)

full_name: LTSeries.map_length
code: /--
For two preorders `α, β`, if `f : α → β` is strictly monotonic, then a strict chain of `α`
can be pushed out to a strict chain of `β` by
`a₀ < a₁ < ... < aₙ ↦ f a₀ < f a₁ < ... < f aₙ`
-/
@[simps!]
def map (p : LTSeries α) (f : α → β) (hf : StrictMono f) : LTSeries β 
goal: (p.map f hf).length = p.length

full_name: LTSeries.comap
code: /--
For two preorders `α, β`, if `f : α → β` is surjective and strictly comonotonic, then a
strict series of `β` can be pulled back to a strict chain of `α` by
`b₀ < b₁ < ... < bₙ ↦ f⁻¹ b₀ < f⁻¹ b₁ < ... < f⁻¹ bₙ` where `f⁻¹ bᵢ` is an arbitrary element in the
preimage of `f⁻¹ {bᵢ}`.
-/
@[simps!]
noncomputable def comap (p : LTSeries β) (f : α → β)
  (comap : ∀ ⦃x y⦄, f x < f y → x < y)
  (surjective : Function.Surjective f) :
  LTSeries α 
goal: LTSeries α

full_name: LTSeries.comap_toFun
code: /--
For two preorders `α, β`, if `f : α → β` is surjective and strictly comonotonic, then a
strict series of `β` can be pulled back to a strict chain of `α` by
`b₀ < b₁ < ... < bₙ ↦ f⁻¹ b₀ < f⁻¹ b₁ < ... < f⁻¹ bₙ` where `f⁻¹ bᵢ` is an arbitrary element in the
preimage of `f⁻¹ {bᵢ}`.
-/
@[simps!]
noncomputable def comap (p : LTSeries β) (f : α → β)
  (comap : ∀ ⦃x y⦄, f x < f y → x < y)
  (surjective : Function.Surjective f) :
  LTSeries α 
goal: (p.comap f comap surjective).toFun i = ⋯.choose

full_name: LTSeries.comap_length
code: /--
For two preorders `α, β`, if `f : α → β` is surjective and strictly comonotonic, then a
strict series of `β` can be pulled back to a strict chain of `α` by
`b₀ < b₁ < ... < bₙ ↦ f⁻¹ b₀ < f⁻¹ b₁ < ... < f⁻¹ bₙ` where `f⁻¹ bᵢ` is an arbitrary element in the
preimage of `f⁻¹ {bᵢ}`.
-/
@[simps!]
noncomputable def comap (p : LTSeries β) (f : α → β)
  (comap : ∀ ⦃x y⦄, f x < f y → x < y)
  (surjective : Function.Surjective f) :
  LTSeries α 
goal: (p.comap f comap surjective).length = p.length

full_name: infiniteDimensionalOrder_of_strictMono
code: /-- If `f : α → β` is a strictly monotonic function and `α` is an infinite dimensional type then so
  is `β`. -/
lemma infiniteDimensionalOrder_of_strictMono [Preorder α] [Preorder β]
    (f : α → β) (hf : StrictMono f) [InfiniteDimensionalOrder α] :
    InfiniteDimensionalOrder β 
goal: InfiniteDimensionalOrder β