l3lab/ntp-mathlib huggingface dataset:
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
        simp only [List.get?, List.zip_cons_cons, List.applyId_cons] at h₂ ⊢
        

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? xs 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'
⊢ (if x' = x then head✝ else applyId (zip xs tail✝) x) = y ↔ get? tail✝ n✝ = some y

Next tactic:
rw [if_neg]
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
        simp only [List.get?, List.zip_cons_cons, List.applyId_cons] at h₂ ⊢
        rw [if_neg]
        · 

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? xs 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 xs tail✝) x = y ↔ get? tail✝ n✝ = some y

Next tactic:
apply xs_ih
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
        simp only [List.get?, List.zip_cons_cons, List.applyId_cons] at h₂ ⊢
        rw [if_neg]
        · apply xs_ih <;> 

Proof state:
case cons.succ.cons.cons.h₀
α : 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? xs 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'
⊢ Nodup xs

Next tactic:
solve_by_elim [Nat.succ.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]
    · 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 <;> 

Proof state:
case cons.succ.cons.cons.h₁
α : 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? xs 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'
⊢ length xs = length tail✝

Next tactic:
solve_by_elim [Nat.succ.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]
    · 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 <;> 

Proof state:
case cons.succ.cons.cons.h₂
α : 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? xs 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'
⊢ get? xs n✝ = some x

Next tactic:
solve_by_elim [Nat.succ.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]
    · 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]
        · 

Proof state:
case cons.succ.cons.cons.hnc
α : 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? xs 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'
⊢ ¬x' = x

Next tactic:
apply 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
        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₀; 

Proof state:
case cons.succ.cons.cons.hnc.a
α : 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? xs 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'
⊢ x ∈ xs

Next tactic:
apply List.get?_mem h₂
theorem applyId_mem_iff [DecidableEq α] {xs ys : List α} (h₀ : List.Nodup xs) (h₁ : xs ~ ys)
    (x : α) : List.applyId.{u} (xs.zip ys) x ∈ ys ↔ x ∈ xs := by
  

Proof state:
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : Nodup xs
h₁ : xs ~ ys
x : α
⊢ applyId (zip xs ys) x ∈ ys ↔ x ∈ xs

Next tactic:
simp only [List.applyId]
theorem applyId_mem_iff [DecidableEq α] {xs ys : List α} (h₀ : List.Nodup xs) (h₁ : xs ~ ys)
    (x : α) : List.applyId.{u} (xs.zip ys) x ∈ ys ↔ x ∈ xs := by
  simp only [List.applyId]
  

Proof state:
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : Nodup xs
h₁ : xs ~ ys
x : α
⊢ Option.getD (dlookup x (map Prod.toSigma (zip xs ys))) x ∈ ys ↔ x ∈ xs

Next tactic:
cases h₃ : List.dlookup x (List.map Prod.toSigma (xs.zip ys)) with
  | none =>
    dsimp [Option.getD]
    rw [h₁.mem_iff]
  | some val =>
    have h₂ : ys.Nodup := h₁.nodup_iff.1 h₀
    replace h₁ : xs.length = ys.length := h₁.length_eq
    dsimp
    induction xs generalizing ys with
    | nil => contradiction
    | cons x' xs xs_ih =>
      cases' ys with y ys
      · cases h₃
      dsimp [List.dlookup] at h₃; split_ifs at h₃ with h
      · rw [Option.some_inj] at h₃
        subst x'; subst val
        simp only [List.mem_cons, true_or_iff, eq_self_iff_true]
      · cases' h₀ with _ _ h₀ h₅
        cases' h₂ with _ _ h₂ h₄
        have h₆ := Nat.succ.inj h₁
        specialize xs_ih h₅ h₃ h₄ h₆
        simp only [Ne.symm h, xs_ih, List.mem_cons, false_or_iff]
        suffices val ∈ ys by tauto
        erw [← Option.mem_def, List.mem_dlookup_iff] at h₃
        simp only [Prod.toSigma, List.mem_map, heq_iff_eq, Prod.exists] at h₃
        rcases h₃ with ⟨a, b, h₃, h₄, h₅⟩
        apply (List.mem_zip h₃).2
        simp only [List.NodupKeys, List.keys, comp, Prod.fst_toSigma, List.map_map]
        rwa [List.map_fst_zip _ _ (le_of_eq h₆)]
