l3lab/ntp-mathlib huggingface dataset:
/-- Create a finitely supported function from a total function by taking the default value to
zero. -/
def applyFinsupp (tf : TotalFunction α β) : α →₀ β where
  support := zeroDefaultSupp tf
  toFun := tf.zeroDefault.apply
  mem_support_toFun := by
    intro a
    rcases tf with ⟨A, y⟩
    simp only [apply, zeroDefaultSupp, List.mem_map, List.mem_filter, exists_and_right,
      List.mem_toFinset, exists_eq_right, Sigma.exists, Ne.def, zeroDefault]
    constructor
    · rintro ⟨od, hval, hod⟩
      have := List.mem_dlookup (List.nodupKeys_dedupKeys A) hval
      rw [(_ : List.dlookup a A = od)]
      · simpa using hod
      · simpa [List.dlookup_dedupKeys, WithTop.some_eq_coe]
    · 

Proof state:
case withDefault.mpr
α : Type u
β : Type v
γ : Sort w
inst✝² : Zero β
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
a : α
A : List ((_ : α) × β)
y : β
⊢ ¬Option.getD (List.dlookup a A) 0 = 0 → ∃ x, { fst := a, snd := x } ∈ List.dedupKeys A ∧ (decide ¬x = 0) = true

Next tactic:
intro h
/-- Create a finitely supported function from a total function by taking the default value to
zero. -/
def applyFinsupp (tf : TotalFunction α β) : α →₀ β where
  support := zeroDefaultSupp tf
  toFun := tf.zeroDefault.apply
  mem_support_toFun := by
    intro a
    rcases tf with ⟨A, y⟩
    simp only [apply, zeroDefaultSupp, List.mem_map, List.mem_filter, exists_and_right,
      List.mem_toFinset, exists_eq_right, Sigma.exists, Ne.def, zeroDefault]
    constructor
    · rintro ⟨od, hval, hod⟩
      have := List.mem_dlookup (List.nodupKeys_dedupKeys A) hval
      rw [(_ : List.dlookup a A = od)]
      · simpa using hod
      · simpa [List.dlookup_dedupKeys, WithTop.some_eq_coe]
    · intro h
      

Proof state:
case withDefault.mpr
α : Type u
β : Type v
γ : Sort w
inst✝² : Zero β
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
a : α
A : List ((_ : α) × β)
y : β
h : ¬Option.getD (List.dlookup a A) 0 = 0
⊢ ∃ x, { fst := a, snd := x } ∈ List.dedupKeys A ∧ (decide ¬x = 0) = true

Next tactic:
use (A.dlookup a).getD (0 : β)
/-- Create a finitely supported function from a total function by taking the default value to
zero. -/
def applyFinsupp (tf : TotalFunction α β) : α →₀ β where
  support := zeroDefaultSupp tf
  toFun := tf.zeroDefault.apply
  mem_support_toFun := by
    intro a
    rcases tf with ⟨A, y⟩
    simp only [apply, zeroDefaultSupp, List.mem_map, List.mem_filter, exists_and_right,
      List.mem_toFinset, exists_eq_right, Sigma.exists, Ne.def, zeroDefault]
    constructor
    · rintro ⟨od, hval, hod⟩
      have := List.mem_dlookup (List.nodupKeys_dedupKeys A) hval
      rw [(_ : List.dlookup a A = od)]
      · simpa using hod
      · simpa [List.dlookup_dedupKeys, WithTop.some_eq_coe]
    · intro h
      use (A.dlookup a).getD (0 : β)
      

Proof state:
case h
α : Type u
β : Type v
γ : Sort w
inst✝² : Zero β
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
a : α
A : List ((_ : α) × β)
y : β
h : ¬Option.getD (List.dlookup a A) 0 = 0
⊢ { fst := a, snd := Option.getD (List.dlookup a A) 0 } ∈ List.dedupKeys A ∧
    (decide ¬Option.getD (List.dlookup a A) 0 = 0) = true

