l3lab/ntp-mathlib huggingface dataset:
/-- Taking only the first `i+1` elements in a list, and then dropping the first `i` ones, one is
left with a list of length `1` made of the `i`-th element of the original list. -/
theorem drop_take_succ_eq_cons_get (L : List α) (i : Fin L.length) :
    (L.take (i + 1)).drop i = [get L i] := by
  

Proof state:
α : Type u_1
β : Type u_2
L : List α
i : Fin (length L)
⊢ drop (↑i) (take (↑i + 1) L) = [get L i]

Next tactic:
induction' L with head tail ih
/-- Taking only the first `i+1` elements in a list, and then dropping the first `i` ones, one is
left with a list of length `1` made of the `i`-th element of the original list. -/
theorem drop_take_succ_eq_cons_get (L : List α) (i : Fin L.length) :
    (L.take (i + 1)).drop i = [get L i] := by
  induction' L with head tail ih
  · 

Proof state:
case nil
α : Type u_1
β : Type u_2
i : Fin (length [])
⊢ drop (↑i) (take (↑i + 1) []) = [get [] i]

Next tactic:
exact (Nat.not_succ_le_zero i i.isLt).elim
/-- Taking only the first `i+1` elements in a list, and then dropping the first `i` ones, one is
left with a list of length `1` made of the `i`-th element of the original list. -/
theorem drop_take_succ_eq_cons_get (L : List α) (i : Fin L.length) :
    (L.take (i + 1)).drop i = [get L i] := by
  induction' L with head tail ih
  · exact (Nat.not_succ_le_zero i i.isLt).elim
  

Proof state:
case cons
α : Type u_1
β : Type u_2
head : α
tail : List α
ih : ∀ (i : Fin (length tail)), drop (↑i) (take (↑i + 1) tail) = [get tail i]
i : Fin (length (head :: tail))
⊢ drop (↑i) (take (↑i + 1) (head :: tail)) = [get (head :: tail) i]

Next tactic:
rcases i with ⟨_ | i, hi⟩
/-- Taking only the first `i+1` elements in a list, and then dropping the first `i` ones, one is
left with a list of length `1` made of the `i`-th element of the original list. -/
theorem drop_take_succ_eq_cons_get (L : List α) (i : Fin L.length) :
    (L.take (i + 1)).drop i = [get L i] := by
  induction' L with head tail ih
  · exact (Nat.not_succ_le_zero i i.isLt).elim
  rcases i with ⟨_ | i, hi⟩
  · 

Proof state:
case cons.mk.zero
α : Type u_1
β : Type u_2
head : α
tail : List α
ih : ∀ (i : Fin (length tail)), drop (↑i) (take (↑i + 1) tail) = [get tail i]
hi : Nat.zero < length (head :: tail)
⊢ drop (↑{ val := Nat.zero, isLt := hi }) (take (↑{ val := Nat.zero, isLt := hi } + 1) (head :: tail)) =
    [get (head :: tail) { val := Nat.zero, isLt := hi }]

Next tactic:
simp
/-- Taking only the first `i+1` elements in a list, and then dropping the first `i` ones, one is
left with a list of length `1` made of the `i`-th element of the original list. -/
theorem drop_take_succ_eq_cons_get (L : List α) (i : Fin L.length) :
    (L.take (i + 1)).drop i = [get L i] := by
  induction' L with head tail ih
  · exact (Nat.not_succ_le_zero i i.isLt).elim
  rcases i with ⟨_ | i, hi⟩
  · simp
  · 

Proof state:
case cons.mk.succ
α : Type u_1
β : Type u_2
head : α
tail : List α
ih : ∀ (i : Fin (length tail)), drop (↑i) (take (↑i + 1) tail) = [get tail i]
i : ℕ
hi : Nat.succ i < length (head :: tail)
⊢ drop (↑{ val := Nat.succ i, isLt := hi }) (take (↑{ val := Nat.succ i, isLt := hi } + 1) (head :: tail)) =
    [get (head :: tail) { val := Nat.succ i, isLt := hi }]