theorem applyId_mem_iff [DecidableEq α] {xs ys : List α} (h₀ : List.Nodup xs) (h₁ : xs ~ ys)
    (x : α) : List.applyId.{u} (xs.zip ys) x ∈ ys ↔ x ∈ xs := by
  simp only [List.applyId]
  

Proof state:
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : Nodup xs
h₁ : xs ~ ys
x : α
x✝ : Option α
h₃ : dlookup x (map Prod.toSigma (zip xs ys)) = x✝
⊢ Option.getD x✝ x ∈ ys ↔ x ∈ xs

Next tactic:
cases h₃ : List.dlookup x (List.map Prod.toSigma (xs.zip ys)) with
  | none =>
    dsimp [Option.getD]
    rw [h₁.mem_iff]
  | some val =>
    have h₂ : ys.Nodup := h₁.nodup_iff.1 h₀
    replace h₁ : xs.length = ys.length := h₁.length_eq
    dsimp
    induction xs generalizing ys with
    | nil => contradiction
    | cons x' xs xs_ih =>
      cases' ys with y ys
      · cases h₃
      dsimp [List.dlookup] at h₃; split_ifs at h₃ with h
      · rw [Option.some_inj] at h₃
        subst x'; subst val
        simp only [List.mem_cons, true_or_iff, eq_self_iff_true]
      · cases' h₀ with _ _ h₀ h₅
        cases' h₂ with _ _ h₂ h₄
        have h₆ := Nat.succ.inj h₁
        specialize xs_ih h₅ h₃ h₄ h₆
        simp only [Ne.symm h, xs_ih, List.mem_cons, false_or_iff]
        suffices val ∈ ys by tauto
        erw [← Option.mem_def, List.mem_dlookup_iff] at h₃
        simp only [Prod.toSigma, List.mem_map, heq_iff_eq, Prod.exists] at h₃
        rcases h₃ with ⟨a, b, h₃, h₄, h₅⟩
        apply (List.mem_zip h₃).2
        simp only [List.NodupKeys, List.keys, comp, Prod.fst_toSigma, List.map_map]
        rwa [List.map_fst_zip _ _ (le_of_eq h₆)]
theorem applyId_mem_iff [DecidableEq α] {xs ys : List α} (h₀ : List.Nodup xs) (h₁ : xs ~ ys)
    (x : α) : List.applyId.{u} (xs.zip ys) x ∈ ys ↔ x ∈ xs := by
  simp only [List.applyId]
  cases h₃ : List.dlookup x (List.map Prod.toSigma (xs.zip ys)) with
  

Proof state:
case none
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : Nodup xs
h₁ : xs ~ ys
x : α
h₃ : dlookup x (map Prod.toSigma (zip xs ys)) = none
⊢ Option.getD none x ∈ ys ↔ x ∈ xs

Next tactic:
| none =>
    dsimp [Option.getD]
    rw [h₁.mem_iff]
theorem applyId_mem_iff [DecidableEq α] {xs ys : List α} (h₀ : List.Nodup xs) (h₁ : xs ~ ys)
    (x : α) : List.applyId.{u} (xs.zip ys) x ∈ ys ↔ x ∈ xs := by
  simp only [List.applyId]
  cases h₃ : List.dlookup x (List.map Prod.toSigma (xs.zip ys)) with
  | none =>
    

Proof state:
case none
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : Nodup xs
h₁ : xs ~ ys
x : α
h₃ : dlookup x (map Prod.toSigma (zip xs ys)) = none
⊢ Option.getD none x ∈ ys ↔ x ∈ xs

Next tactic:
dsimp [Option.getD]
theorem applyId_mem_iff [DecidableEq α] {xs ys : List α} (h₀ : List.Nodup xs) (h₁ : xs ~ ys)
    (x : α) : List.applyId.{u} (xs.zip ys) x ∈ ys ↔ x ∈ xs := by
  simp only [List.applyId]
  cases h₃ : List.dlookup x (List.map Prod.toSigma (xs.zip ys)) with
  | none =>
    dsimp [Option.getD]
    

Proof state:
case none
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : Nodup xs
h₁ : xs ~ ys
x : α
h₃ : dlookup x (map Prod.toSigma (zip xs ys)) = none
⊢ x ∈ ys ↔ x ∈ xs

