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 l.length), l.get ix = l'.get (f ix)
state_after: α : Type u_1
l l' : List α
⊢ (∃ f, ∀ (ix : ℕ), l.get? ix = l'.get? (f ix)) ↔ ∃ f, ∀ (ix : Fin l.length), l.get ix = l'.get (f ix)

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

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

tactic: rintro ⟨f, hf⟩
state_before: case mp
α : Type u_1
l l' : List α
⊢ (∃ f, ∀ (ix : ℕ), l.get? ix = l'.get? (f ix)) → ∃ f, ∀ (ix : Fin l.length), l.get ix = l'.get (f ix)
state_after: case mp.intro
α : Type u_1
l l' : List α
f : ℕ ↪o ℕ
hf : ∀ (ix : ℕ), l.get? ix = l'.get? (f ix)
⊢ ∃ f, ∀ (ix : Fin l.length), l.get ix = l'.get (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 : ℕ), l.get? ix = l'.get? (f ix)
⊢ ∃ f, ∀ (ix : Fin l.length), l.get ix = l'.get (f ix)
state_after: case mp.intro
α : Type u_1
l l' : List α
f : ℕ ↪o ℕ
hf : ∀ (ix : ℕ), l.get? ix = l'.get? (f ix)
h : ∀ {i : ℕ}, i < l.length → f i < l'.length
⊢ ∃ f, ∀ (ix : Fin l.length), l.get ix = l'.get (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 : ℕ), l.get? ix = l'.get? (f ix)
h : ∀ {i : ℕ}, i < l.length → f i < l'.length
⊢ ∃ f, ∀ (ix : Fin l.length), l.get ix = l'.get (f ix)
state_after: case mp.intro.refine_1
α : Type u_1
l l' : List α
f : ℕ ↪o ℕ
hf : ∀ (ix : ℕ), l.get? ix = l'.get? (f ix)
h : ∀ {i : ℕ}, i < l.length → f i < l'.length
⊢ ∀ (a b : Fin l.length), (fun ix => ⟨f ↑ix, ⋯⟩) a ≤ (fun ix => ⟨f ↑ix, ⋯⟩) b ↔ a ≤ b

case mp.intro.refine_2
α : Type u_1
l l' : List α
f : ℕ ↪o ℕ
hf : ∀ (ix : ℕ), l.get? ix = l'.get? (f ix)
h : ∀ {i : ℕ}, i < l.length → f i < l'.length
⊢ ∀ (ix : Fin l.length), l.get ix = l'.get ((OrderEmbedding.ofMapLEIff (fun ix => ⟨f ↑ix, ⋯⟩) ?mp.intro.refine_1) ix)

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

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

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 < l.length
hf : l.get? i = l'.get? (f i)
⊢ f i < l'.length
state_after: α : Type u_1
l l' : List α
f : ℕ ↪o ℕ
i : ℕ
hi : i < l.length
hf : ∃ (h : f i < l'.length), l'.get ⟨f i, h⟩ = l.get ⟨i, hi⟩
⊢ f i < l'.length

tactic: obtain ⟨h, -⟩ := hf
state_before: α : Type u_1
l l' : List α
f : ℕ ↪o ℕ
i : ℕ
hi : i < l.length
hf : ∃ (h : f i < l'.length), l'.get ⟨f i, h⟩ = l.get ⟨i, hi⟩
⊢ f i < l'.length
state_after: case intro
α : Type u_1
l l' : List α
f : ℕ ↪o ℕ
i : ℕ
hi : i < l.length
h : f i < l'.length
⊢ f i < l'.length

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

tactic: simp
state_before: case mp.intro.refine_1
α : Type u_1
l l' : List α
f : ℕ ↪o ℕ
hf : ∀ (ix : ℕ), l.get? ix = l'.get? (f ix)
h : ∀ {i : ℕ}, i < l.length → f i < l'.length
⊢ ∀ (a b : Fin l.length), (fun ix => ⟨f ↑ix, ⋯⟩) a ≤ (fun ix => ⟨f ↑ix, ⋯⟩) b ↔ a ≤ b
state_after: no goals

tactic: intro i
state_before: case mp.intro.refine_2
α : Type u_1
l l' : List α
f : ℕ ↪o ℕ
hf : ∀ (ix : ℕ), l.get? ix = l'.get? (f ix)
h : ∀ {i : ℕ}, i < l.length → f i < l'.length
⊢ ∀ (ix : Fin l.length), l.get ix = l'.get ((OrderEmbedding.ofMapLEIff (fun ix => ⟨f ↑ix, ⋯⟩) ⋯) ix)
state_after: case mp.intro.refine_2
α : Type u_1
l l' : List α
f : ℕ ↪o ℕ
hf : ∀ (ix : ℕ), l.get? ix = l'.get? (f ix)
h : ∀ {i : ℕ}, i < l.length → f i < l'.length
i : Fin l.length
⊢ l.get i = l'.get ((OrderEmbedding.ofMapLEIff (fun ix => ⟨f ↑ix, ⋯⟩) ⋯) i)

tactic: apply Option.some_injective
state_before: case mp.intro.refine_2
α : Type u_1
l l' : List α
f : ℕ ↪o ℕ
hf : ∀ (ix : ℕ), l.get? ix = l'.get? (f ix)
h : ∀ {i : ℕ}, i < l.length → f i < l'.length
i : Fin l.length
⊢ l.get i = l'.get ((OrderEmbedding.ofMapLEIff (fun ix => ⟨f ↑ix, ⋯⟩) ⋯) i)
state_after: case mp.intro.refine_2.a
α : Type u_1
l l' : List α
f : ℕ ↪o ℕ
hf : ∀ (ix : ℕ), l.get? ix = l'.get? (f ix)
h : ∀ {i : ℕ}, i < l.length → f i < l'.length
i : Fin l.length
⊢ some (l.get i) = some (l'.get ((OrderEmbedding.ofMapLEIff (fun ix => ⟨f ↑ix, ⋯⟩) ⋯) i))

tactic: simpa [getElem?_eq_getElem i.2, getElem?_eq_getElem (h i.2)] using hf i
state_before: case mp.intro.refine_2.a
α : Type u_1
l l' : List α
f : ℕ ↪o ℕ
hf : ∀ (ix : ℕ), l.get? ix = l'.get? (f ix)
h : ∀ {i : ℕ}, i < l.length → f i < l'.length
i : Fin l.length
⊢ some (l.get i) = some (l'.get ((OrderEmbedding.ofMapLEIff (fun ix => ⟨f ↑ix, ⋯⟩) ⋯) i))
state_after: no goals

tactic: rintro ⟨f, hf⟩
state_before: case mpr
α : Type u_1
l l' : List α
⊢ (∃ f, ∀ (ix : Fin l.length), l.get ix = l'.get (f ix)) → ∃ f, ∀ (ix : ℕ), l.get? ix = l'.get? (f ix)
state_after: case mpr.intro
α : Type u_1
l l' : List α
f : Fin l.length ↪o Fin l'.length
hf : ∀ (ix : Fin l.length), l.get ix = l'.get (f ix)
⊢ ∃ f, ∀ (ix : ℕ), l.get? ix = l'.get? (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 l.length ↪o Fin l'.length
hf : ∀ (ix : Fin l.length), l.get ix = l'.get (f ix)
⊢ ∃ f, ∀ (ix : ℕ), l.get? ix = l'.get? (f ix)
state_after: case mpr.intro.refine_1
α : Type u_1
l l' : List α
f : Fin l.length ↪o Fin l'.length
hf : ∀ (ix : Fin l.length), l.get ix = l'.get (f ix)
⊢ StrictMono fun i => if hi : i < l.length then ↑(f ⟨i, hi⟩) else i + l'.length

case mpr.intro.refine_2
α : Type u_1
l l' : List α
f : Fin l.length ↪o Fin l'.length
hf : ∀ (ix : Fin l.length), l.get ix = l'.get (f ix)
⊢ ∀ (ix : ℕ),
    l.get? ix =
      l'.get?
        ((OrderEmbedding.ofStrictMono (fun i => if hi : i < l.length then ↑(f ⟨i, hi⟩) else i + l'.length)
            ?mpr.intro.refine_1)
          ix)

tactic: intro i j h
state_before: case mpr.intro.refine_1
α : Type u_1
l l' : List α
f : Fin l.length ↪o Fin l'.length
hf : ∀ (ix : Fin l.length), l.get ix = l'.get (f ix)
⊢ StrictMono fun i => if hi : i < l.length then ↑(f ⟨i, hi⟩) else i + l'.length
state_after: case mpr.intro.refine_1
α : Type u_1
l l' : List α
f : Fin l.length ↪o Fin l'.length
hf : ∀ (ix : Fin l.length), l.get ix = l'.get (f ix)
i j : ℕ
h : i < j
⊢ (fun i => if hi : i < l.length then ↑(f ⟨i, hi⟩) else i + l'.length) i <
    (fun i => if hi : i < l.length then ↑(f ⟨i, hi⟩) else i + l'.length) j

tactic: dsimp only
state_before: case mpr.intro.refine_1
α : Type u_1
l l' : List α
f : Fin l.length ↪o Fin l'.length
hf : ∀ (ix : Fin l.length), l.get ix = l'.get (f ix)
i j : ℕ
h : i < j
⊢ (fun i => if hi : i < l.length then ↑(f ⟨i, hi⟩) else i + l'.length) i <
    (fun i => if hi : i < l.length then ↑(f ⟨i, hi⟩) else i + l'.length) j
state_after: case mpr.intro.refine_1
α : Type u_1
l l' : List α
f : Fin l.length ↪o Fin l'.length
hf : ∀ (ix : Fin l.length), l.get ix = l'.get (f ix)
i j : ℕ
h : i < j
⊢ (if hi : i < l.length then ↑(f ⟨i, hi⟩) else i + l'.length) <
    if hi : j < l.length then ↑(f ⟨j, hi⟩) else j + l'.length

tactic: split_ifs with hi hj hj
state_before: case mpr.intro.refine_1
α : Type u_1
l l' : List α
f : Fin l.length ↪o Fin l'.length
hf : ∀ (ix : Fin l.length), l.get ix = l'.get (f ix)
i j : ℕ
h : i < j
⊢ (if hi : i < l.length then ↑(f ⟨i, hi⟩) else i + l'.length) <
    if hi : j < l.length then ↑(f ⟨j, hi⟩) else j + l'.length
state_after: case pos
α : Type u_1
l l' : List α
f : Fin l.length ↪o Fin l'.length
hf : ∀ (ix : Fin l.length), l.get ix = l'.get (f ix)
i j : ℕ
h : i < j
hi : i < l.length
hj : j < l.length
⊢ ↑(f ⟨i, hi⟩) < ↑(f ⟨j, hj⟩)

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

case pos
α : Type u_1
l l' : List α
f : Fin l.length ↪o Fin l'.length
hf : ∀ (ix : Fin l.length), l.get ix = l'.get (f ix)
i j : ℕ
h : i < j
hi : ¬i < l.length
hj : j < l.length
⊢ i + l'.length < ↑(f ⟨j, hj⟩)

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

tactic: rwa [Fin.val_fin_lt, f.lt_iff_lt]
state_before: case pos
α : Type u_1
l l' : List α
f : Fin l.length ↪o Fin l'.length
hf : ∀ (ix : Fin l.length), l.get ix = l'.get (f ix)
i j : ℕ
h : i < j
hi : i < l.length
hj : j < l.length
⊢ ↑(f ⟨i, hi⟩) < ↑(f ⟨j, hj⟩)
state_after: no goals

tactic: have := (f ⟨i, hi⟩).is_lt
state_before: case neg
α : Type u_1
l l' : List α
f : Fin l.length ↪o Fin l'.length
hf : ∀ (ix : Fin l.length), l.get ix = l'.get (f ix)
i j : ℕ
h : i < j
hi : i < l.length
hj : ¬j < l.length
⊢ ↑(f ⟨i, hi⟩) < j + l'.length
state_after: case neg
α : Type u_1
l l' : List α
f : Fin l.length ↪o Fin l'.length
hf : ∀ (ix : Fin l.length), l.get ix = l'.get (f ix)
i j : ℕ
h : i < j
hi : i < l.length
hj : ¬j < l.length
this : ↑(f ⟨i, hi⟩) < l'.length
⊢ ↑(f ⟨i, hi⟩) < j + l'.length

tactic: omega
state_before: case neg
α : Type u_1
l l' : List α
f : Fin l.length ↪o Fin l'.length
hf : ∀ (ix : Fin l.length), l.get ix = l'.get (f ix)
i j : ℕ
h : i < j
hi : i < l.length
hj : ¬j < l.length
this : ↑(f ⟨i, hi⟩) < l'.length
⊢ ↑(f ⟨i, hi⟩) < j + l'.length
state_after: no goals

tactic: exact absurd (h.trans hj) hi
state_before: case pos
α : Type u_1
l l' : List α
f : Fin l.length ↪o Fin l'.length
hf : ∀ (ix : Fin l.length), l.get ix = l'.get (f ix)
i j : ℕ
h : i < j
hi : ¬i < l.length
hj : j < l.length
⊢ i + l'.length < ↑(f ⟨j, hj⟩)
state_after: no goals

tactic: simpa using h
state_before: case neg
α : Type u_1
l l' : List α
f : Fin l.length ↪o Fin l'.length
hf : ∀ (ix : Fin l.length), l.get ix = l'.get (f ix)
i j : ℕ
h : i < j
hi : ¬i < l.length
hj : ¬j < l.length
⊢ i + l'.length < j + l'.length
state_after: no goals

tactic: intro i
state_before: case mpr.intro.refine_2
α : Type u_1
l l' : List α
f : Fin l.length ↪o Fin l'.length
hf : ∀ (ix : Fin l.length), l.get ix = l'.get (f ix)
⊢ ∀ (ix : ℕ),
    l.get? ix =
      l'.get? ((OrderEmbedding.ofStrictMono (fun i => if hi : i < l.length then ↑(f ⟨i, hi⟩) else i + l'.length) ⋯) ix)
state_after: case mpr.intro.refine_2
α : Type u_1
l l' : List α
f : Fin l.length ↪o Fin l'.length
hf : ∀ (ix : Fin l.length), l.get ix = l'.get (f ix)
i : ℕ
⊢ l.get? i =
    l'.get? ((OrderEmbedding.ofStrictMono (fun i => if hi : i < l.length then ↑(f ⟨i, hi⟩) else i + l'.length) ⋯) i)

tactic: simp only [OrderEmbedding.coe_ofStrictMono]
state_before: case mpr.intro.refine_2
α : Type u_1
l l' : List α
f : Fin l.length ↪o Fin l'.length
hf : ∀ (ix : Fin l.length), l.get ix = l'.get (f ix)
i : ℕ
⊢ l.get? i =
    l'.get? ((OrderEmbedding.ofStrictMono (fun i => if hi : i < l.length then ↑(f ⟨i, hi⟩) else i + l'.length) ⋯) i)
state_after: case mpr.intro.refine_2
α : Type u_1
l l' : List α
f : Fin l.length ↪o Fin l'.length
hf : ∀ (ix : Fin l.length), l.get ix = l'.get (f ix)
i : ℕ
⊢ l.get? i = l'.get? (if hi : i < l.length then ↑(f ⟨i, hi⟩) else i + l'.length)

tactic: split_ifs with hi
state_before: case mpr.intro.refine_2
α : Type u_1
l l' : List α
f : Fin l.length ↪o Fin l'.length
hf : ∀ (ix : Fin l.length), l.get ix = l'.get (f ix)
i : ℕ
⊢ l.get? i = l'.get? (if hi : i < l.length then ↑(f ⟨i, hi⟩) else i + l'.length)
state_after: case pos
α : Type u_1
l l' : List α
f : Fin l.length ↪o Fin l'.length
hf : ∀ (ix : Fin l.length), l.get ix = l'.get (f ix)
i : ℕ
hi : i < l.length
⊢ l.get? i = l'.get? ↑(f ⟨i, hi⟩)

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

tactic: rw [get?_eq_get hi, get?_eq_get, ← hf]
state_before: case pos
α : Type u_1
l l' : List α
f : Fin l.length ↪o Fin l'.length
hf : ∀ (ix : Fin l.length), l.get ix = l'.get (f ix)
i : ℕ
hi : i < l.length
⊢ l.get? i = l'.get? ↑(f ⟨i, hi⟩)
state_after: no goals

tactic: rw [get?_eq_none.mpr, get?_eq_none.mpr]
state_before: case neg
α : Type u_1
l l' : List α
f : Fin l.length ↪o Fin l'.length
hf : ∀ (ix : Fin l.length), l.get ix = l'.get (f ix)
i : ℕ
hi : ¬i < l.length
⊢ l.get? i = l'.get? (i + l'.length)
state_after: case neg
α : Type u_1
l l' : List α
f : Fin l.length ↪o Fin l'.length
hf : ∀ (ix : Fin l.length), l.get ix = l'.get (f ix)
i : ℕ
hi : ¬i < l.length
⊢ l'.length ≤ i + l'.length

case neg
α : Type u_1
l l' : List α
f : Fin l.length ↪o Fin l'.length
hf : ∀ (ix : Fin l.length), l.get ix = l'.get (f ix)
i : ℕ
hi : ¬i < l.length
⊢ l.length ≤ i

tactic: simp
state_before: case neg
α : Type u_1
l l' : List α
f : Fin l.length ↪o Fin l'.length
hf : ∀ (ix : Fin l.length), l.get ix = l'.get (f ix)
i : ℕ
hi : ¬i < l.length
⊢ l'.length ≤ i + l'.length
state_after: no goals

tactic: simpa using hi
state_before: case neg
α : Type u_1
l l' : List α
f : Fin l.length ↪o Fin l'.length
hf : ∀ (ix : Fin l.length), l.get ix = l'.get (f ix)
i : ℕ
hi : ¬i < l.length
⊢ l.length ≤ i
state_after: no goals