Next tactic:
rw [← List.dlookup_dedupKeys] at h ⊢
/-- Create a finitely supported function from a total function by taking the default value to
zero. -/
def applyFinsupp (tf : TotalFunction α β) : α →₀ β where
  support := zeroDefaultSupp tf
  toFun := tf.zeroDefault.apply
  mem_support_toFun := by
    intro a
    rcases tf with ⟨A, y⟩
    simp only [apply, zeroDefaultSupp, List.mem_map, List.mem_filter, exists_and_right,
      List.mem_toFinset, exists_eq_right, Sigma.exists, Ne.def, zeroDefault]
    constructor
    · rintro ⟨od, hval, hod⟩
      have := List.mem_dlookup (List.nodupKeys_dedupKeys A) hval
      rw [(_ : List.dlookup a A = od)]
      · simpa using hod
      · simpa [List.dlookup_dedupKeys, WithTop.some_eq_coe]
    · intro h
      use (A.dlookup a).getD (0 : β)
      rw [← List.dlookup_dedupKeys] at h ⊢
      

Proof state:
case h
α : Type u
β : Type v
γ : Sort w
inst✝² : Zero β
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
a : α
A : List ((_ : α) × β)
y : β
h : ¬Option.getD (List.dlookup a (List.dedupKeys A)) 0 = 0
⊢ { fst := a, snd := Option.getD (List.dlookup a (List.dedupKeys A)) 0 } ∈ List.dedupKeys A ∧
    (decide ¬Option.getD (List.dlookup a (List.dedupKeys A)) 0 = 0) = true

Next tactic:
simp only [h, ← List.mem_dlookup_iff A.nodupKeys_dedupKeys, and_true_iff, not_false_iff,
        Option.mem_def]
/-- Create a finitely supported function from a total function by taking the default value to
zero. -/
def applyFinsupp (tf : TotalFunction α β) : α →₀ β where
  support := zeroDefaultSupp tf
  toFun := tf.zeroDefault.apply
  mem_support_toFun := by
    intro a
    rcases tf with ⟨A, y⟩
    simp only [apply, zeroDefaultSupp, List.mem_map, List.mem_filter, exists_and_right,
      List.mem_toFinset, exists_eq_right, Sigma.exists, Ne.def, zeroDefault]
    constructor
    · rintro ⟨od, hval, hod⟩
      have := List.mem_dlookup (List.nodupKeys_dedupKeys A) hval
      rw [(_ : List.dlookup a A = od)]
      · simpa using hod
      · simpa [List.dlookup_dedupKeys, WithTop.some_eq_coe]
    · intro h
      use (A.dlookup a).getD (0 : β)
      rw [← List.dlookup_dedupKeys] at h ⊢
      simp only [h, ← List.mem_dlookup_iff A.nodupKeys_dedupKeys, and_true_iff, not_false_iff,
        Option.mem_def]
      

Proof state:
case h
α : Type u
β : Type v
γ : Sort w
inst✝² : Zero β
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
a : α
A : List ((_ : α) × β)
y : β
h : ¬Option.getD (List.dlookup a (List.dedupKeys A)) 0 = 0
⊢ List.dlookup a (List.dedupKeys A) = some (Option.getD (List.dlookup a (List.dedupKeys A)) 0) ∧ decide True = true

Next tactic:
cases haA : List.dlookup a A.dedupKeys
/-- Create a finitely supported function from a total function by taking the default value to
zero. -/
def applyFinsupp (tf : TotalFunction α β) : α →₀ β where
  support := zeroDefaultSupp tf
  toFun := tf.zeroDefault.apply
  mem_support_toFun := by
    intro a
    rcases tf with ⟨A, y⟩
    simp only [apply, zeroDefaultSupp, List.mem_map, List.mem_filter, exists_and_right,
      List.mem_toFinset, exists_eq_right, Sigma.exists, Ne.def, zeroDefault]
    constructor
    · rintro ⟨od, hval, hod⟩
      have := List.mem_dlookup (List.nodupKeys_dedupKeys A) hval
      rw [(_ : List.dlookup a A = od)]
      · simpa using hod
      · simpa [List.dlookup_dedupKeys, WithTop.some_eq_coe]
    · intro h
      use (A.dlookup a).getD (0 : β)
      rw [← List.dlookup_dedupKeys] at h ⊢
      simp only [h, ← List.mem_dlookup_iff A.nodupKeys_dedupKeys, and_true_iff, not_false_iff,
        Option.mem_def]
      cases haA : List.dlookup a A.dedupKeys
      · 

Proof state:
case h.none
α : Type u
β : Type v
γ : Sort w
inst✝² : Zero β
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
a : α
A : List ((_ : α) × β)
y : β
h : ¬Option.getD (List.dlookup a (List.dedupKeys A)) 0 = 0
haA : List.dlookup a (List.dedupKeys A) = none
⊢ none = some (Option.getD none 0) ∧ decide True = true