Next tactic:
rw [h₁.mem_iff]
theorem applyId_mem_iff [DecidableEq α] {xs ys : List α} (h₀ : List.Nodup xs) (h₁ : xs ~ ys)
    (x : α) : List.applyId.{u} (xs.zip ys) x ∈ ys ↔ x ∈ xs := by
  simp only [List.applyId]
  cases h₃ : List.dlookup x (List.map Prod.toSigma (xs.zip ys)) with
  | none =>
    dsimp [Option.getD]
    rw [h₁.mem_iff]
  

Proof state:
case some
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : Nodup xs
h₁ : xs ~ ys
x val : α
h₃ : dlookup x (map Prod.toSigma (zip xs ys)) = some val
⊢ Option.getD (some val) x ∈ ys ↔ x ∈ xs

Next tactic:
| some val =>
    have h₂ : ys.Nodup := h₁.nodup_iff.1 h₀
    replace h₁ : xs.length = ys.length := h₁.length_eq
    dsimp
    induction xs generalizing ys with
    | nil => contradiction
    | cons x' xs xs_ih =>
      cases' ys with y ys
      · cases h₃
      dsimp [List.dlookup] at h₃; split_ifs at h₃ with h
      · rw [Option.some_inj] at h₃
        subst x'; subst val
        simp only [List.mem_cons, true_or_iff, eq_self_iff_true]
      · cases' h₀ with _ _ h₀ h₅
        cases' h₂ with _ _ h₂ h₄
        have h₆ := Nat.succ.inj h₁
        specialize xs_ih h₅ h₃ h₄ h₆
        simp only [Ne.symm h, xs_ih, List.mem_cons, false_or_iff]
        suffices val ∈ ys by tauto
        erw [← Option.mem_def, List.mem_dlookup_iff] at h₃
        simp only [Prod.toSigma, List.mem_map, heq_iff_eq, Prod.exists] at h₃
        rcases h₃ with ⟨a, b, h₃, h₄, h₅⟩
        apply (List.mem_zip h₃).2
        simp only [List.NodupKeys, List.keys, comp, Prod.fst_toSigma, List.map_map]
        rwa [List.map_fst_zip _ _ (le_of_eq h₆)]
theorem applyId_mem_iff [DecidableEq α] {xs ys : List α} (h₀ : List.Nodup xs) (h₁ : xs ~ ys)
    (x : α) : List.applyId.{u} (xs.zip ys) x ∈ ys ↔ x ∈ xs := by
  simp only [List.applyId]
  cases h₃ : List.dlookup x (List.map Prod.toSigma (xs.zip ys)) with
  | none =>
    dsimp [Option.getD]
    rw [h₁.mem_iff]
  | some val =>
    

Proof state:
case some
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : Nodup xs
h₁ : xs ~ ys
x val : α
h₃ : dlookup x (map Prod.toSigma (zip xs ys)) = some val
⊢ Option.getD (some val) x ∈ ys ↔ x ∈ xs

Next tactic:
have h₂ : ys.Nodup := h₁.nodup_iff.1 h₀
theorem applyId_mem_iff [DecidableEq α] {xs ys : List α} (h₀ : List.Nodup xs) (h₁ : xs ~ ys)
    (x : α) : List.applyId.{u} (xs.zip ys) x ∈ ys ↔ x ∈ xs := by
  simp only [List.applyId]
  cases h₃ : List.dlookup x (List.map Prod.toSigma (xs.zip ys)) with
  | none =>
    dsimp [Option.getD]
    rw [h₁.mem_iff]
  | some val =>
    have h₂ : ys.Nodup := h₁.nodup_iff.1 h₀
    

Proof state:
case some
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : Nodup xs
h₁ : xs ~ ys
x val : α
h₃ : dlookup x (map Prod.toSigma (zip xs ys)) = some val
h₂ : Nodup ys
⊢ Option.getD (some val) x ∈ ys ↔ x ∈ xs

Next tactic:
replace h₁ : xs.length = ys.length := h₁.length_eq
theorem applyId_mem_iff [DecidableEq α] {xs ys : List α} (h₀ : List.Nodup xs) (h₁ : xs ~ ys)
    (x : α) : List.applyId.{u} (xs.zip ys) x ∈ ys ↔ x ∈ xs := by
  simp only [List.applyId]
  cases h₃ : List.dlookup x (List.map Prod.toSigma (xs.zip ys)) with
  | none =>
    dsimp [Option.getD]
    rw [h₁.mem_iff]
  | some val =>
    have h₂ : ys.Nodup := h₁.nodup_iff.1 h₀
    replace h₁ : xs.length = ys.length := h₁.length_eq
    

