Theorem: List.sublist_iff_exists_fin_orderEmbedding_get_eq
File: Mathlib/Data/List/NodupEquivFin.lean

tactic: rw [sublist_iff_exists_orderEmbedding_get?_eq]
state_before: α : Type u_1
l l' : List α
⊢ l <+ l' ↔ ∃ f, ∀ (ix : Fin (length l)), get l ix = get l' (↑f ix)

tactic: constructor
state_before: α : Type u_1
l l' : List α
⊢ (∃ f, ∀ (ix : ℕ), get? l ix = get? l' (↑f ix)) ↔ ∃ f, ∀ (ix : Fin (length l)), get l ix = get l' (↑f ix)

tactic: rintro ⟨f, hf⟩
state_before: case mp
α : Type u_1
l l' : List α
⊢ (∃ f, ∀ (ix : ℕ), get? l ix = get? l' (↑f ix)) → ∃ f, ∀ (ix : Fin (length l)), get l ix = get l' (↑f ix)

tactic: 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
state_before: case mp.intro
α : Type u_1
l l' : List α
f : ℕ ↪o ℕ
hf : ∀ (ix : ℕ), get? l ix = get? l' (↑f ix)
⊢ ∃ f, ∀ (ix : Fin (length l)), get l ix = get l' (↑f ix)

tactic: refine' ⟨OrderEmbedding.ofMapLEIff (fun ix => ⟨f ix, h ix.is_lt⟩) _, _⟩
state_before: case mp.intro
α : 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'
⊢ ∃ f, ∀ (ix : Fin (length l)), get l ix = get l' (↑f ix)

tactic: intro i hi
state_before: α : Type u_1
l l' : List α
f : ℕ ↪o ℕ
hf : ∀ (ix : ℕ), get? l ix = get? l' (↑f ix)
⊢ ∀ {i : ℕ}, i < length l → ↑f i < length l'

tactic: specialize hf i
state_before: α : Type u_1
l l' : List α
f : ℕ ↪o ℕ
hf : ∀ (ix : ℕ), get? l ix = get? l' (↑f ix)
i : ℕ
hi : i < length l
⊢ ↑f i < length l'

tactic: rw [get?_eq_get hi, eq_comm, get?_eq_some] at hf
state_before: α : Type u_1
l l' : List α
f : ℕ ↪o ℕ
i : ℕ
hi : i < length l
hf : get? l i = get? l' (↑f i)
⊢ ↑f i < length l'

tactic: obtain ⟨h, -⟩ := hf
state_before: α : Type u_1
l l' : List α
f : ℕ ↪o ℕ
i : ℕ
hi : i < length l
hf : ∃ h, get l' { val := ↑f i, isLt := h } = get l { val := i, isLt := hi }
⊢ ↑f i < length l'

tactic: exact h
state_before: case intro
α : Type u_1
l l' : List α
f : ℕ ↪o ℕ
i : ℕ
hi : i < length l
h : ↑f i < length l'
⊢ ↑f i < length l'

tactic: simp
state_before: case mp.intro.refine'_1
α : 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'
⊢ ∀ (a b : Fin (length l)),
    (fun ix => { val := ↑f ↑ix, isLt := (_ : ↑f ↑ix < length l') }) a ≤
        (fun ix => { val := ↑f ↑ix, isLt := (_ : ↑f ↑ix < length l') }) b ↔
      a ≤ b

tactic: intro i
state_before: 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'
⊢ ∀ (ix : Fin (length l)),
    get l ix =
      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))
          ix)

tactic: apply Option.some_injective
state_before: 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)

tactic: simpa [get?_eq_get i.2, get?_eq_get (h i.2)] using hf i
state_before: 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))

tactic: rintro ⟨f, hf⟩
state_before: 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)

tactic: refine'
  ⟨OrderEmbedding.ofStrictMono (fun i => if hi : i < l.length then f ⟨i, hi⟩ else i + l'.length)
      _,
    _⟩
state_before: 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)

tactic: intro i j h
state_before: 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'

tactic: dsimp only
state_before: 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

tactic: split_ifs with hi hj hj
state_before: 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'

tactic: rwa [Fin.val_fin_lt, f.lt_iff_lt]
state_before: case mpr.intro.refine'_1.inl.inl
α : 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 })

tactic: rw [add_comm]
state_before: case mpr.intro.refine'_1.inl.inr
α : 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'

tactic: exact lt_add_of_lt_of_pos (Fin.is_lt _) (i.zero_le.trans_lt h)
state_before: case mpr.intro.refine'_1.inl.inr
α : 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

tactic: exact absurd (h.trans hj) hi
state_before: case mpr.intro.refine'_1.inr.inl
α : 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 })

tactic: simpa using h
state_before: case mpr.intro.refine'_1.inr.inr
α : 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'

tactic: intro i
state_before: 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)

tactic: simp only [OrderEmbedding.coe_ofStrictMono]
state_before: 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)

tactic: split_ifs with hi
state_before: 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 h : i < length l then ↑(↑f { val := i, isLt := (_ : i < length l) }) else i + length l')

tactic: rw [get?_eq_get hi, get?_eq_get, ← hf]
state_before: case mpr.intro.refine'_2.inl
α : 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 := (_ : i < length l) })

tactic: rw [get?_eq_none.mpr, get?_eq_none.mpr]
state_before: case mpr.intro.refine'_2.inr
α : 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' (i + length l')

tactic: simp
state_before: case mpr.intro.refine'_2.inr
α : 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
⊢ length l' ≤ i + length l'

tactic: simpa using hi
state_before: case mpr.intro.refine'_2.inr
α : 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
⊢ length l ≤ i