Next tactic:
simpa using ih ⟨i, Nat.lt_of_succ_lt_succ hi⟩
set_option linter.deprecated false in
/-- Taking only the first `i+1` elements in a list, and then dropping the first `i` ones, one is
left with a list of length `1` made of the `i`-th element of the original list. -/
@[deprecated drop_take_succ_eq_cons_get]
theorem drop_take_succ_eq_cons_nthLe (L : List α) {i : ℕ} (hi : i < L.length) :
    (L.take (i + 1)).drop i = [nthLe L i hi] := by
  

Proof state:
α : Type u_1
β : Type u_2
L : List α
i : ℕ
hi : i < length L
⊢ drop i (take (i + 1) L) = [nthLe L i hi]

Next tactic:
induction' L with head tail generalizing i
set_option linter.deprecated false in
/-- Taking only the first `i+1` elements in a list, and then dropping the first `i` ones, one is
left with a list of length `1` made of the `i`-th element of the original list. -/
@[deprecated drop_take_succ_eq_cons_get]
theorem drop_take_succ_eq_cons_nthLe (L : List α) {i : ℕ} (hi : i < L.length) :
    (L.take (i + 1)).drop i = [nthLe L i hi] := by
  induction' L with head tail generalizing i
  · 

Proof state:
case nil
α : Type u_1
β : Type u_2
i : ℕ
hi : i < length []
⊢ drop i (take (i + 1) []) = [nthLe [] i hi]

Next tactic:
simp only [length] at hi
set_option linter.deprecated false in
/-- Taking only the first `i+1` elements in a list, and then dropping the first `i` ones, one is
left with a list of length `1` made of the `i`-th element of the original list. -/
@[deprecated drop_take_succ_eq_cons_get]
theorem drop_take_succ_eq_cons_nthLe (L : List α) {i : ℕ} (hi : i < L.length) :
    (L.take (i + 1)).drop i = [nthLe L i hi] := by
  induction' L with head tail generalizing i
  · simp only [length] at hi
    

Proof state:
case nil
α : Type u_1
β : Type u_2
i : ℕ
hi : i < 0
⊢ drop i (take (i + 1) []) = [nthLe [] i hi]

Next tactic:
exact (Nat.not_succ_le_zero i hi).elim
set_option linter.deprecated false in
/-- Taking only the first `i+1` elements in a list, and then dropping the first `i` ones, one is
left with a list of length `1` made of the `i`-th element of the original list. -/
@[deprecated drop_take_succ_eq_cons_get]
theorem drop_take_succ_eq_cons_nthLe (L : List α) {i : ℕ} (hi : i < L.length) :
    (L.take (i + 1)).drop i = [nthLe L i hi] := by
  induction' L with head tail generalizing i
  · simp only [length] at hi
    exact (Nat.not_succ_le_zero i hi).elim
  

Proof state:
case cons
α : Type u_1
β : Type u_2
head : α
tail : List α
tail_ih✝ : ∀ {i : ℕ} (hi : i < length tail), drop i (take (i + 1) tail) = [nthLe tail i hi]
i : ℕ
hi : i < length (head :: tail)
⊢ drop i (take (i + 1) (head :: tail)) = [nthLe (head :: tail) i hi]

Next tactic:
cases' i with i hi
set_option linter.deprecated false in
/-- Taking only the first `i+1` elements in a list, and then dropping the first `i` ones, one is
left with a list of length `1` made of the `i`-th element of the original list. -/
@[deprecated drop_take_succ_eq_cons_get]
theorem drop_take_succ_eq_cons_nthLe (L : List α) {i : ℕ} (hi : i < L.length) :
    (L.take (i + 1)).drop i = [nthLe L i hi] := by
  induction' L with head tail generalizing i
  · simp only [length] at hi
    exact (Nat.not_succ_le_zero i hi).elim
  cases' i with i hi
  · 

Proof state:
case cons.zero
α : Type u_1
β : Type u_2
head : α
tail : List α
tail_ih✝ : ∀ {i : ℕ} (hi : i < length tail), drop i (take (i + 1) tail) = [nthLe tail i hi]
hi : Nat.zero < length (head :: tail)
⊢ drop Nat.zero (take (Nat.zero + 1) (head :: tail)) = [nthLe (head :: tail) Nat.zero hi]