Next tactic:
simp [haA] at h
/-- Create a finitely supported function from a total function by taking the default value to
zero. -/
def applyFinsupp (tf : TotalFunction α β) : α →₀ β where
  support := zeroDefaultSupp tf
  toFun := tf.zeroDefault.apply
  mem_support_toFun := by
    intro a
    rcases tf with ⟨A, y⟩
    simp only [apply, zeroDefaultSupp, List.mem_map, List.mem_filter, exists_and_right,
      List.mem_toFinset, exists_eq_right, Sigma.exists, Ne.def, zeroDefault]
    constructor
    · rintro ⟨od, hval, hod⟩
      have := List.mem_dlookup (List.nodupKeys_dedupKeys A) hval
      rw [(_ : List.dlookup a A = od)]
      · simpa using hod
      · simpa [List.dlookup_dedupKeys, WithTop.some_eq_coe]
    · intro h
      use (A.dlookup a).getD (0 : β)
      rw [← List.dlookup_dedupKeys] at h ⊢
      simp only [h, ← List.mem_dlookup_iff A.nodupKeys_dedupKeys, and_true_iff, not_false_iff,
        Option.mem_def]
      cases haA : List.dlookup a A.dedupKeys
      · simp [haA] at h
      · 

Proof state:
case h.some
α : Type u
β : Type v
γ : Sort w
inst✝² : Zero β
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
a : α
A : List ((_ : α) × β)
y : β
h : ¬Option.getD (List.dlookup a (List.dedupKeys A)) 0 = 0
val✝ : β
haA : List.dlookup a (List.dedupKeys A) = some val✝
⊢ some val✝ = some (Option.getD (some val✝) 0) ∧ decide True = true

Next tactic:
simp
@[simp]
theorem List.applyId_cons [DecidableEq α] (xs : List (α × α)) (x y z : α) :
    List.applyId ((y, z)::xs) x = if y = x then z else List.applyId xs x := by
  

Proof state:
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs : List (α × α)
x y z : α
⊢ applyId ((y, z) :: xs) x = if y = x then z else applyId xs x

Next tactic:
simp only [List.applyId, List.dlookup, eq_rec_constant, Prod.toSigma, List.map]
@[simp]
theorem List.applyId_cons [DecidableEq α] (xs : List (α × α)) (x y z : α) :
    List.applyId ((y, z)::xs) x = if y = x then z else List.applyId xs x := by
  simp only [List.applyId, List.dlookup, eq_rec_constant, Prod.toSigma, List.map]
  

Proof state:
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs : List (α × α)
x y z : α
⊢ Option.getD (if h : y = x then some z else dlookup x (map Prod.toSigma xs)) x =
    if y = x then z else Option.getD (dlookup x (map Prod.toSigma xs)) x

Next tactic:
split_ifs
@[simp]
theorem List.applyId_cons [DecidableEq α] (xs : List (α × α)) (x y z : α) :
    List.applyId ((y, z)::xs) x = if y = x then z else List.applyId xs x := by
  simp only [List.applyId, List.dlookup, eq_rec_constant, Prod.toSigma, List.map]
  split_ifs <;> 

Proof state:
case pos
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs : List (α × α)
x y z : α
h✝ : y = x
⊢ Option.getD (some z) x = z

Next tactic:
rfl
@[simp]
theorem List.applyId_cons [DecidableEq α] (xs : List (α × α)) (x y z : α) :
    List.applyId ((y, z)::xs) x = if y = x then z else List.applyId xs x := by
  simp only [List.applyId, List.dlookup, eq_rec_constant, Prod.toSigma, List.map]
  split_ifs <;> 

Proof state:
case neg
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs : List (α × α)
x y z : α
h✝ : ¬y = x
⊢ Option.getD (dlookup x (map Prod.toSigma xs)) x = Option.getD (dlookup x (map Prod.toSigma xs)) x

Next tactic:
rfl
theorem List.applyId_zip_eq [DecidableEq α] {xs ys : List α} (h₀ : List.Nodup xs)
    (h₁ : xs.length = ys.length) (x y : α) (i : ℕ) (h₂ : xs.get? i = some x) :
    List.applyId.{u} (xs.zip ys) x = y ↔ ys.get? i = some y := by
  