Proof state:
case some
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : Nodup xs
x val : α
h₃ : dlookup x (map Prod.toSigma (zip xs ys)) = some val
h₂ : Nodup ys
h₁ : length xs = length ys
⊢ Option.getD (some val) x ∈ ys ↔ x ∈ xs

Next tactic:
dsimp
theorem applyId_mem_iff [DecidableEq α] {xs ys : List α} (h₀ : List.Nodup xs) (h₁ : xs ~ ys)
    (x : α) : List.applyId.{u} (xs.zip ys) x ∈ ys ↔ x ∈ xs := by
  simp only [List.applyId]
  cases h₃ : List.dlookup x (List.map Prod.toSigma (xs.zip ys)) with
  | none =>
    dsimp [Option.getD]
    rw [h₁.mem_iff]
  | some val =>
    have h₂ : ys.Nodup := h₁.nodup_iff.1 h₀
    replace h₁ : xs.length = ys.length := h₁.length_eq
    dsimp
    

Proof state:
case some
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : Nodup xs
x val : α
h₃ : dlookup x (map Prod.toSigma (zip xs ys)) = some val
h₂ : Nodup ys
h₁ : length xs = length ys
⊢ val ∈ ys ↔ x ∈ xs

Next tactic:
induction xs generalizing ys with
    | nil => contradiction
    | cons x' xs xs_ih =>
      cases' ys with y ys
      · cases h₃
      dsimp [List.dlookup] at h₃; split_ifs at h₃ with h
      · rw [Option.some_inj] at h₃
        subst x'; subst val
        simp only [List.mem_cons, true_or_iff, eq_self_iff_true]
      · cases' h₀ with _ _ h₀ h₅
        cases' h₂ with _ _ h₂ h₄
        have h₆ := Nat.succ.inj h₁
        specialize xs_ih h₅ h₃ h₄ h₆
        simp only [Ne.symm h, xs_ih, List.mem_cons, false_or_iff]
        suffices val ∈ ys by tauto
        erw [← Option.mem_def, List.mem_dlookup_iff] at h₃
        simp only [Prod.toSigma, List.mem_map, heq_iff_eq, Prod.exists] at h₃
        rcases h₃ with ⟨a, b, h₃, h₄, h₅⟩
        apply (List.mem_zip h₃).2
        simp only [List.NodupKeys, List.keys, comp, Prod.fst_toSigma, List.map_map]
        rwa [List.map_fst_zip _ _ (le_of_eq h₆)]
theorem applyId_mem_iff [DecidableEq α] {xs ys : List α} (h₀ : List.Nodup xs) (h₁ : xs ~ ys)
    (x : α) : List.applyId.{u} (xs.zip ys) x ∈ ys ↔ x ∈ xs := by
  simp only [List.applyId]
  cases h₃ : List.dlookup x (List.map Prod.toSigma (xs.zip ys)) with
  | none =>
    dsimp [Option.getD]
    rw [h₁.mem_iff]
  | some val =>
    have h₂ : ys.Nodup := h₁.nodup_iff.1 h₀
    replace h₁ : xs.length = ys.length := h₁.length_eq
    dsimp
    induction xs generalizing ys with
    

Proof state:
case some.nil
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
x val : α
ys : List α
h₀ : Nodup []
h₃ : dlookup x (map Prod.toSigma (zip [] ys)) = some val
h₂ : Nodup ys
h₁ : length [] = length ys
⊢ val ∈ ys ↔ x ∈ []

Next tactic:
| nil => contradiction
theorem applyId_mem_iff [DecidableEq α] {xs ys : List α} (h₀ : List.Nodup xs) (h₁ : xs ~ ys)
    (x : α) : List.applyId.{u} (xs.zip ys) x ∈ ys ↔ x ∈ xs := by
  simp only [List.applyId]
  cases h₃ : List.dlookup x (List.map Prod.toSigma (xs.zip ys)) with
  | none =>
    dsimp [Option.getD]
    rw [h₁.mem_iff]
  | some val =>
    have h₂ : ys.Nodup := h₁.nodup_iff.1 h₀
    replace h₁ : xs.length = ys.length := h₁.length_eq
    dsimp
    induction xs generalizing ys with
    | nil => 