Next tactic:
simp
set_option linter.deprecated false in
/-- Taking only the first `i+1` elements in a list, and then dropping the first `i` ones, one is
left with a list of length `1` made of the `i`-th element of the original list. -/
@[deprecated drop_take_succ_eq_cons_get]
theorem drop_take_succ_eq_cons_nthLe (L : List α) {i : ℕ} (hi : i < L.length) :
    (L.take (i + 1)).drop i = [nthLe L i hi] := by
  induction' L with head tail generalizing i
  · simp only [length] at hi
    exact (Nat.not_succ_le_zero i hi).elim
  cases' i with i hi
  · simp
    

Proof state:
case cons.zero
α : Type u_1
β : Type u_2
head : α
tail : List α
tail_ih✝ : ∀ {i : ℕ} (hi : i < length tail), drop i (take (i + 1) tail) = [nthLe tail i hi]
hi : Nat.zero < length (head :: tail)
⊢ head = nthLe (head :: tail) 0 hi

Next tactic:
rfl
set_option linter.deprecated false in
/-- Taking only the first `i+1` elements in a list, and then dropping the first `i` ones, one is
left with a list of length `1` made of the `i`-th element of the original list. -/
@[deprecated drop_take_succ_eq_cons_get]
theorem drop_take_succ_eq_cons_nthLe (L : List α) {i : ℕ} (hi : i < L.length) :
    (L.take (i + 1)).drop i = [nthLe L i hi] := by
  induction' L with head tail generalizing i
  · simp only [length] at hi
    exact (Nat.not_succ_le_zero i hi).elim
  cases' i with i hi
  · simp
    rfl
  

Proof state:
case cons.succ
α : Type u_1
β : Type u_2
head : α
tail : List α
tail_ih✝ : ∀ {i : ℕ} (hi : i < length tail), drop i (take (i + 1) tail) = [nthLe tail i hi]
i : ℕ
hi : Nat.succ i < length (head :: tail)
⊢ drop (Nat.succ i) (take (Nat.succ i + 1) (head :: tail)) = [nthLe (head :: tail) (Nat.succ i) hi]

Next tactic:
have : i < tail.length := by
    simp? at hi says simp only [length_cons] at hi
    exact Nat.lt_of_succ_lt_succ hi
set_option linter.deprecated false in
/-- Taking only the first `i+1` elements in a list, and then dropping the first `i` ones, one is
left with a list of length `1` made of the `i`-th element of the original list. -/
@[deprecated drop_take_succ_eq_cons_get]
theorem drop_take_succ_eq_cons_nthLe (L : List α) {i : ℕ} (hi : i < L.length) :
    (L.take (i + 1)).drop i = [nthLe L i hi] := by
  induction' L with head tail generalizing i
  · simp only [length] at hi
    exact (Nat.not_succ_le_zero i hi).elim
  cases' i with i hi
  · simp
    rfl
  have : i < tail.length := by
    

Proof state:
α : Type u_1
β : Type u_2
head : α
tail : List α
tail_ih✝ : ∀ {i : ℕ} (hi : i < length tail), drop i (take (i + 1) tail) = [nthLe tail i hi]
i : ℕ
hi : Nat.succ i < length (head :: tail)
⊢ i < length tail

Next tactic:
simp? at hi says simp only [length_cons] at hi
set_option linter.deprecated false in
/-- Taking only the first `i+1` elements in a list, and then dropping the first `i` ones, one is
left with a list of length `1` made of the `i`-th element of the original list. -/
@[deprecated drop_take_succ_eq_cons_get]
theorem drop_take_succ_eq_cons_nthLe (L : List α) {i : ℕ} (hi : i < L.length) :
    (L.take (i + 1)).drop i = [nthLe L i hi] := by
  induction' L with head tail generalizing i
  · simp only [length] at hi
    exact (Nat.not_succ_le_zero i hi).elim
  cases' i with i hi
  · simp
    rfl
  have : i < tail.length := by
    simp? at hi says 

Proof state:
α : Type u_1
β : Type u_2
head : α
tail : List α
tail_ih✝ : ∀ {i : ℕ} (hi : i < length tail), drop i (take (i + 1) tail) = [nthLe tail i hi]
i : ℕ
hi : Nat.succ i < length (head :: tail)
⊢ i < length tail

