l3lab/ntp-mathlib huggingface dataset:
/-- A `l : List α` is `Sublist l l'` for `l' : List α` iff
there is `f`, an order-preserving embedding of `Fin l.length` into `Fin l'.length` such that
any element of `l` found at index `ix` can be found at index `f ix` in `l'`.
-/
theorem sublist_iff_exists_fin_orderEmbedding_get_eq {l l' : List α} :
    l <+ l' ↔
      ∃ f : Fin l.length ↪o Fin l'.length,
        ∀ ix : Fin l.length, l.get ix = l'.get (f ix) := by
  rw [sublist_iff_exists_orderEmbedding_get?_eq]
  constructor
  · rintro ⟨f, hf⟩
    have h : ∀ {i : ℕ}, i < l.length → f i < l'.length := by
      intro i hi
      specialize hf i
      rw [get?_eq_get hi, eq_comm, get?_eq_some] at hf
      obtain ⟨h, -⟩ := hf
      exact h
    refine' ⟨OrderEmbedding.ofMapLEIff (fun ix => ⟨f ix, h ix.is_lt⟩) _, _⟩
    · simp
    · intro i
      

Proof state:
case mp.intro.refine'_2
α : Type u_1
l l' : List α
f : ℕ ↪o ℕ
hf : ∀ (ix : ℕ), get? l ix = get? l' (f ix)
h : ∀ {i : ℕ}, i < length l → f i < length l'
i : Fin (length l)
⊢ get l i =
    get l'
      ((OrderEmbedding.ofMapLEIff (fun ix => { val := f ↑ix, isLt := (_ : f ↑ix < length l') })
          (_ :
            ∀ (a a_1 : Fin (length l)),
              { val := f ↑a, isLt := (_ : f ↑a < length l') } ≤ { val := f ↑a_1, isLt := (_ : f ↑a_1 < length l') } ↔
                a ≤ a_1))
        i)

Next tactic:
apply Option.some_injective
/-- A `l : List α` is `Sublist l l'` for `l' : List α` iff
there is `f`, an order-preserving embedding of `Fin l.length` into `Fin l'.length` such that
any element of `l` found at index `ix` can be found at index `f ix` in `l'`.
-/
theorem sublist_iff_exists_fin_orderEmbedding_get_eq {l l' : List α} :
    l <+ l' ↔
      ∃ f : Fin l.length ↪o Fin l'.length,
        ∀ ix : Fin l.length, l.get ix = l'.get (f ix) := by
  rw [sublist_iff_exists_orderEmbedding_get?_eq]
  constructor
  · rintro ⟨f, hf⟩
    have h : ∀ {i : ℕ}, i < l.length → f i < l'.length := by
      intro i hi
      specialize hf i
      rw [get?_eq_get hi, eq_comm, get?_eq_some] at hf
      obtain ⟨h, -⟩ := hf
      exact h
    refine' ⟨OrderEmbedding.ofMapLEIff (fun ix => ⟨f ix, h ix.is_lt⟩) _, _⟩
    · simp
    · intro i
      apply Option.some_injective
      

Proof state:
case mp.intro.refine'_2.a
α : Type u_1
l l' : List α
f : ℕ ↪o ℕ
hf : ∀ (ix : ℕ), get? l ix = get? l' (f ix)
h : ∀ {i : ℕ}, i < length l → f i < length l'
i : Fin (length l)
⊢ some (get l i) =
    some
      (get l'
        ((OrderEmbedding.ofMapLEIff (fun ix => { val := f ↑ix, isLt := (_ : f ↑ix < length l') })
            (_ :
              ∀ (a a_1 : Fin (length l)),
                { val := f ↑a, isLt := (_ : f ↑a < length l') } ≤ { val := f ↑a_1, isLt := (_ : f ↑a_1 < length l') } ↔
                  a ≤ a_1))
          i))

Next tactic:
simpa [get?_eq_get i.2, get?_eq_get (h i.2)] using hf i
/-- A `l : List α` is `Sublist l l'` for `l' : List α` iff
there is `f`, an order-preserving embedding of `Fin l.length` into `Fin l'.length` such that
any element of `l` found at index `ix` can be found at index `f ix` in `l'`.
-/
theorem sublist_iff_exists_fin_orderEmbedding_get_eq {l l' : List α} :
    l <+ l' ↔
      ∃ f : Fin l.length ↪o Fin l'.length,
        ∀ ix : Fin l.length, l.get ix = l'.get (f ix) := by
  rw [sublist_iff_exists_orderEmbedding_get?_eq]
  constructor
  · rintro ⟨f, hf⟩
    have h : ∀ {i : ℕ}, i < l.length → f i < l'.length := by
      intro i hi
      specialize hf i
      rw [get?_eq_get hi, eq_comm, get?_eq_some] at hf
      obtain ⟨h, -⟩ := hf
      exact h
    refine' ⟨OrderEmbedding.ofMapLEIff (fun ix => ⟨f ix, h ix.is_lt⟩) _, _⟩
    · simp
    · intro i
      apply Option.some_injective
      simpa [get?_eq_get i.2, get?_eq_get (h i.2)] using hf i
  · 

Proof state:
case mpr
α : Type u_1
l l' : List α
⊢ (∃ f, ∀ (ix : Fin (length l)), get l ix = get l' (f ix)) → ∃ f, ∀ (ix : ℕ), get? l ix = get? l' (f ix)

Next tactic:
rintro ⟨f, hf⟩
/-- A `l : List α` is `Sublist l l'` for `l' : List α` iff
there is `f`, an order-preserving embedding of `Fin l.length` into `Fin l'.length` such that
any element of `l` found at index `ix` can be found at index `f ix` in `l'`.
-/
theorem sublist_iff_exists_fin_orderEmbedding_get_eq {l l' : List α} :
    l <+ l' ↔
      ∃ f : Fin l.length ↪o Fin l'.length,
        ∀ ix : Fin l.length, l.get ix = l'.get (f ix) := by
  rw [sublist_iff_exists_orderEmbedding_get?_eq]
  constructor
  · rintro ⟨f, hf⟩
    have h : ∀ {i : ℕ}, i < l.length → f i < l'.length := by
      intro i hi
      specialize hf i
      rw [get?_eq_get hi, eq_comm, get?_eq_some] at hf
      obtain ⟨h, -⟩ := hf
      exact h
    refine' ⟨OrderEmbedding.ofMapLEIff (fun ix => ⟨f ix, h ix.is_lt⟩) _, _⟩
    · simp
    · intro i
      apply Option.some_injective
      simpa [get?_eq_get i.2, get?_eq_get (h i.2)] using hf i
  · rintro ⟨f, hf⟩
    

Proof state:
case mpr.intro
α : Type u_1
l l' : List α
f : Fin (length l) ↪o Fin (length l')
hf : ∀ (ix : Fin (length l)), get l ix = get l' (f ix)
⊢ ∃ f, ∀ (ix : ℕ), get? l ix = get? l' (f ix)

Next tactic:
refine'
      ⟨OrderEmbedding.ofStrictMono (fun i => if hi : i < l.length then f ⟨i, hi⟩ else i + l'.length)
          _,
        _⟩
/-- A `l : List α` is `Sublist l l'` for `l' : List α` iff
there is `f`, an order-preserving embedding of `Fin l.length` into `Fin l'.length` such that
any element of `l` found at index `ix` can be found at index `f ix` in `l'`.
-/
theorem sublist_iff_exists_fin_orderEmbedding_get_eq {l l' : List α} :
    l <+ l' ↔
      ∃ f : Fin l.length ↪o Fin l'.length,
        ∀ ix : Fin l.length, l.get ix = l'.get (f ix) := by
  rw [sublist_iff_exists_orderEmbedding_get?_eq]
  constructor
  · rintro ⟨f, hf⟩
    have h : ∀ {i : ℕ}, i < l.length → f i < l'.length := by
      intro i hi
      specialize hf i
      rw [get?_eq_get hi, eq_comm, get?_eq_some] at hf
      obtain ⟨h, -⟩ := hf
      exact h
    refine' ⟨OrderEmbedding.ofMapLEIff (fun ix => ⟨f ix, h ix.is_lt⟩) _, _⟩
    · simp
    · intro i
      apply Option.some_injective
      simpa [get?_eq_get i.2, get?_eq_get (h i.2)] using hf i
  · rintro ⟨f, hf⟩
    refine'
      ⟨OrderEmbedding.ofStrictMono (fun i => if hi : i < l.length then f ⟨i, hi⟩ else i + l'.length)
          _,
        _⟩
    · 

Proof state:
case mpr.intro.refine'_1
α : Type u_1
l l' : List α
f : Fin (length l) ↪o Fin (length l')
hf : ∀ (ix : Fin (length l)), get l ix = get l' (f ix)
⊢ StrictMono fun i => if hi : i < length l then ↑(f { val := i, isLt := hi }) else i + length l'

Next tactic:
intro i j h
/-- A `l : List α` is `Sublist l l'` for `l' : List α` iff
there is `f`, an order-preserving embedding of `Fin l.length` into `Fin l'.length` such that
any element of `l` found at index `ix` can be found at index `f ix` in `l'`.
-/
theorem sublist_iff_exists_fin_orderEmbedding_get_eq {l l' : List α} :
    l <+ l' ↔
      ∃ f : Fin l.length ↪o Fin l'.length,
        ∀ ix : Fin l.length, l.get ix = l'.get (f ix) := by
  rw [sublist_iff_exists_orderEmbedding_get?_eq]
  constructor
  · rintro ⟨f, hf⟩
    have h : ∀ {i : ℕ}, i < l.length → f i < l'.length := by
      intro i hi
      specialize hf i
      rw [get?_eq_get hi, eq_comm, get?_eq_some] at hf
      obtain ⟨h, -⟩ := hf
      exact h
    refine' ⟨OrderEmbedding.ofMapLEIff (fun ix => ⟨f ix, h ix.is_lt⟩) _, _⟩
    · simp
    · intro i
      apply Option.some_injective
      simpa [get?_eq_get i.2, get?_eq_get (h i.2)] using hf i
  · rintro ⟨f, hf⟩
    refine'
      ⟨OrderEmbedding.ofStrictMono (fun i => if hi : i < l.length then f ⟨i, hi⟩ else i + l'.length)
          _,
        _⟩
    · intro i j h
      

Proof state:
case mpr.intro.refine'_1
α : Type u_1
l l' : List α
f : Fin (length l) ↪o Fin (length l')
hf : ∀ (ix : Fin (length l)), get l ix = get l' (f ix)
i j : ℕ
h : i < j
⊢ (fun i => if hi : i < length l then ↑(f { val := i, isLt := hi }) else i + length l') i <
    (fun i => if hi : i < length l then ↑(f { val := i, isLt := hi }) else i + length l') j

Next tactic:
dsimp only
/-- A `l : List α` is `Sublist l l'` for `l' : List α` iff
there is `f`, an order-preserving embedding of `Fin l.length` into `Fin l'.length` such that
any element of `l` found at index `ix` can be found at index `f ix` in `l'`.
-/
theorem sublist_iff_exists_fin_orderEmbedding_get_eq {l l' : List α} :
    l <+ l' ↔
      ∃ f : Fin l.length ↪o Fin l'.length,
        ∀ ix : Fin l.length, l.get ix = l'.get (f ix) := by
  rw [sublist_iff_exists_orderEmbedding_get?_eq]
  constructor
  · rintro ⟨f, hf⟩
    have h : ∀ {i : ℕ}, i < l.length → f i < l'.length := by
      intro i hi
      specialize hf i
      rw [get?_eq_get hi, eq_comm, get?_eq_some] at hf
      obtain ⟨h, -⟩ := hf
      exact h
    refine' ⟨OrderEmbedding.ofMapLEIff (fun ix => ⟨f ix, h ix.is_lt⟩) _, _⟩
    · simp
    · intro i
      apply Option.some_injective
      simpa [get?_eq_get i.2, get?_eq_get (h i.2)] using hf i
  · rintro ⟨f, hf⟩
    refine'
      ⟨OrderEmbedding.ofStrictMono (fun i => if hi : i < l.length then f ⟨i, hi⟩ else i + l'.length)
          _,
        _⟩
    · intro i j h
      dsimp only
      

Proof state:
case mpr.intro.refine'_1
α : Type u_1
l l' : List α
f : Fin (length l) ↪o Fin (length l')
hf : ∀ (ix : Fin (length l)), get l ix = get l' (f ix)
i j : ℕ
h : i < j
⊢ (if hi : i < length l then ↑(f { val := i, isLt := hi }) else i + length l') <
    if hi : j < length l then ↑(f { val := j, isLt := hi }) else j + length l'

Next tactic:
split_ifs with hi hj hj
/-- A `l : List α` is `Sublist l l'` for `l' : List α` iff
there is `f`, an order-preserving embedding of `Fin l.length` into `Fin l'.length` such that
any element of `l` found at index `ix` can be found at index `f ix` in `l'`.
-/
theorem sublist_iff_exists_fin_orderEmbedding_get_eq {l l' : List α} :
    l <+ l' ↔
      ∃ f : Fin l.length ↪o Fin l'.length,
        ∀ ix : Fin l.length, l.get ix = l'.get (f ix) := by
  rw [sublist_iff_exists_orderEmbedding_get?_eq]
  constructor
  · rintro ⟨f, hf⟩
    have h : ∀ {i : ℕ}, i < l.length → f i < l'.length := by
      intro i hi
      specialize hf i
      rw [get?_eq_get hi, eq_comm, get?_eq_some] at hf
      obtain ⟨h, -⟩ := hf
      exact h
    refine' ⟨OrderEmbedding.ofMapLEIff (fun ix => ⟨f ix, h ix.is_lt⟩) _, _⟩
    · simp
    · intro i
      apply Option.some_injective
      simpa [get?_eq_get i.2, get?_eq_get (h i.2)] using hf i
  · rintro ⟨f, hf⟩
    refine'
      ⟨OrderEmbedding.ofStrictMono (fun i => if hi : i < l.length then f ⟨i, hi⟩ else i + l'.length)
          _,
        _⟩
    · intro i j h
      dsimp only
      split_ifs with hi hj hj
      · 

Proof state:
case pos
α : Type u_1
l l' : List α
f : Fin (length l) ↪o Fin (length l')
hf : ∀ (ix : Fin (length l)), get l ix = get l' (f ix)
i j : ℕ
h : i < j
hi : i < length l
hj : j < length l
⊢ ↑(f { val := i, isLt := hi }) < ↑(f { val := j, isLt := hj })

Next tactic:
rwa [Fin.val_fin_lt, f.lt_iff_lt]
/-- A `l : List α` is `Sublist l l'` for `l' : List α` iff
there is `f`, an order-preserving embedding of `Fin l.length` into `Fin l'.length` such that
any element of `l` found at index `ix` can be found at index `f ix` in `l'`.
-/
theorem sublist_iff_exists_fin_orderEmbedding_get_eq {l l' : List α} :
    l <+ l' ↔
      ∃ f : Fin l.length ↪o Fin l'.length,
        ∀ ix : Fin l.length, l.get ix = l'.get (f ix) := by
  rw [sublist_iff_exists_orderEmbedding_get?_eq]
  constructor
  · rintro ⟨f, hf⟩
    have h : ∀ {i : ℕ}, i < l.length → f i < l'.length := by
      intro i hi
      specialize hf i
      rw [get?_eq_get hi, eq_comm, get?_eq_some] at hf
      obtain ⟨h, -⟩ := hf
      exact h
    refine' ⟨OrderEmbedding.ofMapLEIff (fun ix => ⟨f ix, h ix.is_lt⟩) _, _⟩
    · simp
    · intro i
      apply Option.some_injective
      simpa [get?_eq_get i.2, get?_eq_get (h i.2)] using hf i
  · rintro ⟨f, hf⟩
    refine'
      ⟨OrderEmbedding.ofStrictMono (fun i => if hi : i < l.length then f ⟨i, hi⟩ else i + l'.length)
          _,
        _⟩
    · intro i j h
      dsimp only
      split_ifs with hi hj hj
      · rwa [Fin.val_fin_lt, f.lt_iff_lt]
      · 

Proof state:
case neg
α : Type u_1
l l' : List α
f : Fin (length l) ↪o Fin (length l')
hf : ∀ (ix : Fin (length l)), get l ix = get l' (f ix)
i j : ℕ
h : i < j
hi : i < length l
hj : ¬j < length l
⊢ ↑(f { val := i, isLt := hi }) < j + length l'

Next tactic:
rw [add_comm]
/-- A `l : List α` is `Sublist l l'` for `l' : List α` iff
there is `f`, an order-preserving embedding of `Fin l.length` into `Fin l'.length` such that
any element of `l` found at index `ix` can be found at index `f ix` in `l'`.
-/
theorem sublist_iff_exists_fin_orderEmbedding_get_eq {l l' : List α} :
    l <+ l' ↔
      ∃ f : Fin l.length ↪o Fin l'.length,
        ∀ ix : Fin l.length, l.get ix = l'.get (f ix) := by
  rw [sublist_iff_exists_orderEmbedding_get?_eq]
  constructor
  · rintro ⟨f, hf⟩
    have h : ∀ {i : ℕ}, i < l.length → f i < l'.length := by
      intro i hi
      specialize hf i
      rw [get?_eq_get hi, eq_comm, get?_eq_some] at hf
      obtain ⟨h, -⟩ := hf
      exact h
    refine' ⟨OrderEmbedding.ofMapLEIff (fun ix => ⟨f ix, h ix.is_lt⟩) _, _⟩
    · simp
    · intro i
      apply Option.some_injective
      simpa [get?_eq_get i.2, get?_eq_get (h i.2)] using hf i
  · rintro ⟨f, hf⟩
    refine'
      ⟨OrderEmbedding.ofStrictMono (fun i => if hi : i < l.length then f ⟨i, hi⟩ else i + l'.length)
          _,
        _⟩
    · intro i j h
      dsimp only
      split_ifs with hi hj hj
      · rwa [Fin.val_fin_lt, f.lt_iff_lt]
      · rw [add_comm]
        

Proof state:
case neg
α : Type u_1
l l' : List α
f : Fin (length l) ↪o Fin (length l')
hf : ∀ (ix : Fin (length l)), get l ix = get l' (f ix)
i j : ℕ
h : i < j
hi : i < length l
hj : ¬j < length l
⊢ ↑(f { val := i, isLt := hi }) < length l' + j

Next tactic:
exact lt_add_of_lt_of_pos (Fin.is_lt _) (i.zero_le.trans_lt h)
/-- A `l : List α` is `Sublist l l'` for `l' : List α` iff
there is `f`, an order-preserving embedding of `Fin l.length` into `Fin l'.length` such that
any element of `l` found at index `ix` can be found at index `f ix` in `l'`.
-/
theorem sublist_iff_exists_fin_orderEmbedding_get_eq {l l' : List α} :
    l <+ l' ↔
      ∃ f : Fin l.length ↪o Fin l'.length,
        ∀ ix : Fin l.length, l.get ix = l'.get (f ix) := by
  rw [sublist_iff_exists_orderEmbedding_get?_eq]
  constructor
  · rintro ⟨f, hf⟩
    have h : ∀ {i : ℕ}, i < l.length → f i < l'.length := by
      intro i hi
      specialize hf i
      rw [get?_eq_get hi, eq_comm, get?_eq_some] at hf
      obtain ⟨h, -⟩ := hf
      exact h
    refine' ⟨OrderEmbedding.ofMapLEIff (fun ix => ⟨f ix, h ix.is_lt⟩) _, _⟩
    · simp
    · intro i
      apply Option.some_injective
      simpa [get?_eq_get i.2, get?_eq_get (h i.2)] using hf i
  · rintro ⟨f, hf⟩
    refine'
      ⟨OrderEmbedding.ofStrictMono (fun i => if hi : i < l.length then f ⟨i, hi⟩ else i + l'.length)
          _,
        _⟩
    · intro i j h
      dsimp only
      split_ifs with hi hj hj
      · rwa [Fin.val_fin_lt, f.lt_iff_lt]
      · rw [add_comm]
        exact lt_add_of_lt_of_pos (Fin.is_lt _) (i.zero_le.trans_lt h)
      · 

Proof state:
case pos
α : Type u_1
l l' : List α
f : Fin (length l) ↪o Fin (length l')
hf : ∀ (ix : Fin (length l)), get l ix = get l' (f ix)
i j : ℕ
h : i < j
hi : ¬i < length l
hj : j < length l
⊢ i + length l' < ↑(f { val := j, isLt := hj })

Next tactic:
exact absurd (h.trans hj) hi
/-- A `l : List α` is `Sublist l l'` for `l' : List α` iff
there is `f`, an order-preserving embedding of `Fin l.length` into `Fin l'.length` such that
any element of `l` found at index `ix` can be found at index `f ix` in `l'`.
-/
theorem sublist_iff_exists_fin_orderEmbedding_get_eq {l l' : List α} :
    l <+ l' ↔
      ∃ f : Fin l.length ↪o Fin l'.length,
        ∀ ix : Fin l.length, l.get ix = l'.get (f ix) := by
  rw [sublist_iff_exists_orderEmbedding_get?_eq]
  constructor
  · rintro ⟨f, hf⟩
    have h : ∀ {i : ℕ}, i < l.length → f i < l'.length := by
      intro i hi
      specialize hf i
      rw [get?_eq_get hi, eq_comm, get?_eq_some] at hf
      obtain ⟨h, -⟩ := hf
      exact h
    refine' ⟨OrderEmbedding.ofMapLEIff (fun ix => ⟨f ix, h ix.is_lt⟩) _, _⟩
    · simp
    · intro i
      apply Option.some_injective
      simpa [get?_eq_get i.2, get?_eq_get (h i.2)] using hf i
  · rintro ⟨f, hf⟩
    refine'
      ⟨OrderEmbedding.ofStrictMono (fun i => if hi : i < l.length then f ⟨i, hi⟩ else i + l'.length)
          _,
        _⟩
    · intro i j h
      dsimp only
      split_ifs with hi hj hj
      · rwa [Fin.val_fin_lt, f.lt_iff_lt]
      · rw [add_comm]
        exact lt_add_of_lt_of_pos (Fin.is_lt _) (i.zero_le.trans_lt h)
      · exact absurd (h.trans hj) hi
      · 

Proof state:
case neg
α : Type u_1
l l' : List α
f : Fin (length l) ↪o Fin (length l')
hf : ∀ (ix : Fin (length l)), get l ix = get l' (f ix)
i j : ℕ
h : i < j
hi : ¬i < length l
hj : ¬j < length l
⊢ i + length l' < j + length l'

Next tactic:
simpa using h
/-- A `l : List α` is `Sublist l l'` for `l' : List α` iff
there is `f`, an order-preserving embedding of `Fin l.length` into `Fin l'.length` such that
any element of `l` found at index `ix` can be found at index `f ix` in `l'`.
-/
theorem sublist_iff_exists_fin_orderEmbedding_get_eq {l l' : List α} :
    l <+ l' ↔
      ∃ f : Fin l.length ↪o Fin l'.length,
        ∀ ix : Fin l.length, l.get ix = l'.get (f ix) := by
  rw [sublist_iff_exists_orderEmbedding_get?_eq]
  constructor
  · rintro ⟨f, hf⟩
    have h : ∀ {i : ℕ}, i < l.length → f i < l'.length := by
      intro i hi
      specialize hf i
      rw [get?_eq_get hi, eq_comm, get?_eq_some] at hf
      obtain ⟨h, -⟩ := hf
      exact h
    refine' ⟨OrderEmbedding.ofMapLEIff (fun ix => ⟨f ix, h ix.is_lt⟩) _, _⟩
    · simp
    · intro i
      apply Option.some_injective
      simpa [get?_eq_get i.2, get?_eq_get (h i.2)] using hf i
  · rintro ⟨f, hf⟩
    refine'
      ⟨OrderEmbedding.ofStrictMono (fun i => if hi : i < l.length then f ⟨i, hi⟩ else i + l'.length)
          _,
        _⟩
    · intro i j h
      dsimp only
      split_ifs with hi hj hj
      · rwa [Fin.val_fin_lt, f.lt_iff_lt]
      · rw [add_comm]
        exact lt_add_of_lt_of_pos (Fin.is_lt _) (i.zero_le.trans_lt h)
      · exact absurd (h.trans hj) hi
      · simpa using h
    · 

Proof state:
case mpr.intro.refine'_2
α : Type u_1
l l' : List α
f : Fin (length l) ↪o Fin (length l')
hf : ∀ (ix : Fin (length l)), get l ix = get l' (f ix)
⊢ ∀ (ix : ℕ),
    get? l ix =
      get? l'
        ((OrderEmbedding.ofStrictMono
            (fun i => if hi : i < length l then ↑(f { val := i, isLt := hi }) else i + length l')
            (_ :
              ∀ ⦃i j : ℕ⦄,
                i < j →
                  (fun i => if hi : i < length l then ↑(f { val := i, isLt := hi }) else i + length l') i <
                    (fun i => if hi : i < length l then ↑(f { val := i, isLt := hi }) else i + length l') j))
          ix)

Next tactic:
intro i
/-- A `l : List α` is `Sublist l l'` for `l' : List α` iff
there is `f`, an order-preserving embedding of `Fin l.length` into `Fin l'.length` such that
any element of `l` found at index `ix` can be found at index `f ix` in `l'`.
-/
theorem sublist_iff_exists_fin_orderEmbedding_get_eq {l l' : List α} :
    l <+ l' ↔
      ∃ f : Fin l.length ↪o Fin l'.length,
        ∀ ix : Fin l.length, l.get ix = l'.get (f ix) := by
  rw [sublist_iff_exists_orderEmbedding_get?_eq]
  constructor
  · rintro ⟨f, hf⟩
    have h : ∀ {i : ℕ}, i < l.length → f i < l'.length := by
      intro i hi
      specialize hf i
      rw [get?_eq_get hi, eq_comm, get?_eq_some] at hf
      obtain ⟨h, -⟩ := hf
      exact h
    refine' ⟨OrderEmbedding.ofMapLEIff (fun ix => ⟨f ix, h ix.is_lt⟩) _, _⟩
    · simp
    · intro i
      apply Option.some_injective
      simpa [get?_eq_get i.2, get?_eq_get (h i.2)] using hf i
  · rintro ⟨f, hf⟩
    refine'
      ⟨OrderEmbedding.ofStrictMono (fun i => if hi : i < l.length then f ⟨i, hi⟩ else i + l'.length)
          _,
        _⟩
    · intro i j h
      dsimp only
      split_ifs with hi hj hj
      · rwa [Fin.val_fin_lt, f.lt_iff_lt]
      · rw [add_comm]
        exact lt_add_of_lt_of_pos (Fin.is_lt _) (i.zero_le.trans_lt h)
      · exact absurd (h.trans hj) hi
      · simpa using h
    · intro i
      

Proof state:
case mpr.intro.refine'_2
α : Type u_1
l l' : List α
f : Fin (length l) ↪o Fin (length l')
hf : ∀ (ix : Fin (length l)), get l ix = get l' (f ix)
i : ℕ
⊢ get? l i =
    get? l'
      ((OrderEmbedding.ofStrictMono
          (fun i => if hi : i < length l then ↑(f { val := i, isLt := hi }) else i + length l')
          (_ :
            ∀ ⦃i j : ℕ⦄,
              i < j →
                (fun i => if hi : i < length l then ↑(f { val := i, isLt := hi }) else i + length l') i <
                  (fun i => if hi : i < length l then ↑(f { val := i, isLt := hi }) else i + length l') j))
        i)

Next tactic:
simp only [OrderEmbedding.coe_ofStrictMono]
/-- A `l : List α` is `Sublist l l'` for `l' : List α` iff
there is `f`, an order-preserving embedding of `Fin l.length` into `Fin l'.length` such that
any element of `l` found at index `ix` can be found at index `f ix` in `l'`.
-/
theorem sublist_iff_exists_fin_orderEmbedding_get_eq {l l' : List α} :
    l <+ l' ↔
      ∃ f : Fin l.length ↪o Fin l'.length,
        ∀ ix : Fin l.length, l.get ix = l'.get (f ix) := by
  rw [sublist_iff_exists_orderEmbedding_get?_eq]
  constructor
  · rintro ⟨f, hf⟩
    have h : ∀ {i : ℕ}, i < l.length → f i < l'.length := by
      intro i hi
      specialize hf i
      rw [get?_eq_get hi, eq_comm, get?_eq_some] at hf
      obtain ⟨h, -⟩ := hf
      exact h
    refine' ⟨OrderEmbedding.ofMapLEIff (fun ix => ⟨f ix, h ix.is_lt⟩) _, _⟩
    · simp
    · intro i
      apply Option.some_injective
      simpa [get?_eq_get i.2, get?_eq_get (h i.2)] using hf i
  · rintro ⟨f, hf⟩
    refine'
      ⟨OrderEmbedding.ofStrictMono (fun i => if hi : i < l.length then f ⟨i, hi⟩ else i + l'.length)
          _,
        _⟩
    · intro i j h
      dsimp only
      split_ifs with hi hj hj
      · rwa [Fin.val_fin_lt, f.lt_iff_lt]
      · rw [add_comm]
        exact lt_add_of_lt_of_pos (Fin.is_lt _) (i.zero_le.trans_lt h)
      · exact absurd (h.trans hj) hi
      · simpa using h
    · intro i
      simp only [OrderEmbedding.coe_ofStrictMono]
      

Proof state:
case mpr.intro.refine'_2
α : Type u_1
l l' : List α
f : Fin (length l) ↪o Fin (length l')
hf : ∀ (ix : Fin (length l)), get l ix = get l' (f ix)
i : ℕ
⊢ get? l i = get? l' (if hi : i < length l then ↑(f { val := i, isLt := hi }) else i + length l')

Next tactic:
split_ifs with hi
/-- A `l : List α` is `Sublist l l'` for `l' : List α` iff
there is `f`, an order-preserving embedding of `Fin l.length` into `Fin l'.length` such that
any element of `l` found at index `ix` can be found at index `f ix` in `l'`.
-/
theorem sublist_iff_exists_fin_orderEmbedding_get_eq {l l' : List α} :
    l <+ l' ↔
      ∃ f : Fin l.length ↪o Fin l'.length,
        ∀ ix : Fin l.length, l.get ix = l'.get (f ix) := by
  rw [sublist_iff_exists_orderEmbedding_get?_eq]
  constructor
  · rintro ⟨f, hf⟩
    have h : ∀ {i : ℕ}, i < l.length → f i < l'.length := by
      intro i hi
      specialize hf i
      rw [get?_eq_get hi, eq_comm, get?_eq_some] at hf
      obtain ⟨h, -⟩ := hf
      exact h
    refine' ⟨OrderEmbedding.ofMapLEIff (fun ix => ⟨f ix, h ix.is_lt⟩) _, _⟩
    · simp
    · intro i
      apply Option.some_injective
      simpa [get?_eq_get i.2, get?_eq_get (h i.2)] using hf i
  · rintro ⟨f, hf⟩
    refine'
      ⟨OrderEmbedding.ofStrictMono (fun i => if hi : i < l.length then f ⟨i, hi⟩ else i + l'.length)
          _,
        _⟩
    · intro i j h
      dsimp only
      split_ifs with hi hj hj
      · rwa [Fin.val_fin_lt, f.lt_iff_lt]
      · rw [add_comm]
        exact lt_add_of_lt_of_pos (Fin.is_lt _) (i.zero_le.trans_lt h)
      · exact absurd (h.trans hj) hi
      · simpa using h
    · intro i
      simp only [OrderEmbedding.coe_ofStrictMono]
      split_ifs with hi
      · 

Proof state:
case pos
α : Type u_1
l l' : List α
f : Fin (length l) ↪o Fin (length l')
hf : ∀ (ix : Fin (length l)), get l ix = get l' (f ix)
i : ℕ
hi : i < length l
⊢ get? l i = get? l' ↑(f { val := i, isLt := hi })

Next tactic:
rw [get?_eq_get hi, get?_eq_get, ← hf]