Proof state:
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : Nodup xs
h₁ : length xs = length ys
x y : α
i : ℕ
h₂ : get? xs i = some x
⊢ applyId (zip xs ys) x = y ↔ get? ys i = some y

Next tactic:
induction xs generalizing ys i with
  | nil => cases h₂
  | cons x' xs xs_ih =>
    cases i
    · injection h₂ with h₀; subst h₀
      cases ys
      · cases h₁
      · -- porting note: `open List` no longer makes `zip_cons_cons` visible
        simp only [List.applyId, Prod.toSigma, Option.getD_some, List.get?, List.dlookup_cons_eq,
          List.zip_cons_cons, List.map, Option.some_inj]
    · cases ys
      · cases h₁
      · cases' h₀ with _ _ h₀ h₁
        -- porting note: `open List` no longer makes `zip_cons_cons` visible
        simp only [List.get?, List.zip_cons_cons, List.applyId_cons] at h₂ ⊢
        rw [if_neg]
        · apply xs_ih <;> solve_by_elim [Nat.succ.inj]
        · apply h₀; apply List.get?_mem h₂
theorem List.applyId_zip_eq [DecidableEq α] {xs ys : List α} (h₀ : List.Nodup xs)
    (h₁ : xs.length = ys.length) (x y : α) (i : ℕ) (h₂ : xs.get? i = some x) :
    List.applyId.{u} (xs.zip ys) x = y ↔ ys.get? i = some y := by
  induction xs generalizing ys i with
  

Proof state:
case nil
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
x y : α
ys : List α
h₀ : Nodup []
h₁ : length [] = length ys
i : ℕ
h₂ : get? [] i = some x
⊢ applyId (zip [] ys) x = y ↔ get? ys i = some y

Next tactic:
| nil => cases h₂
theorem List.applyId_zip_eq [DecidableEq α] {xs ys : List α} (h₀ : List.Nodup xs)
    (h₁ : xs.length = ys.length) (x y : α) (i : ℕ) (h₂ : xs.get? i = some x) :
    List.applyId.{u} (xs.zip ys) x = y ↔ ys.get? i = some y := by
  induction xs generalizing ys i with
  | nil => 

Proof state:
case nil
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
x y : α
ys : List α
h₀ : Nodup []
h₁ : length [] = length ys
i : ℕ
h₂ : get? [] i = some x
⊢ applyId (zip [] ys) x = y ↔ get? ys i = some y

Next tactic:
cases h₂
theorem List.applyId_zip_eq [DecidableEq α] {xs ys : List α} (h₀ : List.Nodup xs)
    (h₁ : xs.length = ys.length) (x y : α) (i : ℕ) (h₂ : xs.get? i = some x) :
    List.applyId.{u} (xs.zip ys) x = y ↔ ys.get? i = some y := by
  induction xs generalizing ys i with
  | nil => cases h₂
  

Proof state:
case cons
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
x y x' : α
xs : List α
xs_ih :
  ∀ {ys : List α},
    Nodup xs → length xs = length ys → ∀ (i : ℕ), get? xs i = some x → (applyId (zip xs ys) x = y ↔ get? ys i = some y)