Next tactic:
simp only [length_cons] at hi
set_option linter.deprecated false in
/-- Taking only the first `i+1` elements in a list, and then dropping the first `i` ones, one is
left with a list of length `1` made of the `i`-th element of the original list. -/
@[deprecated drop_take_succ_eq_cons_get]
theorem drop_take_succ_eq_cons_nthLe (L : List α) {i : ℕ} (hi : i < L.length) :
    (L.take (i + 1)).drop i = [nthLe L i hi] := by
  induction' L with head tail generalizing i
  · simp only [length] at hi
    exact (Nat.not_succ_le_zero i hi).elim
  cases' i with i hi
  · simp
    rfl
  have : i < tail.length := by
    simp? at hi says simp only [length_cons] at hi
    

Proof state:
α : Type u_1
β : Type u_2
head : α
tail : List α
tail_ih✝ : ∀ {i : ℕ} (hi : i < length tail), drop i (take (i + 1) tail) = [nthLe tail i hi]
i : ℕ
hi : Nat.succ i < Nat.succ (length tail)
⊢ i < length tail

Next tactic:
exact Nat.lt_of_succ_lt_succ hi
set_option linter.deprecated false in
/-- Taking only the first `i+1` elements in a list, and then dropping the first `i` ones, one is
left with a list of length `1` made of the `i`-th element of the original list. -/
@[deprecated drop_take_succ_eq_cons_get]
theorem drop_take_succ_eq_cons_nthLe (L : List α) {i : ℕ} (hi : i < L.length) :
    (L.take (i + 1)).drop i = [nthLe L i hi] := by
  induction' L with head tail generalizing i
  · simp only [length] at hi
    exact (Nat.not_succ_le_zero i hi).elim
  cases' i with i hi
  · simp
    rfl
  have : i < tail.length := by
    simp? at hi says simp only [length_cons] at hi
    exact Nat.lt_of_succ_lt_succ hi
  

Proof state:
case cons.succ
α : Type u_1
β : Type u_2
head : α
tail : List α
tail_ih✝ : ∀ {i : ℕ} (hi : i < length tail), drop i (take (i + 1) tail) = [nthLe tail i hi]
i : ℕ
hi : Nat.succ i < length (head :: tail)
this : i < length tail
⊢ drop (Nat.succ i) (take (Nat.succ i + 1) (head :: tail)) = [nthLe (head :: tail) (Nat.succ i) hi]

Next tactic:
simp [*]
set_option linter.deprecated false in
/-- Taking only the first `i+1` elements in a list, and then dropping the first `i` ones, one is
left with a list of length `1` made of the `i`-th element of the original list. -/
@[deprecated drop_take_succ_eq_cons_get]
theorem drop_take_succ_eq_cons_nthLe (L : List α) {i : ℕ} (hi : i < L.length) :
    (L.take (i + 1)).drop i = [nthLe L i hi] := by
  induction' L with head tail generalizing i
  · simp only [length] at hi
    exact (Nat.not_succ_le_zero i hi).elim
  cases' i with i hi
  · simp
    rfl
  have : i < tail.length := by
    simp? at hi says simp only [length_cons] at hi
    exact Nat.lt_of_succ_lt_succ hi
  simp [*]
  

Proof state:
case cons.succ
α : Type u_1
β : Type u_2
head : α
tail : List α
tail_ih✝ : ∀ {i : ℕ} (hi : i < length tail), drop i (take (i + 1) tail) = [nthLe tail i hi]
i : ℕ
hi : Nat.succ i < length (head :: tail)
this : i < length tail
⊢ nthLe tail i (_ : i < length tail) = nthLe (head :: tail) (Nat.succ i) hi

Next tactic:
rfl
/-- In a join of sublists, taking the slice between the indices `A` and `B - 1` gives back the
original sublist of index `i` if `A` is the sum of the lengths of sublists of index `< i`, and
`B` is the sum of the lengths of sublists of index `≤ i`. -/
theorem drop_take_succ_join_eq_get (L : List (List α)) (i : Fin L.length) :
    (L.join.take ((L.map length).take (i + 1)).sum).drop ((L.map length).take i).sum =
      get L i := by
  

Proof state:
α : Type u_1
β : Type u_2
L : List (List α)
i : Fin (length L)
⊢ drop (sum (take (↑i) (map length L))) (take (sum (take (↑i + 1) (map length L))) (join L)) = get L i

