l3lab/ntp-mathlib huggingface dataset:
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 =>
      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₅⟩
        

Proof state:
case neg.cons.cons.intro.intro.intro.refl
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
x val x' : α
xs : List α
y : α
ys : List α
h₁ : length (x' :: xs) = length (y :: ys)
h : ¬x' = x
h₅ : List.Pairwise (fun x x_1 => x ≠ x_1) xs
h₀ : ∀ a' ∈ xs, x' ≠ a'
h₄ : List.Pairwise (fun x x_1 => x ≠ x_1) ys
h₂ : ∀ a' ∈ ys, y ≠ a'
h₆ : length xs = length ys
xs_ih : val ∈ ys ↔ x ∈ xs
h₃ : (x, val) ∈ zip xs ys
⊢ val ∈ ys
case neg.cons.cons
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
x val x' : α
xs : List α
y : α
ys : List α
h₁ : length (x' :: xs) = length (y :: ys)
h : ¬x' = x
h₃ : val ∈ dlookup x (map Prod.toSigma (zip xs ys))
h₅ : List.Pairwise (fun x x_1 => x ≠ x_1) xs
h₀ : ∀ a' ∈ xs, x' ≠ a'
h₄ : List.Pairwise (fun x x_1 => x ≠ x_1) ys
h₂ : ∀ a' ∈ ys, y ≠ a'
h₆ : length xs = length ys
xs_ih : val ∈ ys ↔ x ∈ xs
⊢ NodupKeys (map Prod.toSigma (zip xs ys))

Next tactic:
apply (List.mem_zip h₃).2
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 =>
      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
        

Proof state:
case neg.cons.cons
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
x val x' : α
xs : List α
y : α
ys : List α
h₁ : length (x' :: xs) = length (y :: ys)
h : ¬x' = x
h₃ : val ∈ dlookup x (map Prod.toSigma (zip xs ys))
h₅ : List.Pairwise (fun x x_1 => x ≠ x_1) xs
h₀ : ∀ a' ∈ xs, x' ≠ a'
h₄ : List.Pairwise (fun x x_1 => x ≠ x_1) ys
h₂ : ∀ a' ∈ ys, y ≠ a'
h₆ : length xs = length ys
xs_ih : val ∈ ys ↔ x ∈ xs
⊢ NodupKeys (map Prod.toSigma (zip xs ys))

Next tactic:
simp only [List.NodupKeys, List.keys, comp, Prod.fst_toSigma, List.map_map]
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 =>
      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]
        

Proof state:
case neg.cons.cons
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
x val x' : α
xs : List α
y : α
ys : List α
h₁ : length (x' :: xs) = length (y :: ys)
h : ¬x' = x
h₃ : val ∈ dlookup x (map Prod.toSigma (zip xs ys))
h₅ : List.Pairwise (fun x x_1 => x ≠ x_1) xs
h₀ : ∀ a' ∈ xs, x' ≠ a'
h₄ : List.Pairwise (fun x x_1 => x ≠ x_1) ys
h₂ : ∀ a' ∈ ys, y ≠ a'
h₆ : length xs = length ys
xs_ih : val ∈ ys ↔ x ∈ xs
⊢ Nodup (map (fun x => x.1) (zip xs ys))

Next tactic:
rwa [List.map_fst_zip _ _ (le_of_eq h₆)]
theorem List.applyId_eq_self [DecidableEq α] {xs ys : List α} (x : α) :
    x ∉ xs → List.applyId.{u} (xs.zip ys) x = x := by
  

Proof state:
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
x : α
⊢ x ∉ xs → applyId (zip xs ys) x = x

Next tactic:
intro h
theorem List.applyId_eq_self [DecidableEq α] {xs ys : List α} (x : α) :
    x ∉ xs → List.applyId.{u} (xs.zip ys) x = x := by
  intro h
  

Proof state:
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
x : α
h : x ∉ xs
⊢ applyId (zip xs ys) x = x

Next tactic:
dsimp [List.applyId]
theorem List.applyId_eq_self [DecidableEq α] {xs ys : List α} (x : α) :
    x ∉ xs → List.applyId.{u} (xs.zip ys) x = x := by
  intro h
  dsimp [List.applyId]
  

Proof state:
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
x : α
h : x ∉ xs
⊢ Option.getD (dlookup x (map Prod.toSigma (zip xs ys))) x = x

Next tactic:
rw [List.dlookup_eq_none.2]
theorem List.applyId_eq_self [DecidableEq α] {xs ys : List α} (x : α) :
    x ∉ xs → List.applyId.{u} (xs.zip ys) x = x := by
  intro h
  dsimp [List.applyId]
  rw [List.dlookup_eq_none.2]; 

Proof state:
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
x : α
h : x ∉ xs
⊢ Option.getD none x = x
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
x : α
h : x ∉ xs
⊢ x ∉ keys (map Prod.toSigma (zip xs ys))

Next tactic:
rfl
theorem List.applyId_eq_self [DecidableEq α] {xs ys : List α} (x : α) :
    x ∉ xs → List.applyId.{u} (xs.zip ys) x = x := by
  intro h
  dsimp [List.applyId]
  rw [List.dlookup_eq_none.2]; rfl
  

Proof state:
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
x : α
h : x ∉ xs
⊢ x ∉ keys (map Prod.toSigma (zip xs ys))

Next tactic:
simp only [List.keys, not_exists, Prod.toSigma, exists_and_right, exists_eq_right, List.mem_map,
    Function.comp_apply, List.map_map, Prod.exists]
theorem List.applyId_eq_self [DecidableEq α] {xs ys : List α} (x : α) :
    x ∉ xs → List.applyId.{u} (xs.zip ys) x = x := by
  intro h
  dsimp [List.applyId]
  rw [List.dlookup_eq_none.2]; rfl
  simp only [List.keys, not_exists, Prod.toSigma, exists_and_right, exists_eq_right, List.mem_map,
    Function.comp_apply, List.map_map, Prod.exists]
  

Proof state:
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
x : α
h : x ∉ xs
⊢ ∀ (x_1 : α), (x, x_1) ∉ zip xs ys

Next tactic:
intro y hy
theorem List.applyId_eq_self [DecidableEq α] {xs ys : List α} (x : α) :
    x ∉ xs → List.applyId.{u} (xs.zip ys) x = x := by
  intro h
  dsimp [List.applyId]
  rw [List.dlookup_eq_none.2]; rfl
  simp only [List.keys, not_exists, Prod.toSigma, exists_and_right, exists_eq_right, List.mem_map,
    Function.comp_apply, List.map_map, Prod.exists]
  intro y hy
  

Proof state:
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
x : α
h : x ∉ xs
y : α
hy : (x, y) ∈ zip xs ys
⊢ False

Next tactic:
exact h (List.mem_zip hy).1
theorem applyId_injective [DecidableEq α] {xs ys : List α} (h₀ : List.Nodup xs) (h₁ : xs ~ ys) :
    Injective.{u + 1, u + 1} (List.applyId (xs.zip ys)) := by
  

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

Next tactic:
intro x y h
theorem applyId_injective [DecidableEq α] {xs ys : List α} (h₀ : List.Nodup xs) (h₁ : xs ~ ys) :
    Injective.{u + 1, u + 1} (List.applyId (xs.zip ys)) := by
  intro x y h
  

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

Next tactic:
by_cases hx : x ∈ xs
theorem applyId_injective [DecidableEq α] {xs ys : List α} (h₀ : List.Nodup xs) (h₁ : xs ~ ys) :
    Injective.{u + 1, u + 1} (List.applyId (xs.zip ys)) := by
  intro x y h
  by_cases hx : x ∈ xs <;> 

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

Next tactic:
by_cases hy : y ∈ xs
theorem applyId_injective [DecidableEq α] {xs ys : List α} (h₀ : List.Nodup xs) (h₁ : xs ~ ys) :
    Injective.{u + 1, u + 1} (List.applyId (xs.zip ys)) := by
  intro x y h
  by_cases hx : x ∈ xs <;> 

Proof state:
case neg
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : Nodup xs
h₁ : xs ~ ys
x y : α
h : applyId (zip xs ys) x = applyId (zip xs ys) y
hx : x ∉ xs
⊢ x = y

Next tactic:
by_cases hy : y ∈ xs
theorem applyId_injective [DecidableEq α] {xs ys : List α} (h₀ : List.Nodup xs) (h₁ : xs ~ ys) :
    Injective.{u + 1, u + 1} (List.applyId (xs.zip ys)) := by
  intro x y h
  by_cases hx : x ∈ xs <;> by_cases hy : y ∈ xs
  · 

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

Next tactic:
rw [List.mem_iff_get?] at hx hy
theorem applyId_injective [DecidableEq α] {xs ys : List α} (h₀ : List.Nodup xs) (h₁ : xs ~ ys) :
    Injective.{u + 1, u + 1} (List.applyId (xs.zip ys)) := by
  intro x y h
  by_cases hx : x ∈ xs <;> by_cases hy : y ∈ xs
  · rw [List.mem_iff_get?] at hx hy
    

Proof state:
case pos
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : Nodup xs
h₁ : xs ~ ys
x y : α
h : applyId (zip xs ys) x = applyId (zip xs ys) y
hx : ∃ n, get? xs n = some x
hy : ∃ n, get? xs n = some y
⊢ x = y

Next tactic:
cases' hx with i hx
theorem applyId_injective [DecidableEq α] {xs ys : List α} (h₀ : List.Nodup xs) (h₁ : xs ~ ys) :
    Injective.{u + 1, u + 1} (List.applyId (xs.zip ys)) := by
  intro x y h
  by_cases hx : x ∈ xs <;> by_cases hy : y ∈ xs
  · rw [List.mem_iff_get?] at hx hy
    cases' hx with i hx
    

Proof state:
case pos.intro
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : Nodup xs
h₁ : xs ~ ys
x y : α
h : applyId (zip xs ys) x = applyId (zip xs ys) y
hy : ∃ n, get? xs n = some y
i : ℕ
hx : get? xs i = some x
⊢ x = y

Next tactic:
cases' hy with j hy
theorem applyId_injective [DecidableEq α] {xs ys : List α} (h₀ : List.Nodup xs) (h₁ : xs ~ ys) :
    Injective.{u + 1, u + 1} (List.applyId (xs.zip ys)) := by
  intro x y h
  by_cases hx : x ∈ xs <;> by_cases hy : y ∈ xs
  · rw [List.mem_iff_get?] at hx hy
    cases' hx with i hx
    cases' hy with j hy
    

Proof state:
case pos.intro.intro
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : Nodup xs
h₁ : xs ~ ys
x y : α
h : applyId (zip xs ys) x = applyId (zip xs ys) y
i : ℕ
hx : get? xs i = some x
j : ℕ
hy : get? xs j = some y
⊢ x = y

Next tactic:
suffices some x = some y by injection this
theorem applyId_injective [DecidableEq α] {xs ys : List α} (h₀ : List.Nodup xs) (h₁ : xs ~ ys) :
    Injective.{u + 1, u + 1} (List.applyId (xs.zip ys)) := by
  intro x y h
  by_cases hx : x ∈ xs <;> by_cases hy : y ∈ xs
  · rw [List.mem_iff_get?] at hx hy
    cases' hx with i hx
    cases' hy with j hy
    suffices some x = some y by 

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

Next tactic:
injection this
theorem applyId_injective [DecidableEq α] {xs ys : List α} (h₀ : List.Nodup xs) (h₁ : xs ~ ys) :
    Injective.{u + 1, u + 1} (List.applyId (xs.zip ys)) := by
  intro x y h
  by_cases hx : x ∈ xs <;> by_cases hy : y ∈ xs
  · rw [List.mem_iff_get?] at hx hy
    cases' hx with i hx
    cases' hy with j hy
    suffices some x = some y by injection this
    

Proof state:
case pos.intro.intro
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : Nodup xs
h₁ : xs ~ ys
x y : α
h : applyId (zip xs ys) x = applyId (zip xs ys) y
i : ℕ
hx : get? xs i = some x
j : ℕ
hy : get? xs j = some y
⊢ some x = some y

Next tactic:
have h₂ := h₁.length_eq
theorem applyId_injective [DecidableEq α] {xs ys : List α} (h₀ : List.Nodup xs) (h₁ : xs ~ ys) :
    Injective.{u + 1, u + 1} (List.applyId (xs.zip ys)) := by
  intro x y h
  by_cases hx : x ∈ xs <;> by_cases hy : y ∈ xs
  · rw [List.mem_iff_get?] at hx hy
    cases' hx with i hx
    cases' hy with j hy
    suffices some x = some y by injection this
    have h₂ := h₁.length_eq
    

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

Next tactic:
rw [List.applyId_zip_eq h₀ h₂ _ _ _ hx] at h
theorem applyId_injective [DecidableEq α] {xs ys : List α} (h₀ : List.Nodup xs) (h₁ : xs ~ ys) :
    Injective.{u + 1, u + 1} (List.applyId (xs.zip ys)) := by
  intro x y h
  by_cases hx : x ∈ xs <;> by_cases hy : y ∈ xs
  · rw [List.mem_iff_get?] at hx hy
    cases' hx with i hx
    cases' hy with j hy
    suffices some x = some y by injection this
    have h₂ := h₁.length_eq
    rw [List.applyId_zip_eq h₀ h₂ _ _ _ hx] at h
    

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

Next tactic:
rw [← hx, ← hy]
theorem applyId_injective [DecidableEq α] {xs ys : List α} (h₀ : List.Nodup xs) (h₁ : xs ~ ys) :
    Injective.{u + 1, u + 1} (List.applyId (xs.zip ys)) := by
  intro x y h
  by_cases hx : x ∈ xs <;> by_cases hy : y ∈ xs
  · rw [List.mem_iff_get?] at hx hy
    cases' hx with i hx
    cases' hy with j hy
    suffices some x = some y by injection this
    have h₂ := h₁.length_eq
    rw [List.applyId_zip_eq h₀ h₂ _ _ _ hx] at h
    rw [← hx, ← hy]; 

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

Next tactic:
congr
theorem applyId_injective [DecidableEq α] {xs ys : List α} (h₀ : List.Nodup xs) (h₁ : xs ~ ys) :
    Injective.{u + 1, u + 1} (List.applyId (xs.zip ys)) := by
  intro x y h
  by_cases hx : x ∈ xs <;> by_cases hy : y ∈ xs
  · rw [List.mem_iff_get?] at hx hy
    cases' hx with i hx
    cases' hy with j hy
    suffices some x = some y by injection this
    have h₂ := h₁.length_eq
    rw [List.applyId_zip_eq h₀ h₂ _ _ _ hx] at h
    rw [← hx, ← hy]; congr
    

Proof state:
case pos.intro.intro.e_a
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : Nodup xs
h₁ : xs ~ ys
x y : α
i : ℕ
h : get? ys i = some (applyId (zip xs ys) y)
hx : get? xs i = some x
j : ℕ
hy : get? xs j = some y
h₂ : length xs = length ys
⊢ i = j

Next tactic:
apply List.get?_injective _ (h₁.nodup_iff.1 h₀)
theorem applyId_injective [DecidableEq α] {xs ys : List α} (h₀ : List.Nodup xs) (h₁ : xs ~ ys) :
    Injective.{u + 1, u + 1} (List.applyId (xs.zip ys)) := by
  intro x y h
  by_cases hx : x ∈ xs <;> by_cases hy : y ∈ xs
  · rw [List.mem_iff_get?] at hx hy
    cases' hx with i hx
    cases' hy with j hy
    suffices some x = some y by injection this
    have h₂ := h₁.length_eq
    rw [List.applyId_zip_eq h₀ h₂ _ _ _ hx] at h
    rw [← hx, ← hy]; congr
    apply List.get?_injective _ (h₁.nodup_iff.1 h₀)
    · 

Proof state:
case pos.intro.intro.e_a
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : Nodup xs
h₁ : xs ~ ys
x y : α
i : ℕ
h : get? ys i = some (applyId (zip xs ys) y)
hx : get? xs i = some x
j : ℕ
hy : get? xs j = some y
h₂ : length xs = length ys
⊢ get? ys i = get? ys j

Next tactic:
symm
theorem applyId_injective [DecidableEq α] {xs ys : List α} (h₀ : List.Nodup xs) (h₁ : xs ~ ys) :
    Injective.{u + 1, u + 1} (List.applyId (xs.zip ys)) := by
  intro x y h
  by_cases hx : x ∈ xs <;> by_cases hy : y ∈ xs
  · rw [List.mem_iff_get?] at hx hy
    cases' hx with i hx
    cases' hy with j hy
    suffices some x = some y by injection this
    have h₂ := h₁.length_eq
    rw [List.applyId_zip_eq h₀ h₂ _ _ _ hx] at h
    rw [← hx, ← hy]; congr
    apply List.get?_injective _ (h₁.nodup_iff.1 h₀)
    · symm; 

Proof state:
case pos.intro.intro.e_a
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : Nodup xs
h₁ : xs ~ ys
x y : α
i : ℕ
h : get? ys i = some (applyId (zip xs ys) y)
hx : get? xs i = some x
j : ℕ
hy : get? xs j = some y
h₂ : length xs = length ys
⊢ get? ys j = get? ys i

Next tactic:
rw [h]
theorem applyId_injective [DecidableEq α] {xs ys : List α} (h₀ : List.Nodup xs) (h₁ : xs ~ ys) :
    Injective.{u + 1, u + 1} (List.applyId (xs.zip ys)) := by
  intro x y h
  by_cases hx : x ∈ xs <;> by_cases hy : y ∈ xs
  · rw [List.mem_iff_get?] at hx hy
    cases' hx with i hx
    cases' hy with j hy
    suffices some x = some y by injection this
    have h₂ := h₁.length_eq
    rw [List.applyId_zip_eq h₀ h₂ _ _ _ hx] at h
    rw [← hx, ← hy]; congr
    apply List.get?_injective _ (h₁.nodup_iff.1 h₀)
    · symm; rw [h]
      

Proof state:
case pos.intro.intro.e_a
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : Nodup xs
h₁ : xs ~ ys
x y : α
i : ℕ
h : get? ys i = some (applyId (zip xs ys) y)
hx : get? xs i = some x
j : ℕ
hy : get? xs j = some y
h₂ : length xs = length ys
⊢ get? ys j = some (applyId (zip xs ys) y)

Next tactic:
rw [← List.applyId_zip_eq]
theorem applyId_injective [DecidableEq α] {xs ys : List α} (h₀ : List.Nodup xs) (h₁ : xs ~ ys) :
    Injective.{u + 1, u + 1} (List.applyId (xs.zip ys)) := by
  intro x y h
  by_cases hx : x ∈ xs <;> by_cases hy : y ∈ xs
  · rw [List.mem_iff_get?] at hx hy
    cases' hx with i hx
    cases' hy with j hy
    suffices some x = some y by injection this
    have h₂ := h₁.length_eq
    rw [List.applyId_zip_eq h₀ h₂ _ _ _ hx] at h
    rw [← hx, ← hy]; congr
    apply List.get?_injective _ (h₁.nodup_iff.1 h₀)
    · symm; rw [h]
      rw [← List.applyId_zip_eq] <;> 

Proof state:
case pos.intro.intro.e_a.h₀
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : Nodup xs
h₁ : xs ~ ys
x y : α
i : ℕ
h : get? ys i = some (applyId (zip xs ys) y)
hx : get? xs i = some x
j : ℕ
hy : get? xs j = some y
h₂ : length xs = length ys
⊢ Nodup xs

Next tactic:
assumption
theorem applyId_injective [DecidableEq α] {xs ys : List α} (h₀ : List.Nodup xs) (h₁ : xs ~ ys) :
    Injective.{u + 1, u + 1} (List.applyId (xs.zip ys)) := by
  intro x y h
  by_cases hx : x ∈ xs <;> by_cases hy : y ∈ xs
  · rw [List.mem_iff_get?] at hx hy
    cases' hx with i hx
    cases' hy with j hy
    suffices some x = some y by injection this
    have h₂ := h₁.length_eq
    rw [List.applyId_zip_eq h₀ h₂ _ _ _ hx] at h
    rw [← hx, ← hy]; congr
    apply List.get?_injective _ (h₁.nodup_iff.1 h₀)
    · symm; rw [h]
      rw [← List.applyId_zip_eq] <;> 

Proof state:
case pos.intro.intro.e_a.h₁
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : Nodup xs
h₁ : xs ~ ys
x y : α
i : ℕ
h : get? ys i = some (applyId (zip xs ys) y)
hx : get? xs i = some x
j : ℕ
hy : get? xs j = some y
h₂ : length xs = length ys
⊢ length xs = length ys

Next tactic:
assumption
theorem applyId_injective [DecidableEq α] {xs ys : List α} (h₀ : List.Nodup xs) (h₁ : xs ~ ys) :
    Injective.{u + 1, u + 1} (List.applyId (xs.zip ys)) := by
  intro x y h
  by_cases hx : x ∈ xs <;> by_cases hy : y ∈ xs
  · rw [List.mem_iff_get?] at hx hy
    cases' hx with i hx
    cases' hy with j hy
    suffices some x = some y by injection this
    have h₂ := h₁.length_eq
    rw [List.applyId_zip_eq h₀ h₂ _ _ _ hx] at h
    rw [← hx, ← hy]; congr
    apply List.get?_injective _ (h₁.nodup_iff.1 h₀)
    · symm; rw [h]
      rw [← List.applyId_zip_eq] <;> 

Proof state:
case pos.intro.intro.e_a.h₂
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : Nodup xs
h₁ : xs ~ ys
x y : α
i : ℕ
h : get? ys i = some (applyId (zip xs ys) y)
hx : get? xs i = some x
j : ℕ
hy : get? xs j = some y
h₂ : length xs = length ys
⊢ get? xs j = some y

Next tactic:
assumption
theorem applyId_injective [DecidableEq α] {xs ys : List α} (h₀ : List.Nodup xs) (h₁ : xs ~ ys) :
    Injective.{u + 1, u + 1} (List.applyId (xs.zip ys)) := by
  intro x y h
  by_cases hx : x ∈ xs <;> by_cases hy : y ∈ xs
  · rw [List.mem_iff_get?] at hx hy
    cases' hx with i hx
    cases' hy with j hy
    suffices some x = some y by injection this
    have h₂ := h₁.length_eq
    rw [List.applyId_zip_eq h₀ h₂ _ _ _ hx] at h
    rw [← hx, ← hy]; congr
    apply List.get?_injective _ (h₁.nodup_iff.1 h₀)
    · symm; rw [h]
      rw [← List.applyId_zip_eq] <;> assumption
    · 

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

Next tactic:
rw [← h₁.length_eq]
theorem applyId_injective [DecidableEq α] {xs ys : List α} (h₀ : List.Nodup xs) (h₁ : xs ~ ys) :
    Injective.{u + 1, u + 1} (List.applyId (xs.zip ys)) := by
  intro x y h
  by_cases hx : x ∈ xs <;> by_cases hy : y ∈ xs
  · rw [List.mem_iff_get?] at hx hy
    cases' hx with i hx
    cases' hy with j hy
    suffices some x = some y by injection this
    have h₂ := h₁.length_eq
    rw [List.applyId_zip_eq h₀ h₂ _ _ _ hx] at h
    rw [← hx, ← hy]; congr
    apply List.get?_injective _ (h₁.nodup_iff.1 h₀)
    · symm; rw [h]
      rw [← List.applyId_zip_eq] <;> assumption
    · rw [← h₁.length_eq]
      

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

Next tactic:
rw [List.get?_eq_some] at hx