ys : List α
h₀ : Nodup (x' :: xs)
h₁ : length (x' :: xs) = length ys
i : ℕ
h₂ : get? (x' :: xs) i = some x
⊢ applyId (zip (x' :: xs) ys) x = y ↔ get? ys i = some y

Next tactic:
| cons x' xs xs_ih =>
    cases i
    · injection h₂ with h₀; subst h₀
      cases ys
      · cases h₁
      · -- porting note: `open List` no longer makes `zip_cons_cons` visible
        simp only [List.applyId, Prod.toSigma, Option.getD_some, List.get?, List.dlookup_cons_eq,
          List.zip_cons_cons, List.map, Option.some_inj]
    · cases ys
      · cases h₁
      · cases' h₀ with _ _ h₀ h₁
        -- porting note: `open List` no longer makes `zip_cons_cons` visible
        simp only [List.get?, List.zip_cons_cons, List.applyId_cons] at h₂ ⊢
        rw [if_neg]
        · apply xs_ih <;> solve_by_elim [Nat.succ.inj]
        · apply h₀; apply List.get?_mem h₂
theorem List.applyId_zip_eq [DecidableEq α] {xs ys : List α} (h₀ : List.Nodup xs)
    (h₁ : xs.length = ys.length) (x y : α) (i : ℕ) (h₂ : xs.get? i = some x) :
    List.applyId.{u} (xs.zip ys) x = y ↔ ys.get? i = some y := by
  induction xs generalizing ys i with
  | nil => cases h₂
  | cons x' xs xs_ih =>
    

Proof state:
case cons
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
x y x' : α
xs : List α
xs_ih :
  ∀ {ys : List α},
    Nodup xs → length xs = length ys → ∀ (i : ℕ), get? xs i = some x → (applyId (zip xs ys) x = y ↔ get? ys i = some y)
ys : List α
h₀ : Nodup (x' :: xs)
h₁ : length (x' :: xs) = length ys
i : ℕ
h₂ : get? (x' :: xs) i = some x
⊢ applyId (zip (x' :: xs) ys) x = y ↔ get? ys i = some y

Next tactic:
cases i
theorem List.applyId_zip_eq [DecidableEq α] {xs ys : List α} (h₀ : List.Nodup xs)
    (h₁ : xs.length = ys.length) (x y : α) (i : ℕ) (h₂ : xs.get? i = some x) :
    List.applyId.{u} (xs.zip ys) x = y ↔ ys.get? i = some y := by
  induction xs generalizing ys i with
  | nil => cases h₂
  | cons x' xs xs_ih =>
    cases i
    · 

Proof state:
case cons.zero
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
x y x' : α
xs : List α
xs_ih :
  ∀ {ys : List α},
    Nodup xs → length xs = length ys → ∀ (i : ℕ), get? xs i = some x → (applyId (zip xs ys) x = y ↔ get? ys i = some y)
ys : List α
h₀ : Nodup (x' :: xs)
h₁ : length (x' :: xs) = length ys
h₂ : get? (x' :: xs) Nat.zero = some x
⊢ applyId (zip (x' :: xs) ys) x = y ↔ get? ys Nat.zero = some y

Next tactic:
injection h₂ with h₀
theorem List.applyId_zip_eq [DecidableEq α] {xs ys : List α} (h₀ : List.Nodup xs)
    (h₁ : xs.length = ys.length) (x y : α) (i : ℕ) (h₂ : xs.get? i = some x) :
    List.applyId.{u} (xs.zip ys) x = y ↔ ys.get? i = some y := by
  induction xs generalizing ys i with
  | nil => cases h₂
  | cons x' xs xs_ih =>
    cases i
    · injection h₂ with h₀; 

Proof state:
case cons.zero
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
x y x' : α
xs : List α
xs_ih :
  ∀ {ys : List α},
    Nodup xs → length xs = length ys → ∀ (i : ℕ), get? xs i = some x → (applyId (zip xs ys) x = y ↔ get? ys i = some y)
ys : List α
h₀✝ : Nodup (x' :: xs)
h₁ : length (x' :: xs) = length ys
h₀ : x' = x
⊢ applyId (zip (x' :: xs) ys) x = y ↔ get? ys Nat.zero = some y

Next tactic:
subst h₀
theorem List.applyId_zip_eq [DecidableEq α] {xs ys : List α} (h₀ : List.Nodup xs)
    (h₁ : xs.length = ys.length) (x y : α) (i : ℕ) (h₂ : xs.get? i = some x) :
    List.applyId.{u} (xs.zip ys) x = y ↔ ys.get? i = some y := by
  induction xs generalizing ys i with
  | nil => cases h₂
  | cons x' xs xs_ih =>
    cases i
    · injection h₂ with h₀; subst h₀
      

Proof state:
case cons.zero
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
y x' : α
xs ys : List α
h₀ : Nodup (x' :: xs)
h₁ : length (x' :: xs) = length ys
xs_ih :
  ∀ {ys : List α},
    Nodup xs →
      length xs = length ys → ∀ (i : ℕ), get? xs i = some x' → (applyId (zip xs ys) x' = y ↔ get? ys i = some y)
⊢ applyId (zip (x' :: xs) ys) x' = y ↔ get? ys Nat.zero = some y

Next tactic:
cases ys
theorem List.applyId_zip_eq [DecidableEq α] {xs ys : List α} (h₀ : List.Nodup xs)
    (h₁ : xs.length = ys.length) (x y : α) (i : ℕ) (h₂ : xs.get? i = some x) :
    List.applyId.{u} (xs.zip ys) x = y ↔ ys.get? i = some y := by
  induction xs generalizing ys i with
  | nil => cases h₂
  | cons x' xs xs_ih =>
    cases i
    · injection h₂ with h₀; subst h₀
      cases ys
      · 

Proof state:
case cons.zero.nil
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
y x' : α
xs : List α
h₀ : Nodup (x' :: xs)
xs_ih :
  ∀ {ys : List α},
    Nodup xs →
      length xs = length ys → ∀ (i : ℕ), get? xs i = some x' → (applyId (zip xs ys) x' = y ↔ get? ys i = some y)
h₁ : length (x' :: xs) = length []
⊢ applyId (zip (x' :: xs) []) x' = y ↔ get? [] Nat.zero = some y

Next tactic:
cases h₁
theorem List.applyId_zip_eq [DecidableEq α] {xs ys : List α} (h₀ : List.Nodup xs)
    (h₁ : xs.length = ys.length) (x y : α) (i : ℕ) (h₂ : xs.get? i = some x) :
    List.applyId.{u} (xs.zip ys) x = y ↔ ys.get? i = some y := by
  induction xs generalizing ys i with
  | nil => cases h₂
  | cons x' xs xs_ih =>
    cases i
    · injection h₂ with h₀; subst h₀
      cases ys
      · cases h₁
      · -- porting note: `open List` no longer makes `zip_cons_cons` visible
        

Proof state:
case cons.zero.cons
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
y x' : α
xs : List α
h₀ : Nodup (x' :: xs)
xs_ih :
  ∀ {ys : List α},
    Nodup xs →
      length xs = length ys → ∀ (i : ℕ), get? xs i = some x' → (applyId (zip xs ys) x' = y ↔ get? ys i = some y)
head✝ : α
tail✝ : List α
h₁ : length (x' :: xs) = length (head✝ :: tail✝)
⊢ applyId (zip (x' :: xs) (head✝ :: tail✝)) x' = y ↔ get? (head✝ :: tail✝) Nat.zero = some y

Next tactic:
simp only [List.applyId, Prod.toSigma, Option.getD_some, List.get?, List.dlookup_cons_eq,
          List.zip_cons_cons, List.map, Option.some_inj]
theorem List.applyId_zip_eq [DecidableEq α] {xs ys : List α} (h₀ : List.Nodup xs)
    (h₁ : xs.length = ys.length) (x y : α) (i : ℕ) (h₂ : xs.get? i = some x) :
    List.applyId.{u} (xs.zip ys) x = y ↔ ys.get? i = some y := by
  induction xs generalizing ys i with
  | nil => cases h₂
  | cons x' xs xs_ih =>
    cases i
    · injection h₂ with h₀; subst h₀
      cases ys
      · cases h₁
      · -- porting note: `open List` no longer makes `zip_cons_cons` visible
        simp only [List.applyId, Prod.toSigma, Option.getD_some, List.get?, List.dlookup_cons_eq,
          List.zip_cons_cons, List.map, Option.some_inj]
    · 

Proof state:
case cons.succ
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
x y x' : α
xs : List α
xs_ih :
  ∀ {ys : List α},
    Nodup xs → length xs = length ys → ∀ (i : ℕ), get? xs i = some x → (applyId (zip xs ys) x = y ↔ get? ys i = some y)
ys : List α
h₀ : Nodup (x' :: xs)
h₁ : length (x' :: xs) = length ys
n✝ : ℕ
h₂ : get? (x' :: xs) (Nat.succ n✝) = some x
⊢ applyId (zip (x' :: xs) ys) x = y ↔ get? ys (Nat.succ n✝) = some y

Next tactic:
cases ys
theorem List.applyId_zip_eq [DecidableEq α] {xs ys : List α} (h₀ : List.Nodup xs)
    (h₁ : xs.length = ys.length) (x y : α) (i : ℕ) (h₂ : xs.get? i = some x) :
    List.applyId.{u} (xs.zip ys) x = y ↔ ys.get? i = some y := by
  induction xs generalizing ys i with
  | nil => cases h₂
  | cons x' xs xs_ih =>
    cases i
    · injection h₂ with h₀; subst h₀
      cases ys
      · cases h₁
      · -- porting note: `open List` no longer makes `zip_cons_cons` visible
        simp only [List.applyId, Prod.toSigma, Option.getD_some, List.get?, List.dlookup_cons_eq,
          List.zip_cons_cons, List.map, Option.some_inj]
    · cases ys
      · 

Proof state:
case cons.succ.nil
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
x y x' : α
xs : List α
xs_ih :
  ∀ {ys : List α},
    Nodup xs → length xs = length ys → ∀ (i : ℕ), get? xs i = some x → (applyId (zip xs ys) x = y ↔ get? ys i = some y)
h₀ : Nodup (x' :: xs)
n✝ : ℕ
h₂ : get? (x' :: xs) (Nat.succ n✝) = some x
h₁ : length (x' :: xs) = length []
⊢ applyId (zip (x' :: xs) []) x = y ↔ get? [] (Nat.succ n✝) = some y

Next tactic:
cases h₁
theorem List.applyId_zip_eq [DecidableEq α] {xs ys : List α} (h₀ : List.Nodup xs)
    (h₁ : xs.length = ys.length) (x y : α) (i : ℕ) (h₂ : xs.get? i = some x) :
    List.applyId.{u} (xs.zip ys) x = y ↔ ys.get? i = some y := by
  induction xs generalizing ys i with
  | nil => cases h₂
  | cons x' xs xs_ih =>
    cases i
    · injection h₂ with h₀; subst h₀
      cases ys
      · cases h₁
      · -- porting note: `open List` no longer makes `zip_cons_cons` visible
        simp only [List.applyId, Prod.toSigma, Option.getD_some, List.get?, List.dlookup_cons_eq,
          List.zip_cons_cons, List.map, Option.some_inj]
    · cases ys
      · cases h₁
      · 

Proof state:
case cons.succ.cons
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
x y x' : α
xs : List α
xs_ih :
  ∀ {ys : List α},
    Nodup xs → length xs = length ys → ∀ (i : ℕ), get? xs i = some x → (applyId (zip xs ys) x = y ↔ get? ys i = some y)
h₀ : Nodup (x' :: xs)
n✝ : ℕ
h₂ : get? (x' :: xs) (Nat.succ n✝) = some x
head✝ : α
tail✝ : List α
h₁ : length (x' :: xs) = length (head✝ :: tail✝)
⊢ applyId (zip (x' :: xs) (head✝ :: tail✝)) x = y ↔ get? (head✝ :: tail✝) (Nat.succ n✝) = some y

Next tactic:
cases' h₀ with _ _ h₀ h₁
theorem List.applyId_zip_eq [DecidableEq α] {xs ys : List α} (h₀ : List.Nodup xs)
    (h₁ : xs.length = ys.length) (x y : α) (i : ℕ) (h₂ : xs.get? i = some x) :
    List.applyId.{u} (xs.zip ys) x = y ↔ ys.get? i = some y := by
  induction xs generalizing ys i with
  | nil => cases h₂
  | cons x' xs xs_ih =>
    cases i
    · injection h₂ with h₀; subst h₀
      cases ys
      · cases h₁
      · -- porting note: `open List` no longer makes `zip_cons_cons` visible
        simp only [List.applyId, Prod.toSigma, Option.getD_some, List.get?, List.dlookup_cons_eq,
          List.zip_cons_cons, List.map, Option.some_inj]
    · cases ys
      · cases h₁
      · cases' h₀ with _ _ h₀ h₁
        -- porting note: `open List` no longer makes `zip_cons_cons` visible
        

Proof state:
case cons.succ.cons.cons
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
x y x' : α
xs : List α
xs_ih :
  ∀ {ys : List α},
    Nodup xs → length xs = length ys → ∀ (i : ℕ), get? xs i = some x → (applyId (zip xs ys) x = y ↔ get? ys i = some y)
n✝ : ℕ
h₂ : get? (x' :: xs) (Nat.succ n✝) = some x
head✝ : α
tail✝ : List α
h₁✝ : length (x' :: xs) = length (head✝ :: tail✝)
h₁ : List.Pairwise (fun x x_1 => x ≠ x_1) xs
h₀ : ∀ a' ∈ xs, x' ≠ a'
⊢ applyId (zip (x' :: xs) (head✝ :: tail✝)) x = y ↔ get? (head✝ :: tail✝) (Nat.succ n✝) = some y

Next tactic:
simp only [List.get?, List.zip_cons_cons, List.applyId_cons] at h₂ ⊢