Next tactic:
have : (L.map length).take i = ((L.take (i + 1)).map length).take i := by
    simp [map_take, take_take]
/-- In a join of sublists, taking the slice between the indices `A` and `B - 1` gives back the
original sublist of index `i` if `A` is the sum of the lengths of sublists of index `< i`, and
`B` is the sum of the lengths of sublists of index `≤ i`. -/
theorem drop_take_succ_join_eq_get (L : List (List α)) (i : Fin L.length) :
    (L.join.take ((L.map length).take (i + 1)).sum).drop ((L.map length).take i).sum =
      get L i := by
  have : (L.map length).take i = ((L.take (i + 1)).map length).take i := by
    

Proof state:
α : Type u_1
β : Type u_2
L : List (List α)
i : Fin (length L)
⊢ take (↑i) (map length L) = take (↑i) (map length (take (↑i + 1) L))

Next tactic:
simp [map_take, take_take]
/-- In a join of sublists, taking the slice between the indices `A` and `B - 1` gives back the
original sublist of index `i` if `A` is the sum of the lengths of sublists of index `< i`, and
`B` is the sum of the lengths of sublists of index `≤ i`. -/
theorem drop_take_succ_join_eq_get (L : List (List α)) (i : Fin L.length) :
    (L.join.take ((L.map length).take (i + 1)).sum).drop ((L.map length).take i).sum =
      get L i := by
  have : (L.map length).take i = ((L.take (i + 1)).map length).take i := by
    simp [map_take, take_take]
  

Proof state:
α : Type u_1
β : Type u_2
L : List (List α)
i : Fin (length L)
this : take (↑i) (map length L) = take (↑i) (map length (take (↑i + 1) L))
⊢ drop (sum (take (↑i) (map length L))) (take (sum (take (↑i + 1) (map length L))) (join L)) = get L i

Next tactic:
simp only [this, length_map, take_sum_join, drop_sum_join, drop_take_succ_eq_cons_get,
    join, append_nil]
set_option linter.deprecated false in
/-- In a join of sublists, taking the slice between the indices `A` and `B - 1` gives back the
original sublist of index `i` if `A` is the sum of the lengths of sublists of index `< i`, and
`B` is the sum of the lengths of sublists of index `≤ i`. -/
@[deprecated drop_take_succ_join_eq_get]
theorem drop_take_succ_join_eq_nthLe (L : List (List α)) {i : ℕ} (hi : i < L.length) :
    (L.join.take ((L.map length).take (i + 1)).sum).drop ((L.map length).take i).sum =
      nthLe L i hi := by
  

Proof state:
α : Type u_1
β : Type u_2
L : List (List α)
i : ℕ
hi : i < length L
⊢ drop (sum (take i (map length L))) (take (sum (take (i + 1) (map length L))) (join L)) = nthLe L i hi

Next tactic:
have : (L.map length).take i = ((L.take (i + 1)).map length).take i := by
    simp [map_take, take_take]
set_option linter.deprecated false in
/-- In a join of sublists, taking the slice between the indices `A` and `B - 1` gives back the
original sublist of index `i` if `A` is the sum of the lengths of sublists of index `< i`, and
`B` is the sum of the lengths of sublists of index `≤ i`. -/
@[deprecated drop_take_succ_join_eq_get]
theorem drop_take_succ_join_eq_nthLe (L : List (List α)) {i : ℕ} (hi : i < L.length) :
    (L.join.take ((L.map length).take (i + 1)).sum).drop ((L.map length).take i).sum =
      nthLe L i hi := by
  have : (L.map length).take i = ((L.take (i + 1)).map length).take i := by
    

Proof state:
α : Type u_1
β : Type u_2
L : List (List α)
i : ℕ
hi : i < length L
⊢ take i (map length L) = take i (map length (take (i + 1) L))

Next tactic:
simp [map_take, take_take]
set_option linter.deprecated false in
/-- In a join of sublists, taking the slice between the indices `A` and `B - 1` gives back the
original sublist of index `i` if `A` is the sum of the lengths of sublists of index `< i`, and
`B` is the sum of the lengths of sublists of index `≤ i`. -/
@[deprecated drop_take_succ_join_eq_get]
theorem drop_take_succ_join_eq_nthLe (L : List (List α)) {i : ℕ} (hi : i < L.length) :
    (L.join.take ((L.map length).take (i + 1)).sum).drop ((L.map length).take i).sum =
      nthLe L i hi := by
  have : (L.map length).take i = ((L.take (i + 1)).map length).take i := by
    simp [map_take, take_take]
  