Proof state:
case some.nil
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
x val : α
ys : List α
h₀ : Nodup []
h₃ : dlookup x (map Prod.toSigma (zip [] ys)) = some val
h₂ : Nodup ys
h₁ : length [] = length ys
⊢ val ∈ ys ↔ x ∈ []

Next tactic:
contradiction
theorem applyId_mem_iff [DecidableEq α] {xs ys : List α} (h₀ : List.Nodup xs) (h₁ : xs ~ ys)
    (x : α) : List.applyId.{u} (xs.zip ys) x ∈ ys ↔ x ∈ xs := by
  simp only [List.applyId]
  cases h₃ : List.dlookup x (List.map Prod.toSigma (xs.zip ys)) with
  | none =>
    dsimp [Option.getD]
    rw [h₁.mem_iff]
  | some val =>
    have h₂ : ys.Nodup := h₁.nodup_iff.1 h₀
    replace h₁ : xs.length = ys.length := h₁.length_eq
    dsimp
    induction xs generalizing ys with
    | nil => contradiction
    

Proof state:
case some.cons
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
x val x' : α
xs : List α
xs_ih :
  ∀ {ys : List α},
    Nodup xs →
      dlookup x (map Prod.toSigma (zip xs ys)) = some val → Nodup ys → length xs = length ys → (val ∈ ys ↔ x ∈ xs)
ys : List α
h₀ : Nodup (x' :: xs)
h₃ : dlookup x (map Prod.toSigma (zip (x' :: xs) ys)) = some val
h₂ : Nodup ys
h₁ : length (x' :: xs) = length ys
⊢ val ∈ ys ↔ x ∈ x' :: xs

Next tactic:
| cons x' xs xs_ih =>
      cases' ys with y ys
      · cases h₃
      dsimp [List.dlookup] at h₃; split_ifs at h₃ with h
      · rw [Option.some_inj] at h₃
        subst x'; subst val
        simp only [List.mem_cons, true_or_iff, eq_self_iff_true]
      · cases' h₀ with _ _ h₀ h₅
        cases' h₂ with _ _ h₂ h₄
        have h₆ := Nat.succ.inj h₁
        specialize xs_ih h₅ h₃ h₄ h₆
        simp only [Ne.symm h, xs_ih, List.mem_cons, false_or_iff]
        suffices val ∈ ys by tauto
        erw [← Option.mem_def, List.mem_dlookup_iff] at h₃
        simp only [Prod.toSigma, List.mem_map, heq_iff_eq, Prod.exists] at h₃
        rcases h₃ with ⟨a, b, h₃, h₄, h₅⟩
        apply (List.mem_zip h₃).2
        simp only [List.NodupKeys, List.keys, comp, Prod.fst_toSigma, List.map_map]
        rwa [List.map_fst_zip _ _ (le_of_eq h₆)]
theorem applyId_mem_iff [DecidableEq α] {xs ys : List α} (h₀ : List.Nodup xs) (h₁ : xs ~ ys)
    (x : α) : List.applyId.{u} (xs.zip ys) x ∈ ys ↔ x ∈ xs := by
  simp only [List.applyId]
  cases h₃ : List.dlookup x (List.map Prod.toSigma (xs.zip ys)) with
  | none =>
    dsimp [Option.getD]
    rw [h₁.mem_iff]
  | some val =>
    have h₂ : ys.Nodup := h₁.nodup_iff.1 h₀
    replace h₁ : xs.length = ys.length := h₁.length_eq
    dsimp
    induction xs generalizing ys with
    | nil => contradiction
    | cons x' xs xs_ih =>
      

Proof state:
case some.cons
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
x val x' : α
xs : List α
xs_ih :
  ∀ {ys : List α},
    Nodup xs →
      dlookup x (map Prod.toSigma (zip xs ys)) = some val → Nodup ys → length xs = length ys → (val ∈ ys ↔ x ∈ xs)
ys : List α
h₀ : Nodup (x' :: xs)
h₃ : dlookup x (map Prod.toSigma (zip (x' :: xs) ys)) = some val
h₂ : Nodup ys
h₁ : length (x' :: xs) = length ys
⊢ val ∈ ys ↔ x ∈ x' :: xs

Next tactic:
cases' ys with y ys