Proof state:
α : Type u_1
β : Type u_2
L : List (List α)
i : ℕ
hi : i < length L
this : take i (map length L) = take i (map length (take (i + 1) L))
⊢ drop (sum (take i (map length L))) (take (sum (take (i + 1) (map length L))) (join L)) = nthLe L i hi

Next tactic:
simp [take_sum_join, this, drop_sum_join, drop_take_succ_eq_cons_nthLe _ hi]
/-- Auxiliary lemma to control elements in a join. -/
@[deprecated]
theorem sum_take_map_length_lt1 (L : List (List α)) {i j : ℕ} (hi : i < L.length)
    (hj : j < (L.get ⟨i, hi⟩).length) :
    ((L.map length).take i).sum + j < ((L.map length).take (i + 1)).sum := by
  

Proof state:
α : Type u_1
β : Type u_2
L : List (List α)
i j : ℕ
hi : i < length L
hj : j < length (get L { val := i, isLt := hi })
⊢ sum (take i (map length L)) + j < sum (take (i + 1) (map length L))

Next tactic:
simp [hi, sum_take_succ, hj]
set_option linter.deprecated false in
/-- Auxiliary lemma to control elements in a join. -/
@[deprecated]
theorem sum_take_map_length_lt2 (L : List (List α)) {i j : ℕ} (hi : i < L.length)
    (hj : j < (nthLe L i hi).length) : ((L.map length).take i).sum + j < L.join.length := by
  

Proof state:
α : Type u_1
β : Type u_2
L : List (List α)
i j : ℕ
hi : i < length L
hj : j < length (nthLe L i hi)
⊢ sum (take i (map length L)) + j < length (join L)

Next tactic:
convert lt_of_lt_of_le (sum_take_map_length_lt1 L hi hj) (monotone_sum_take _ hi)
set_option linter.deprecated false in
/-- Auxiliary lemma to control elements in a join. -/
@[deprecated]
theorem sum_take_map_length_lt2 (L : List (List α)) {i j : ℕ} (hi : i < L.length)
    (hj : j < (nthLe L i hi).length) : ((L.map length).take i).sum + j < L.join.length := by
  convert lt_of_lt_of_le (sum_take_map_length_lt1 L hi hj) (monotone_sum_take _ hi)
  

Proof state:
case h.e'_4
α : Type u_1
β : Type u_2
L : List (List α)
i j : ℕ
hi : i < length L
hj : j < length (nthLe L i hi)
⊢ length (join L) = (fun i => sum (take i (map length L))) (length L)

Next tactic:
have : L.length = (L.map length).length := by simp
set_option linter.deprecated false in
/-- Auxiliary lemma to control elements in a join. -/
@[deprecated]
theorem sum_take_map_length_lt2 (L : List (List α)) {i j : ℕ} (hi : i < L.length)
    (hj : j < (nthLe L i hi).length) : ((L.map length).take i).sum + j < L.join.length := by
  convert lt_of_lt_of_le (sum_take_map_length_lt1 L hi hj) (monotone_sum_take _ hi)
  have : L.length = (L.map length).length := by 

Proof state:
α : Type u_1
β : Type u_2
L : List (List α)
i j : ℕ
hi : i < length L
hj : j < length (nthLe L i hi)
⊢ length L = length (map length L)

Next tactic:
simp
set_option linter.deprecated false in
/-- Auxiliary lemma to control elements in a join. -/
@[deprecated]
theorem sum_take_map_length_lt2 (L : List (List α)) {i j : ℕ} (hi : i < L.length)
    (hj : j < (nthLe L i hi).length) : ((L.map length).take i).sum + j < L.join.length := by
  convert lt_of_lt_of_le (sum_take_map_length_lt1 L hi hj) (monotone_sum_take _ hi)
  have : L.length = (L.map length).length := by simp
  

Proof state:
case h.e'_4
α : Type u_1
β : Type u_2
L : List (List α)
i j : ℕ
hi : i < length L
hj : j < length (nthLe L i hi)
this : length L = length (map length L)
⊢ length (join L) = (fun i => sum (take i (map length L))) (length L)

Next tactic:
simp [this, -length_map]
set_option linter.deprecated false in
/-- The `n`-th element in a join of sublists is the `j`-th element of the `i`th sublist,
where `n` can be obtained in terms of `i` and `j` by adding the lengths of all the sublists
of index `< i`, and adding `j`. -/
@[deprecated]
theorem nthLe_join (L : List (List α)) {i j : ℕ} (hi : i < L.length)
    (hj : j < (nthLe L i hi).length) :
    nthLe L.join (((L.map length).take i).sum + j) (sum_take_map_length_lt2 L hi hj) =
      nthLe (nthLe L i hi) j hj := by
  

Proof state:
α : Type u_1
β : Type u_2
L : List (List α)
i j : ℕ
hi : i < length L
hj : j < length (nthLe L i hi)
⊢ nthLe (join L) (sum (take i (map length L)) + j) (_ : sum (take i (map length L)) + j < length (join L)) =
    nthLe (nthLe L i hi) j hj

Next tactic:
have := nthLe_take L.join (sum_take_map_length_lt2 L hi hj) (sum_take_map_length_lt1 L hi hj)
set_option linter.deprecated false in
/-- The `n`-th element in a join of sublists is the `j`-th element of the `i`th sublist,
where `n` can be obtained in terms of `i` and `j` by adding the lengths of all the sublists
of index `< i`, and adding `j`. -/
@[deprecated]
theorem nthLe_join (L : List (List α)) {i j : ℕ} (hi : i < L.length)
    (hj : j < (nthLe L i hi).length) :
    nthLe L.join (((L.map length).take i).sum + j) (sum_take_map_length_lt2 L hi hj) =
      nthLe (nthLe L i hi) j hj := by
  have := nthLe_take L.join (sum_take_map_length_lt2 L hi hj) (sum_take_map_length_lt1 L hi hj)
  

Proof state:
α : Type u_1
β : Type u_2
L : List (List α)
i j : ℕ
hi : i < length L
hj : j < length (nthLe L i hi)
this :
  nthLe (join L) (sum (take i (map length L)) + j) (_ : sum (take i (map length L)) + j < length (join L)) =
    nthLe (take (sum (take (i + 1) (map length L))) (join L)) (sum (take i (map length L)) + j)
      (_ : sum (take i (map length L)) + j < length (take (sum (take (i + 1) (map length L))) (join L)))
⊢ nthLe (join L) (sum (take i (map length L)) + j) (_ : sum (take i (map length L)) + j < length (join L)) =
    nthLe (nthLe L i hi) j hj

Next tactic:
rw [this, nthLe_drop, nthLe_of_eq (drop_take_succ_join_eq_nthLe L hi)]
/-- Two lists of sublists are equal iff their joins coincide, as well as the lengths of the
sublists. -/
theorem eq_iff_join_eq (L L' : List (List α)) :
    L = L' ↔ L.join = L'.join ∧ map length L = map length L' := by
  

Proof state:
α : Type u_1
β : Type u_2
L L' : List (List α)
⊢ L = L' ↔ join L = join L' ∧ map length L = map length L'

Next tactic:
refine' ⟨fun H => by simp [H], _⟩
/-- Two lists of sublists are equal iff their joins coincide, as well as the lengths of the
sublists. -/
theorem eq_iff_join_eq (L L' : List (List α)) :
    L = L' ↔ L.join = L'.join ∧ map length L = map length L' := by
  refine' ⟨fun H => by 

Proof state:
α : Type u_1
β : Type u_2
L L' : List (List α)
H : L = L'
⊢ join L = join L' ∧ map length L = map length L'

Next tactic:
simp [H]
/-- Two lists of sublists are equal iff their joins coincide, as well as the lengths of the
sublists. -/
theorem eq_iff_join_eq (L L' : List (List α)) :
    L = L' ↔ L.join = L'.join ∧ map length L = map length L' := by
  refine' ⟨fun H => by simp [H], _⟩
  

Proof state:
α : Type u_1
β : Type u_2
L L' : List (List α)
⊢ join L = join L' ∧ map length L = map length L' → L = L'

Next tactic:
rintro ⟨join_eq, length_eq⟩