[GOAL]
α : Type u
β : Type v
γ : Sort w
inst✝² : Zero β
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
tf : TotalFunction α β
⊢ ∀ (a : α), a ∈ zeroDefaultSupp tf ↔ apply (zeroDefault tf) a ≠ 0
[PROOFSTEP]
intro a
[GOAL]
α : Type u
β : Type v
γ : Sort w
inst✝² : Zero β
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
tf : TotalFunction α β
a : α
⊢ a ∈ zeroDefaultSupp tf ↔ apply (zeroDefault tf) a ≠ 0
[PROOFSTEP]
rcases tf with ⟨A, y⟩
[GOAL]
case withDefault
α : Type u
β : Type v
γ : Sort w
inst✝² : Zero β
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
a : α
A : List ((_ : α) × β)
y : β
⊢ a ∈ zeroDefaultSupp (withDefault A y) ↔ apply (zeroDefault (withDefault A y)) a ≠ 0
[PROOFSTEP]
simp only [apply, zeroDefaultSupp, List.mem_map, List.mem_filter, exists_and_right, List.mem_toFinset, exists_eq_right,
  Sigma.exists, Ne.def, zeroDefault]
[GOAL]
case withDefault
α : Type u
β : Type v
γ : Sort w
inst✝² : Zero β
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
a : α
A : List ((_ : α) × β)
y : β
⊢ (∃ x, { fst := a, snd := x } ∈ List.dedupKeys A ∧ (decide ¬x = 0) = true) ↔ ¬Option.getD (List.dlookup a A) 0 = 0
[PROOFSTEP]
constructor
[GOAL]
case withDefault.mp
α : Type u
β : Type v
γ : Sort w
inst✝² : Zero β
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
a : α
A : List ((_ : α) × β)
y : β
⊢ (∃ x, { fst := a, snd := x } ∈ List.dedupKeys A ∧ (decide ¬x = 0) = true) → ¬Option.getD (List.dlookup a A) 0 = 0
[PROOFSTEP]
rintro ⟨od, hval, hod⟩
[GOAL]
case withDefault.mp.intro.intro
α : Type u
β : Type v
γ : Sort w
inst✝² : Zero β
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
a : α
A : List ((_ : α) × β)
y od : β
hval : { fst := a, snd := od } ∈ List.dedupKeys A
hod : (decide ¬od = 0) = true
⊢ ¬Option.getD (List.dlookup a A) 0 = 0
[PROOFSTEP]
have := List.mem_dlookup (List.nodupKeys_dedupKeys A) hval
[GOAL]
case withDefault.mp.intro.intro
α : Type u
β : Type v
γ : Sort w
inst✝² : Zero β
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
a : α
A : List ((_ : α) × β)
y od : β
hval : { fst := a, snd := od } ∈ List.dedupKeys A
hod : (decide ¬od = 0) = true
this : od ∈ List.dlookup a (List.dedupKeys A)
⊢ ¬Option.getD (List.dlookup a A) 0 = 0
[PROOFSTEP]
rw [(_ : List.dlookup a A = od)]
[GOAL]
case withDefault.mp.intro.intro
α : Type u
β : Type v
γ : Sort w
inst✝² : Zero β
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
a : α
A : List ((_ : α) × β)
y od : β
hval : { fst := a, snd := od } ∈ List.dedupKeys A
hod : (decide ¬od = 0) = true
this : od ∈ List.dlookup a (List.dedupKeys A)
⊢ ¬Option.getD (some od) 0 = 0
[PROOFSTEP]
simpa using hod
[GOAL]
α : Type u
β : Type v
γ : Sort w
inst✝² : Zero β
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
a : α
A : List ((_ : α) × β)
y od : β
hval : { fst := a, snd := od } ∈ List.dedupKeys A
hod : (decide ¬od = 0) = true
this : od ∈ List.dlookup a (List.dedupKeys A)
⊢ List.dlookup a A = some od
[PROOFSTEP]
simpa [List.dlookup_dedupKeys, WithTop.some_eq_coe]
[GOAL]
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
[PROOFSTEP]
intro h
[GOAL]
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
[PROOFSTEP]
use(A.dlookup a).getD (0 : β)
[GOAL]
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
[PROOFSTEP]
rw [← List.dlookup_dedupKeys] at h ⊢
[GOAL]
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
[PROOFSTEP]
simp only [h, ← List.mem_dlookup_iff A.nodupKeys_dedupKeys, and_true_iff, not_false_iff, Option.mem_def]
[GOAL]
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)
[PROOFSTEP]
cases haA : List.dlookup a A.dedupKeys
[GOAL]
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)
[PROOFSTEP]
simp [haA] at h 
[GOAL]
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)
[PROOFSTEP]
simp
[GOAL]
α : 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
[PROOFSTEP]
simp only [List.applyId, List.dlookup, eq_rec_constant, Prod.toSigma, List.map]
[GOAL]
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs : List (α × α)
x y z : α
⊢ Option.getD (if h : y = x then some z else List.dlookup x (List.map (fun p => { fst := p.fst, snd := p.snd }) xs)) x =
    if y = x then z else Option.getD (List.dlookup x (List.map (fun p => { fst := p.fst, snd := p.snd }) xs)) x
[PROOFSTEP]
split_ifs
[GOAL]
case pos
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs : List (α × α)
x y z : α
h✝ : y = x
⊢ Option.getD (some z) x = z
[PROOFSTEP]
rfl
[GOAL]
case neg
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs : List (α × α)
x y z : α
h✝ : ¬y = x
⊢ Option.getD (List.dlookup x (List.map (fun p => { fst := p.fst, snd := p.snd }) xs)) x =
    Option.getD (List.dlookup x (List.map (fun p => { fst := p.fst, snd := p.snd }) xs)) x
[PROOFSTEP]
rfl
[GOAL]
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : List.Nodup xs
h₁ : List.length xs = List.length ys
x y : α
i : ℕ
h₂ : List.get? xs i = some x
⊢ applyId (List.zip xs ys) x = y ↔ List.get? ys i = some y
[PROOFSTEP]
induction xs generalizing ys i
[GOAL]
case nil
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
x y : α
ys : List α
h₀ : List.Nodup []
h₁ : List.length [] = List.length ys
i : ℕ
h₂ : List.get? [] i = some x
⊢ applyId (List.zip [] ys) x = y ↔ List.get? ys i = some y
case cons
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
x y head✝ : α
tail✝ : List α
tail_ih✝ :
  ∀ {ys : List α},
    List.Nodup tail✝ →
      List.length tail✝ = List.length ys →
        ∀ (i : ℕ), List.get? tail✝ i = some x → (applyId (List.zip tail✝ ys) x = y ↔ List.get? ys i = some y)
ys : List α
h₀ : List.Nodup (head✝ :: tail✝)
h₁ : List.length (head✝ :: tail✝) = List.length ys
i : ℕ
h₂ : List.get? (head✝ :: tail✝) i = some x
⊢ applyId (List.zip (head✝ :: tail✝) ys) x = y ↔ List.get? ys i = some y
[PROOFSTEP]
case nil => cases h₂
[GOAL]
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
x y : α
ys : List α
h₀ : List.Nodup []
h₁ : List.length [] = List.length ys
i : ℕ
h₂ : List.get? [] i = some x
⊢ applyId (List.zip [] ys) x = y ↔ List.get? ys i = some y
[PROOFSTEP]
case nil => cases h₂
[GOAL]
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
x y : α
ys : List α
h₀ : List.Nodup []
h₁ : List.length [] = List.length ys
i : ℕ
h₂ : List.get? [] i = some x
⊢ applyId (List.zip [] ys) x = y ↔ List.get? ys i = some y
[PROOFSTEP]
cases h₂
[GOAL]
case cons
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
x y head✝ : α
tail✝ : List α
tail_ih✝ :
  ∀ {ys : List α},
    List.Nodup tail✝ →
      List.length tail✝ = List.length ys →
        ∀ (i : ℕ), List.get? tail✝ i = some x → (applyId (List.zip tail✝ ys) x = y ↔ List.get? ys i = some y)
ys : List α
h₀ : List.Nodup (head✝ :: tail✝)
h₁ : List.length (head✝ :: tail✝) = List.length ys
i : ℕ
h₂ : List.get? (head✝ :: tail✝) i = some x
⊢ applyId (List.zip (head✝ :: tail✝) ys) x = y ↔ List.get? ys i = some y
[PROOFSTEP]
case 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` visiblesimp 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₁
      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₂
[GOAL]
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
x y x' : α
xs : List α
xs_ih :
  ∀ {ys : List α},
    List.Nodup xs →
      List.length xs = List.length ys →
        ∀ (i : ℕ), List.get? xs i = some x → (applyId (List.zip xs ys) x = y ↔ List.get? ys i = some y)
ys : List α
h₀ : List.Nodup (x' :: xs)
h₁ : List.length (x' :: xs) = List.length ys
i : ℕ
h₂ : List.get? (x' :: xs) i = some x
⊢ applyId (List.zip (x' :: xs) ys) x = y ↔ List.get? ys i = some y
[PROOFSTEP]
case 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` visiblesimp 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₁
      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₂
[GOAL]
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
x y x' : α
xs : List α
xs_ih :
  ∀ {ys : List α},
    List.Nodup xs →
      List.length xs = List.length ys →
        ∀ (i : ℕ), List.get? xs i = some x → (applyId (List.zip xs ys) x = y ↔ List.get? ys i = some y)
ys : List α
h₀ : List.Nodup (x' :: xs)
h₁ : List.length (x' :: xs) = List.length ys
i : ℕ
h₂ : List.get? (x' :: xs) i = some x
⊢ applyId (List.zip (x' :: xs) ys) x = y ↔ List.get? ys i = some y
[PROOFSTEP]
cases i
[GOAL]
case zero
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
x y x' : α
xs : List α
xs_ih :
  ∀ {ys : List α},
    List.Nodup xs →
      List.length xs = List.length ys →
        ∀ (i : ℕ), List.get? xs i = some x → (applyId (List.zip xs ys) x = y ↔ List.get? ys i = some y)
ys : List α
h₀ : List.Nodup (x' :: xs)
h₁ : List.length (x' :: xs) = List.length ys
h₂ : List.get? (x' :: xs) Nat.zero = some x
⊢ applyId (List.zip (x' :: xs) ys) x = y ↔ List.get? ys Nat.zero = some y
[PROOFSTEP]
injection h₂ with h₀
[GOAL]
case zero
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
x y x' : α
xs : List α
xs_ih :
  ∀ {ys : List α},
    List.Nodup xs →
      List.length xs = List.length ys →
        ∀ (i : ℕ), List.get? xs i = some x → (applyId (List.zip xs ys) x = y ↔ List.get? ys i = some y)
ys : List α
h₀✝ : List.Nodup (x' :: xs)
h₁ : List.length (x' :: xs) = List.length ys
h₀ : x' = x
⊢ applyId (List.zip (x' :: xs) ys) x = y ↔ List.get? ys Nat.zero = some y
[PROOFSTEP]
subst h₀
[GOAL]
case zero
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
y x' : α
xs ys : List α
h₀ : List.Nodup (x' :: xs)
h₁ : List.length (x' :: xs) = List.length ys
xs_ih :
  ∀ {ys : List α},
    List.Nodup xs →
      List.length xs = List.length ys →
        ∀ (i : ℕ), List.get? xs i = some x' → (applyId (List.zip xs ys) x' = y ↔ List.get? ys i = some y)
⊢ applyId (List.zip (x' :: xs) ys) x' = y ↔ List.get? ys Nat.zero = some y
[PROOFSTEP]
cases ys
[GOAL]
case zero.nil
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
y x' : α
xs : List α
h₀ : List.Nodup (x' :: xs)
xs_ih :
  ∀ {ys : List α},
    List.Nodup xs →
      List.length xs = List.length ys →
        ∀ (i : ℕ), List.get? xs i = some x' → (applyId (List.zip xs ys) x' = y ↔ List.get? ys i = some y)
h₁ : List.length (x' :: xs) = List.length []
⊢ applyId (List.zip (x' :: xs) []) x' = y ↔ List.get? [] Nat.zero = some y
[PROOFSTEP]
cases h₁
[GOAL]
case zero.cons
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
y x' : α
xs : List α
h₀ : List.Nodup (x' :: xs)
xs_ih :
  ∀ {ys : List α},
    List.Nodup xs →
      List.length xs = List.length ys →
        ∀ (i : ℕ), List.get? xs i = some x' → (applyId (List.zip xs ys) x' = y ↔ List.get? ys i = some y)
head✝ : α
tail✝ : List α
h₁ : List.length (x' :: xs) = List.length (head✝ :: tail✝)
⊢ applyId (List.zip (x' :: xs) (head✝ :: tail✝)) x' = y ↔ List.get? (head✝ :: tail✝) Nat.zero = some y
[PROOFSTEP]
simp only [List.applyId, Prod.toSigma, Option.getD_some, List.get?, List.dlookup_cons_eq, List.zip_cons_cons, List.map,
  Option.some_inj]
[GOAL]
case succ
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
x y x' : α
xs : List α
xs_ih :
  ∀ {ys : List α},
    List.Nodup xs →
      List.length xs = List.length ys →
        ∀ (i : ℕ), List.get? xs i = some x → (applyId (List.zip xs ys) x = y ↔ List.get? ys i = some y)
ys : List α
h₀ : List.Nodup (x' :: xs)
h₁ : List.length (x' :: xs) = List.length ys
n✝ : ℕ
h₂ : List.get? (x' :: xs) (Nat.succ n✝) = some x
⊢ applyId (List.zip (x' :: xs) ys) x = y ↔ List.get? ys (Nat.succ n✝) = some y
[PROOFSTEP]
cases ys
[GOAL]
case succ.nil
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
x y x' : α
xs : List α
xs_ih :
  ∀ {ys : List α},
    List.Nodup xs →
      List.length xs = List.length ys →
        ∀ (i : ℕ), List.get? xs i = some x → (applyId (List.zip xs ys) x = y ↔ List.get? ys i = some y)
h₀ : List.Nodup (x' :: xs)
n✝ : ℕ
h₂ : List.get? (x' :: xs) (Nat.succ n✝) = some x
h₁ : List.length (x' :: xs) = List.length []
⊢ applyId (List.zip (x' :: xs) []) x = y ↔ List.get? [] (Nat.succ n✝) = some y
[PROOFSTEP]
cases h₁
[GOAL]
case succ.cons
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
x y x' : α
xs : List α
xs_ih :
  ∀ {ys : List α},
    List.Nodup xs →
      List.length xs = List.length ys →
        ∀ (i : ℕ), List.get? xs i = some x → (applyId (List.zip xs ys) x = y ↔ List.get? ys i = some y)
h₀ : List.Nodup (x' :: xs)
n✝ : ℕ
h₂ : List.get? (x' :: xs) (Nat.succ n✝) = some x
head✝ : α
tail✝ : List α
h₁ : List.length (x' :: xs) = List.length (head✝ :: tail✝)
⊢ applyId (List.zip (x' :: xs) (head✝ :: tail✝)) x = y ↔ List.get? (head✝ :: tail✝) (Nat.succ n✝) = some y
[PROOFSTEP]
cases' h₀ with _ _ h₀ h₁
[GOAL]
case succ.cons.cons
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
x y x' : α
xs : List α
xs_ih :
  ∀ {ys : List α},
    List.Nodup xs →
      List.length xs = List.length ys →
        ∀ (i : ℕ), List.get? xs i = some x → (applyId (List.zip xs ys) x = y ↔ List.get? ys i = some y)
n✝ : ℕ
h₂ : List.get? (x' :: xs) (Nat.succ n✝) = some x
head✝ : α
tail✝ : List α
h₁✝ : List.length (x' :: xs) = List.length (head✝ :: tail✝)
h₁ : List.Pairwise (fun x x_1 => x ≠ x_1) xs
h₀ : ∀ (a' : α), a' ∈ xs → x' ≠ a'
⊢ applyId (List.zip (x' :: xs) (head✝ :: tail✝)) x = y ↔ List.get? (head✝ :: tail✝) (Nat.succ n✝) = some y
[PROOFSTEP]
simp only [List.get?, List.zip_cons_cons, List.applyId_cons] at h₂ ⊢
[GOAL]
case succ.cons.cons
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
x y x' : α
xs : List α
xs_ih :
  ∀ {ys : List α},
    List.Nodup xs →
      List.length xs = List.length ys →
        ∀ (i : ℕ), List.get? xs i = some x → (applyId (List.zip xs ys) x = y ↔ List.get? ys i = some y)
n✝ : ℕ
h₂ : List.get? xs n✝ = some x
head✝ : α
tail✝ : List α
h₁✝ : List.length (x' :: xs) = List.length (head✝ :: tail✝)
h₁ : List.Pairwise (fun x x_1 => x ≠ x_1) xs
h₀ : ∀ (a' : α), a' ∈ xs → x' ≠ a'
⊢ (if x' = x then head✝ else applyId (List.zip xs tail✝) x) = y ↔ List.get? tail✝ n✝ = some y
[PROOFSTEP]
rw [if_neg]
[GOAL]
case succ.cons.cons
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
x y x' : α
xs : List α
xs_ih :
  ∀ {ys : List α},
    List.Nodup xs →
      List.length xs = List.length ys →
        ∀ (i : ℕ), List.get? xs i = some x → (applyId (List.zip xs ys) x = y ↔ List.get? ys i = some y)
n✝ : ℕ
h₂ : List.get? xs n✝ = some x
head✝ : α
tail✝ : List α
h₁✝ : List.length (x' :: xs) = List.length (head✝ :: tail✝)
h₁ : List.Pairwise (fun x x_1 => x ≠ x_1) xs
h₀ : ∀ (a' : α), a' ∈ xs → x' ≠ a'
⊢ applyId (List.zip xs tail✝) x = y ↔ List.get? tail✝ n✝ = some y
[PROOFSTEP]
apply xs_ih
[GOAL]
case succ.cons.cons.h₀
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
x y x' : α
xs : List α
xs_ih :
  ∀ {ys : List α},
    List.Nodup xs →
      List.length xs = List.length ys →
        ∀ (i : ℕ), List.get? xs i = some x → (applyId (List.zip xs ys) x = y ↔ List.get? ys i = some y)
n✝ : ℕ
h₂ : List.get? xs n✝ = some x
head✝ : α
tail✝ : List α
h₁✝ : List.length (x' :: xs) = List.length (head✝ :: tail✝)
h₁ : List.Pairwise (fun x x_1 => x ≠ x_1) xs
h₀ : ∀ (a' : α), a' ∈ xs → x' ≠ a'
⊢ List.Nodup xs
[PROOFSTEP]
solve_by_elim [Nat.succ.inj]
[GOAL]
case succ.cons.cons.h₁
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
x y x' : α
xs : List α
xs_ih :
  ∀ {ys : List α},
    List.Nodup xs →
      List.length xs = List.length ys →
        ∀ (i : ℕ), List.get? xs i = some x → (applyId (List.zip xs ys) x = y ↔ List.get? ys i = some y)
n✝ : ℕ
h₂ : List.get? xs n✝ = some x
head✝ : α
tail✝ : List α
h₁✝ : List.length (x' :: xs) = List.length (head✝ :: tail✝)
h₁ : List.Pairwise (fun x x_1 => x ≠ x_1) xs
h₀ : ∀ (a' : α), a' ∈ xs → x' ≠ a'
⊢ List.length xs = List.length tail✝
[PROOFSTEP]
solve_by_elim [Nat.succ.inj]
[GOAL]
case succ.cons.cons.h₂
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
x y x' : α
xs : List α
xs_ih :
  ∀ {ys : List α},
    List.Nodup xs →
      List.length xs = List.length ys →
        ∀ (i : ℕ), List.get? xs i = some x → (applyId (List.zip xs ys) x = y ↔ List.get? ys i = some y)
n✝ : ℕ
h₂ : List.get? xs n✝ = some x
head✝ : α
tail✝ : List α
h₁✝ : List.length (x' :: xs) = List.length (head✝ :: tail✝)
h₁ : List.Pairwise (fun x x_1 => x ≠ x_1) xs
h₀ : ∀ (a' : α), a' ∈ xs → x' ≠ a'
⊢ List.get? xs n✝ = some x
[PROOFSTEP]
solve_by_elim [Nat.succ.inj]
[GOAL]
case succ.cons.cons.hnc
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
x y x' : α
xs : List α
xs_ih :
  ∀ {ys : List α},
    List.Nodup xs →
      List.length xs = List.length ys →
        ∀ (i : ℕ), List.get? xs i = some x → (applyId (List.zip xs ys) x = y ↔ List.get? ys i = some y)
n✝ : ℕ
h₂ : List.get? xs n✝ = some x
head✝ : α
tail✝ : List α
h₁✝ : List.length (x' :: xs) = List.length (head✝ :: tail✝)
h₁ : List.Pairwise (fun x x_1 => x ≠ x_1) xs
h₀ : ∀ (a' : α), a' ∈ xs → x' ≠ a'
⊢ ¬x' = x
[PROOFSTEP]
apply h₀
[GOAL]
case succ.cons.cons.hnc.a
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
x y x' : α
xs : List α
xs_ih :
  ∀ {ys : List α},
    List.Nodup xs →
      List.length xs = List.length ys →
        ∀ (i : ℕ), List.get? xs i = some x → (applyId (List.zip xs ys) x = y ↔ List.get? ys i = some y)
n✝ : ℕ
h₂ : List.get? xs n✝ = some x
head✝ : α
tail✝ : List α
h₁✝ : List.length (x' :: xs) = List.length (head✝ :: tail✝)
h₁ : List.Pairwise (fun x x_1 => x ≠ x_1) xs
h₀ : ∀ (a' : α), a' ∈ xs → x' ≠ a'
⊢ x ∈ xs
[PROOFSTEP]
apply List.get?_mem h₂
[GOAL]
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : List.Nodup xs
h₁ : xs ~ ys
x : α
⊢ applyId (List.zip xs ys) x ∈ ys ↔ x ∈ xs
[PROOFSTEP]
simp only [List.applyId]
[GOAL]
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : List.Nodup xs
h₁ : xs ~ ys
x : α
⊢ Option.getD (List.dlookup x (List.map Prod.toSigma (List.zip xs ys))) x ∈ ys ↔ x ∈ xs
[PROOFSTEP]
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; 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₆)]
[GOAL]
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : List.Nodup xs
h₁ : xs ~ ys
x : α
x✝ : Option α
h₃ : List.dlookup x (List.map Prod.toSigma (List.zip xs ys)) = x✝
⊢ Option.getD x✝ x ∈ ys ↔ x ∈ xs
[PROOFSTEP]
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; 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₆)]
[GOAL]
case none
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : List.Nodup xs
h₁ : xs ~ ys
x : α
h₃ : List.dlookup x (List.map Prod.toSigma (List.zip xs ys)) = none
⊢ Option.getD none x ∈ ys ↔ x ∈ xs
[PROOFSTEP]

| none =>
  dsimp [Option.getD]
  rw [h₁.mem_iff]
[GOAL]
case none
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : List.Nodup xs
h₁ : xs ~ ys
x : α
h₃ : List.dlookup x (List.map Prod.toSigma (List.zip xs ys)) = none
⊢ Option.getD none x ∈ ys ↔ x ∈ xs
[PROOFSTEP]
dsimp [Option.getD]
[GOAL]
case none
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : List.Nodup xs
h₁ : xs ~ ys
x : α
h₃ : List.dlookup x (List.map Prod.toSigma (List.zip xs ys)) = none
⊢ x ∈ ys ↔ x ∈ xs
[PROOFSTEP]
rw [h₁.mem_iff]
[GOAL]
case some
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : List.Nodup xs
h₁ : xs ~ ys
x val : α
h₃ : List.dlookup x (List.map Prod.toSigma (List.zip xs ys)) = some val
⊢ Option.getD (some val) x ∈ ys ↔ x ∈ xs
[PROOFSTEP]

| 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; 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₆)]
[GOAL]
case some
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : List.Nodup xs
h₁ : xs ~ ys
x val : α
h₃ : List.dlookup x (List.map Prod.toSigma (List.zip xs ys)) = some val
⊢ Option.getD (some val) x ∈ ys ↔ x ∈ xs
[PROOFSTEP]
have h₂ : ys.Nodup := h₁.nodup_iff.1 h₀
[GOAL]
case some
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : List.Nodup xs
h₁ : xs ~ ys
x val : α
h₃ : List.dlookup x (List.map Prod.toSigma (List.zip xs ys)) = some val
h₂ : List.Nodup ys
⊢ Option.getD (some val) x ∈ ys ↔ x ∈ xs
[PROOFSTEP]
replace h₁ : xs.length = ys.length := h₁.length_eq
[GOAL]
case some
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : List.Nodup xs
x val : α
h₃ : List.dlookup x (List.map Prod.toSigma (List.zip xs ys)) = some val
h₂ : List.Nodup ys
h₁ : List.length xs = List.length ys
⊢ Option.getD (some val) x ∈ ys ↔ x ∈ xs
[PROOFSTEP]
dsimp
[GOAL]
case some
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : List.Nodup xs
x val : α
h₃ : List.dlookup x (List.map Prod.toSigma (List.zip xs ys)) = some val
h₂ : List.Nodup ys
h₁ : List.length xs = List.length ys
⊢ val ∈ ys ↔ x ∈ xs
[PROOFSTEP]
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; 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₆)]
[GOAL]
case some
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : List.Nodup xs
x val : α
h₃ : List.dlookup x (List.map Prod.toSigma (List.zip xs ys)) = some val
h₂ : List.Nodup ys
h₁ : List.length xs = List.length ys
⊢ val ∈ ys ↔ x ∈ xs
[PROOFSTEP]
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; 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₆)]
[GOAL]
case some.nil
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
x val : α
ys : List α
h₀ : List.Nodup []
h₃ : List.dlookup x (List.map Prod.toSigma (List.zip [] ys)) = some val
h₂ : List.Nodup ys
h₁ : List.length [] = List.length ys
⊢ val ∈ ys ↔ x ∈ []
[PROOFSTEP]

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

| 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; 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₆)]
[GOAL]
case some.cons
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
x val x' : α
xs : List α
xs_ih :
  ∀ {ys : List α},
    List.Nodup xs →
      List.dlookup x (List.map Prod.toSigma (List.zip xs ys)) = some val →
        List.Nodup ys → List.length xs = List.length ys → (val ∈ ys ↔ x ∈ xs)
ys : List α
h₀ : List.Nodup (x' :: xs)
h₃ : List.dlookup x (List.map Prod.toSigma (List.zip (x' :: xs) ys)) = some val
h₂ : List.Nodup ys
h₁ : List.length (x' :: xs) = List.length ys
⊢ val ∈ ys ↔ x ∈ x' :: xs
[PROOFSTEP]
cases' ys with y ys
[GOAL]
case some.cons.nil
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
x val x' : α
xs : List α
xs_ih :
  ∀ {ys : List α},
    List.Nodup xs →
      List.dlookup x (List.map Prod.toSigma (List.zip xs ys)) = some val →
        List.Nodup ys → List.length xs = List.length ys → (val ∈ ys ↔ x ∈ xs)
h₀ : List.Nodup (x' :: xs)
h₃ : List.dlookup x (List.map Prod.toSigma (List.zip (x' :: xs) [])) = some val
h₂ : List.Nodup []
h₁ : List.length (x' :: xs) = List.length []
⊢ val ∈ [] ↔ x ∈ x' :: xs
[PROOFSTEP]
cases h₃
[GOAL]
case some.cons.cons
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
x val x' : α
xs : List α
xs_ih :
  ∀ {ys : List α},
    List.Nodup xs →
      List.dlookup x (List.map Prod.toSigma (List.zip xs ys)) = some val →
        List.Nodup ys → List.length xs = List.length ys → (val ∈ ys ↔ x ∈ xs)
h₀ : List.Nodup (x' :: xs)
y : α
ys : List α
h₃ : List.dlookup x (List.map Prod.toSigma (List.zip (x' :: xs) (y :: ys))) = some val
h₂ : List.Nodup (y :: ys)
h₁ : List.length (x' :: xs) = List.length (y :: ys)
⊢ val ∈ y :: ys ↔ x ∈ x' :: xs
[PROOFSTEP]
dsimp [List.dlookup] at h₃ 
[GOAL]
case some.cons.cons
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
x val x' : α
xs : List α
xs_ih :
  ∀ {ys : List α},
    List.Nodup xs →
      List.dlookup x (List.map Prod.toSigma (List.zip xs ys)) = some val →
        List.Nodup ys → List.length xs = List.length ys → (val ∈ ys ↔ x ∈ xs)
h₀ : List.Nodup (x' :: xs)
y : α
ys : List α
h₃ : (if h : x' = x then some (h ▸ y) else List.dlookup x (List.map Prod.toSigma (List.zip xs ys))) = some val
h₂ : List.Nodup (y :: ys)
h₁ : List.length (x' :: xs) = List.length (y :: ys)
⊢ val ∈ y :: ys ↔ x ∈ x' :: xs
[PROOFSTEP]
split_ifs at h₃  with h
[GOAL]
case pos
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
x val x' : α
xs : List α
xs_ih :
  ∀ {ys : List α},
    List.Nodup xs →
      List.dlookup x (List.map Prod.toSigma (List.zip xs ys)) = some val →
        List.Nodup ys → List.length xs = List.length ys → (val ∈ ys ↔ x ∈ xs)
h₀ : List.Nodup (x' :: xs)
y : α
ys : List α
h₂ : List.Nodup (y :: ys)
h₁ : List.length (x' :: xs) = List.length (y :: ys)
h : x' = x
h₃ : some (h ▸ y) = some val
⊢ val ∈ y :: ys ↔ x ∈ x' :: xs
[PROOFSTEP]
rw [Option.some_inj] at h₃ 
[GOAL]
case pos
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
x val x' : α
xs : List α
xs_ih :
  ∀ {ys : List α},
    List.Nodup xs →
      List.dlookup x (List.map Prod.toSigma (List.zip xs ys)) = some val →
        List.Nodup ys → List.length xs = List.length ys → (val ∈ ys ↔ x ∈ xs)
h₀ : List.Nodup (x' :: xs)
y : α
ys : List α
h₂ : List.Nodup (y :: ys)
h₁ : List.length (x' :: xs) = List.length (y :: ys)
h : x' = x
h₃ : h ▸ y = val
⊢ val ∈ y :: ys ↔ x ∈ x' :: xs
[PROOFSTEP]
subst x'
[GOAL]
case pos
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
x val : α
xs : List α
xs_ih :
  ∀ {ys : List α},
    List.Nodup xs →
      List.dlookup x (List.map Prod.toSigma (List.zip xs ys)) = some val →
        List.Nodup ys → List.length xs = List.length ys → (val ∈ ys ↔ x ∈ xs)
y : α
ys : List α
h₂ : List.Nodup (y :: ys)
h₀ : List.Nodup (x :: xs)
h₁ : List.length (x :: xs) = List.length (y :: ys)
h₃ : (_ : x = x) ▸ y = val
⊢ val ∈ y :: ys ↔ x ∈ x :: xs
[PROOFSTEP]
subst val
[GOAL]
case pos
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
x : α
xs : List α
y : α
ys : List α
h₂ : List.Nodup (y :: ys)
h₀ : List.Nodup (x :: xs)
h₁ : List.length (x :: xs) = List.length (y :: ys)
xs_ih :
  ∀ {ys : List α},
    List.Nodup xs →
      List.dlookup x (List.map Prod.toSigma (List.zip xs ys)) = some ((_ : x = x) ▸ y) →
        List.Nodup ys → List.length xs = List.length ys → ((_ : x = x) ▸ y ∈ ys ↔ x ∈ xs)
⊢ (_ : x = x) ▸ y ∈ y :: ys ↔ x ∈ x :: xs
[PROOFSTEP]
simp only [List.mem_cons, true_or_iff, eq_self_iff_true]
[GOAL]
case neg
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
x val x' : α
xs : List α
xs_ih :
  ∀ {ys : List α},
    List.Nodup xs →
      List.dlookup x (List.map Prod.toSigma (List.zip xs ys)) = some val →
        List.Nodup ys → List.length xs = List.length ys → (val ∈ ys ↔ x ∈ xs)
h₀ : List.Nodup (x' :: xs)
y : α
ys : List α
h₂ : List.Nodup (y :: ys)
h₁ : List.length (x' :: xs) = List.length (y :: ys)
h : ¬x' = x
h₃ : List.dlookup x (List.map Prod.toSigma (List.zip xs ys)) = some val
⊢ val ∈ y :: ys ↔ x ∈ x' :: xs
[PROOFSTEP]
cases' h₀ with _ _ h₀ h₅
[GOAL]
case neg.cons
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
x val x' : α
xs : List α
xs_ih :
  ∀ {ys : List α},
    List.Nodup xs →
      List.dlookup x (List.map Prod.toSigma (List.zip xs ys)) = some val →
        List.Nodup ys → List.length xs = List.length ys → (val ∈ ys ↔ x ∈ xs)
y : α
ys : List α
h₂ : List.Nodup (y :: ys)
h₁ : List.length (x' :: xs) = List.length (y :: ys)
h : ¬x' = x
h₃ : List.dlookup x (List.map Prod.toSigma (List.zip xs ys)) = some val
h₅ : List.Pairwise (fun x x_1 => x ≠ x_1) xs
h₀ : ∀ (a' : α), a' ∈ xs → x' ≠ a'
⊢ val ∈ y :: ys ↔ x ∈ x' :: xs
[PROOFSTEP]
cases' h₂ with _ _ h₂ h₄
[GOAL]
case neg.cons.cons
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
x val x' : α
xs : List α
xs_ih :
  ∀ {ys : List α},
    List.Nodup xs →
      List.dlookup x (List.map Prod.toSigma (List.zip xs ys)) = some val →
        List.Nodup ys → List.length xs = List.length ys → (val ∈ ys ↔ x ∈ xs)
y : α
ys : List α
h₁ : List.length (x' :: xs) = List.length (y :: ys)
h : ¬x' = x
h₃ : List.dlookup x (List.map Prod.toSigma (List.zip xs ys)) = some val
h₅ : List.Pairwise (fun x x_1 => x ≠ x_1) xs
h₀ : ∀ (a' : α), a' ∈ xs → x' ≠ a'
h₄ : List.Pairwise (fun x x_1 => x ≠ x_1) ys
h₂ : ∀ (a' : α), a' ∈ ys → y ≠ a'
⊢ val ∈ y :: ys ↔ x ∈ x' :: xs
[PROOFSTEP]
have h₆ := Nat.succ.inj h₁
[GOAL]
case neg.cons.cons
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
x val x' : α
xs : List α
xs_ih :
  ∀ {ys : List α},
    List.Nodup xs →
      List.dlookup x (List.map Prod.toSigma (List.zip xs ys)) = some val →
        List.Nodup ys → List.length xs = List.length ys → (val ∈ ys ↔ x ∈ xs)
y : α
ys : List α
h₁ : List.length (x' :: xs) = List.length (y :: ys)
h : ¬x' = x
h₃ : List.dlookup x (List.map Prod.toSigma (List.zip xs ys)) = some val
h₅ : List.Pairwise (fun x x_1 => x ≠ x_1) xs
h₀ : ∀ (a' : α), a' ∈ xs → x' ≠ a'
h₄ : List.Pairwise (fun x x_1 => x ≠ x_1) ys
h₂ : ∀ (a' : α), a' ∈ ys → y ≠ a'
h₆ : List.length xs = List.length ys
⊢ val ∈ y :: ys ↔ x ∈ x' :: xs
[PROOFSTEP]
specialize xs_ih h₅ h₃ h₄ h₆
[GOAL]
case neg.cons.cons
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
x val x' : α
xs : List α
y : α
ys : List α
h₁ : List.length (x' :: xs) = List.length (y :: ys)
h : ¬x' = x
h₃ : List.dlookup x (List.map Prod.toSigma (List.zip xs ys)) = some val
h₅ : List.Pairwise (fun x x_1 => x ≠ x_1) xs
h₀ : ∀ (a' : α), a' ∈ xs → x' ≠ a'
h₄ : List.Pairwise (fun x x_1 => x ≠ x_1) ys
h₂ : ∀ (a' : α), a' ∈ ys → y ≠ a'
h₆ : List.length xs = List.length ys
xs_ih : val ∈ ys ↔ x ∈ xs
⊢ val ∈ y :: ys ↔ x ∈ x' :: xs
[PROOFSTEP]
simp only [Ne.symm h, xs_ih, List.mem_cons, false_or_iff]
[GOAL]
case neg.cons.cons
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
x val x' : α
xs : List α
y : α
ys : List α
h₁ : List.length (x' :: xs) = List.length (y :: ys)
h : ¬x' = x
h₃ : List.dlookup x (List.map Prod.toSigma (List.zip xs ys)) = some val
h₅ : List.Pairwise (fun x x_1 => x ≠ x_1) xs
h₀ : ∀ (a' : α), a' ∈ xs → x' ≠ a'
h₄ : List.Pairwise (fun x x_1 => x ≠ x_1) ys
h₂ : ∀ (a' : α), a' ∈ ys → y ≠ a'
h₆ : List.length xs = List.length ys
xs_ih : val ∈ ys ↔ x ∈ xs
⊢ val = y ∨ x ∈ xs ↔ x ∈ xs
[PROOFSTEP]
suffices : val ∈ ys
[GOAL]
case neg.cons.cons
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
x val x' : α
xs : List α
y : α
ys : List α
h₁ : List.length (x' :: xs) = List.length (y :: ys)
h : ¬x' = x
h₃ : List.dlookup x (List.map Prod.toSigma (List.zip xs ys)) = some val
h₅ : List.Pairwise (fun x x_1 => x ≠ x_1) xs
h₀ : ∀ (a' : α), a' ∈ xs → x' ≠ a'
h₄ : List.Pairwise (fun x x_1 => x ≠ x_1) ys
h₂ : ∀ (a' : α), a' ∈ ys → y ≠ a'
h₆ : List.length xs = List.length ys
xs_ih : val ∈ ys ↔ x ∈ xs
this : val ∈ ys
⊢ val = y ∨ x ∈ xs ↔ x ∈ xs
case this
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
x val x' : α
xs : List α
y : α
ys : List α
h₁ : List.length (x' :: xs) = List.length (y :: ys)
h : ¬x' = x
h₃ : List.dlookup x (List.map Prod.toSigma (List.zip xs ys)) = some val
h₅ : List.Pairwise (fun x x_1 => x ≠ x_1) xs
h₀ : ∀ (a' : α), a' ∈ xs → x' ≠ a'
h₄ : List.Pairwise (fun x x_1 => x ≠ x_1) ys
h₂ : ∀ (a' : α), a' ∈ ys → y ≠ a'
h₆ : List.length xs = List.length ys
xs_ih : val ∈ ys ↔ x ∈ xs
⊢ val ∈ ys
[PROOFSTEP]
tauto
[GOAL]
case this
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
x val x' : α
xs : List α
y : α
ys : List α
h₁ : List.length (x' :: xs) = List.length (y :: ys)
h : ¬x' = x
h₃ : List.dlookup x (List.map Prod.toSigma (List.zip xs ys)) = some val
h₅ : List.Pairwise (fun x x_1 => x ≠ x_1) xs
h₀ : ∀ (a' : α), a' ∈ xs → x' ≠ a'
h₄ : List.Pairwise (fun x x_1 => x ≠ x_1) ys
h₂ : ∀ (a' : α), a' ∈ ys → y ≠ a'
h₆ : List.length xs = List.length ys
xs_ih : val ∈ ys ↔ x ∈ xs
⊢ val ∈ ys
[PROOFSTEP]
erw [← Option.mem_def, List.mem_dlookup_iff] at h₃ 
[GOAL]
case this
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
x val x' : α
xs : List α
y : α
ys : List α
h₁ : List.length (x' :: xs) = List.length (y :: ys)
h : ¬x' = x
h₃ : { fst := x, snd := val } ∈ List.map Prod.toSigma (List.zip xs ys)
h₅ : List.Pairwise (fun x x_1 => x ≠ x_1) xs
h₀ : ∀ (a' : α), a' ∈ xs → x' ≠ a'
h₄ : List.Pairwise (fun x x_1 => x ≠ x_1) ys
h₂ : ∀ (a' : α), a' ∈ ys → y ≠ a'
h₆ : List.length xs = List.length ys
xs_ih : val ∈ ys ↔ x ∈ xs
⊢ val ∈ ys
case this
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
x val x' : α
xs : List α
y : α
ys : List α
h₁ : List.length (x' :: xs) = List.length (y :: ys)
h : ¬x' = x
h₃ : val ∈ List.dlookup x (List.map Prod.toSigma (List.zip xs ys))
h₅ : List.Pairwise (fun x x_1 => x ≠ x_1) xs
h₀ : ∀ (a' : α), a' ∈ xs → x' ≠ a'
h₄ : List.Pairwise (fun x x_1 => x ≠ x_1) ys
h₂ : ∀ (a' : α), a' ∈ ys → y ≠ a'
h₆ : List.length xs = List.length ys
xs_ih : val ∈ ys ↔ x ∈ xs
⊢ List.NodupKeys (List.map Prod.toSigma (List.zip xs ys))
[PROOFSTEP]
simp only [Prod.toSigma, List.mem_map, heq_iff_eq, Prod.exists] at h₃ 
[GOAL]
case this
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
x val x' : α
xs : List α
y : α
ys : List α
h₁ : List.length (x' :: xs) = List.length (y :: ys)
h : ¬x' = x
h₅ : List.Pairwise (fun x x_1 => x ≠ x_1) xs
h₀ : ∀ (a' : α), a' ∈ xs → x' ≠ a'
h₄ : List.Pairwise (fun x x_1 => x ≠ x_1) ys
h₂ : ∀ (a' : α), a' ∈ ys → y ≠ a'
h₆ : List.length xs = List.length ys
xs_ih : val ∈ ys ↔ x ∈ xs
h₃ : ∃ a b, (a, b) ∈ List.zip xs ys ∧ { fst := a, snd := b } = { fst := x, snd := val }
⊢ val ∈ ys
case this
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
x val x' : α
xs : List α
y : α
ys : List α
h₁ : List.length (x' :: xs) = List.length (y :: ys)
h : ¬x' = x
h₃ : val ∈ List.dlookup x (List.map Prod.toSigma (List.zip xs ys))
h₅ : List.Pairwise (fun x x_1 => x ≠ x_1) xs
h₀ : ∀ (a' : α), a' ∈ xs → x' ≠ a'
h₄ : List.Pairwise (fun x x_1 => x ≠ x_1) ys
h₂ : ∀ (a' : α), a' ∈ ys → y ≠ a'
h₆ : List.length xs = List.length ys
xs_ih : val ∈ ys ↔ x ∈ xs
⊢ List.NodupKeys (List.map Prod.toSigma (List.zip xs ys))
[PROOFSTEP]
rcases h₃ with ⟨a, b, h₃, h₄, h₅⟩
[GOAL]
case this.intro.intro.intro.refl
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
x val x' : α
xs : List α
y : α
ys : List α
h₁ : List.length (x' :: xs) = List.length (y :: ys)
h : ¬x' = x
h₅ : List.Pairwise (fun x x_1 => x ≠ x_1) xs
h₀ : ∀ (a' : α), a' ∈ xs → x' ≠ a'
h₄ : List.Pairwise (fun x x_1 => x ≠ x_1) ys
h₂ : ∀ (a' : α), a' ∈ ys → y ≠ a'
h₆ : List.length xs = List.length ys
xs_ih : val ∈ ys ↔ x ∈ xs
h₃ : (x, val) ∈ List.zip xs ys
⊢ val ∈ ys
case this
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
x val x' : α
xs : List α
y : α
ys : List α
h₁ : List.length (x' :: xs) = List.length (y :: ys)
h : ¬x' = x
h₃ : val ∈ List.dlookup x (List.map Prod.toSigma (List.zip xs ys))
h₅ : List.Pairwise (fun x x_1 => x ≠ x_1) xs
h₀ : ∀ (a' : α), a' ∈ xs → x' ≠ a'
h₄ : List.Pairwise (fun x x_1 => x ≠ x_1) ys
h₂ : ∀ (a' : α), a' ∈ ys → y ≠ a'
h₆ : List.length xs = List.length ys
xs_ih : val ∈ ys ↔ x ∈ xs
⊢ List.NodupKeys (List.map Prod.toSigma (List.zip xs ys))
[PROOFSTEP]
apply (List.mem_zip h₃).2
[GOAL]
case this
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
x val x' : α
xs : List α
y : α
ys : List α
h₁ : List.length (x' :: xs) = List.length (y :: ys)
h : ¬x' = x
h₃ : val ∈ List.dlookup x (List.map Prod.toSigma (List.zip xs ys))
h₅ : List.Pairwise (fun x x_1 => x ≠ x_1) xs
h₀ : ∀ (a' : α), a' ∈ xs → x' ≠ a'
h₄ : List.Pairwise (fun x x_1 => x ≠ x_1) ys
h₂ : ∀ (a' : α), a' ∈ ys → y ≠ a'
h₆ : List.length xs = List.length ys
xs_ih : val ∈ ys ↔ x ∈ xs
⊢ List.NodupKeys (List.map Prod.toSigma (List.zip xs ys))
[PROOFSTEP]
simp only [List.NodupKeys, List.keys, comp, Prod.fst_toSigma, List.map_map]
[GOAL]
case this
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
x val x' : α
xs : List α
y : α
ys : List α
h₁ : List.length (x' :: xs) = List.length (y :: ys)
h : ¬x' = x
h₃ : val ∈ List.dlookup x (List.map Prod.toSigma (List.zip xs ys))
h₅ : List.Pairwise (fun x x_1 => x ≠ x_1) xs
h₀ : ∀ (a' : α), a' ∈ xs → x' ≠ a'
h₄ : List.Pairwise (fun x x_1 => x ≠ x_1) ys
h₂ : ∀ (a' : α), a' ∈ ys → y ≠ a'
h₆ : List.length xs = List.length ys
xs_ih : val ∈ ys ↔ x ∈ xs
⊢ List.Nodup (List.map (fun x => x.fst) (List.zip xs ys))
[PROOFSTEP]
rwa [List.map_fst_zip _ _ (le_of_eq h₆)]
[GOAL]
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
x : α
⊢ ¬x ∈ xs → applyId (List.zip xs ys) x = x
[PROOFSTEP]
intro h
[GOAL]
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
x : α
h : ¬x ∈ xs
⊢ applyId (List.zip xs ys) x = x
[PROOFSTEP]
dsimp [List.applyId]
[GOAL]
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
x : α
h : ¬x ∈ xs
⊢ Option.getD (List.dlookup x (List.map Prod.toSigma (List.zip xs ys))) x = x
[PROOFSTEP]
rw [List.dlookup_eq_none.2]
[GOAL]
α : 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 ∈ List.keys (List.map Prod.toSigma (List.zip xs ys))
[PROOFSTEP]
rfl
[GOAL]
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
x : α
h : ¬x ∈ xs
⊢ ¬x ∈ List.keys (List.map Prod.toSigma (List.zip xs ys))
[PROOFSTEP]
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]
[GOAL]
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
x : α
h : ¬x ∈ xs
⊢ ∀ (x_1 : α), ¬(x, x_1) ∈ List.zip xs ys
[PROOFSTEP]
intro y hy
[GOAL]
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
x : α
h : ¬x ∈ xs
y : α
hy : (x, y) ∈ List.zip xs ys
⊢ False
[PROOFSTEP]
exact h (List.mem_zip hy).1
[GOAL]
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : List.Nodup xs
h₁ : xs ~ ys
⊢ Injective (applyId (List.zip xs ys))
[PROOFSTEP]
intro x y h
[GOAL]
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : List.Nodup xs
h₁ : xs ~ ys
x y : α
h : applyId (List.zip xs ys) x = applyId (List.zip xs ys) y
⊢ x = y
[PROOFSTEP]
by_cases hx : x ∈ xs
[GOAL]
case pos
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : List.Nodup xs
h₁ : xs ~ ys
x y : α
h : applyId (List.zip xs ys) x = applyId (List.zip xs ys) y
hx : x ∈ xs
⊢ x = y
[PROOFSTEP]
by_cases hy : y ∈ xs
[GOAL]
case neg
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : List.Nodup xs
h₁ : xs ~ ys
x y : α
h : applyId (List.zip xs ys) x = applyId (List.zip xs ys) y
hx : ¬x ∈ xs
⊢ x = y
[PROOFSTEP]
by_cases hy : y ∈ xs
[GOAL]
case pos
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : List.Nodup xs
h₁ : xs ~ ys
x y : α
h : applyId (List.zip xs ys) x = applyId (List.zip xs ys) y
hx : x ∈ xs
hy : y ∈ xs
⊢ x = y
[PROOFSTEP]
rw [List.mem_iff_get?] at hx hy 
[GOAL]
case pos
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : List.Nodup xs
h₁ : xs ~ ys
x y : α
h : applyId (List.zip xs ys) x = applyId (List.zip xs ys) y
hx : ∃ n, List.get? xs n = some x
hy : ∃ n, List.get? xs n = some y
⊢ x = y
[PROOFSTEP]
cases' hx with i hx
[GOAL]
case pos.intro
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : List.Nodup xs
h₁ : xs ~ ys
x y : α
h : applyId (List.zip xs ys) x = applyId (List.zip xs ys) y
hy : ∃ n, List.get? xs n = some y
i : ℕ
hx : List.get? xs i = some x
⊢ x = y
[PROOFSTEP]
cases' hy with j hy
[GOAL]
case pos.intro.intro
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : List.Nodup xs
h₁ : xs ~ ys
x y : α
h : applyId (List.zip xs ys) x = applyId (List.zip xs ys) y
i : ℕ
hx : List.get? xs i = some x
j : ℕ
hy : List.get? xs j = some y
⊢ x = y
[PROOFSTEP]
suffices some x = some y by injection this
[GOAL]
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : List.Nodup xs
h₁ : xs ~ ys
x y : α
h : applyId (List.zip xs ys) x = applyId (List.zip xs ys) y
i : ℕ
hx : List.get? xs i = some x
j : ℕ
hy : List.get? xs j = some y
this : some x = some y
⊢ x = y
[PROOFSTEP]
injection this
[GOAL]
case pos.intro.intro
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : List.Nodup xs
h₁ : xs ~ ys
x y : α
h : applyId (List.zip xs ys) x = applyId (List.zip xs ys) y
i : ℕ
hx : List.get? xs i = some x
j : ℕ
hy : List.get? xs j = some y
⊢ some x = some y
[PROOFSTEP]
have h₂ := h₁.length_eq
[GOAL]
case pos.intro.intro
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : List.Nodup xs
h₁ : xs ~ ys
x y : α
h : applyId (List.zip xs ys) x = applyId (List.zip xs ys) y
i : ℕ
hx : List.get? xs i = some x
j : ℕ
hy : List.get? xs j = some y
h₂ : List.length xs = List.length ys
⊢ some x = some y
[PROOFSTEP]
rw [List.applyId_zip_eq h₀ h₂ _ _ _ hx] at h 
[GOAL]
case pos.intro.intro
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : List.Nodup xs
h₁ : xs ~ ys
x y : α
i : ℕ
h : List.get? ys i = some (applyId (List.zip xs ys) y)
hx : List.get? xs i = some x
j : ℕ
hy : List.get? xs j = some y
h₂ : List.length xs = List.length ys
⊢ some x = some y
[PROOFSTEP]
rw [← hx, ← hy]
[GOAL]
case pos.intro.intro
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : List.Nodup xs
h₁ : xs ~ ys
x y : α
i : ℕ
h : List.get? ys i = some (applyId (List.zip xs ys) y)
hx : List.get? xs i = some x
j : ℕ
hy : List.get? xs j = some y
h₂ : List.length xs = List.length ys
⊢ List.get? xs i = List.get? xs j
[PROOFSTEP]
congr
[GOAL]
case pos.intro.intro.e_a
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : List.Nodup xs
h₁ : xs ~ ys
x y : α
i : ℕ
h : List.get? ys i = some (applyId (List.zip xs ys) y)
hx : List.get? xs i = some x
j : ℕ
hy : List.get? xs j = some y
h₂ : List.length xs = List.length ys
⊢ i = j
[PROOFSTEP]
apply List.get?_injective _ (h₁.nodup_iff.1 h₀)
[GOAL]
case pos.intro.intro.e_a
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : List.Nodup xs
h₁ : xs ~ ys
x y : α
i : ℕ
h : List.get? ys i = some (applyId (List.zip xs ys) y)
hx : List.get? xs i = some x
j : ℕ
hy : List.get? xs j = some y
h₂ : List.length xs = List.length ys
⊢ List.get? ys i = List.get? ys j
[PROOFSTEP]
symm
[GOAL]
case pos.intro.intro.e_a
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : List.Nodup xs
h₁ : xs ~ ys
x y : α
i : ℕ
h : List.get? ys i = some (applyId (List.zip xs ys) y)
hx : List.get? xs i = some x
j : ℕ
hy : List.get? xs j = some y
h₂ : List.length xs = List.length ys
⊢ List.get? ys j = List.get? ys i
[PROOFSTEP]
rw [h]
[GOAL]
case pos.intro.intro.e_a
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : List.Nodup xs
h₁ : xs ~ ys
x y : α
i : ℕ
h : List.get? ys i = some (applyId (List.zip xs ys) y)
hx : List.get? xs i = some x
j : ℕ
hy : List.get? xs j = some y
h₂ : List.length xs = List.length ys
⊢ List.get? ys j = some (applyId (List.zip xs ys) y)
[PROOFSTEP]
rw [← List.applyId_zip_eq]
[GOAL]
case pos.intro.intro.e_a.h₀
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : List.Nodup xs
h₁ : xs ~ ys
x y : α
i : ℕ
h : List.get? ys i = some (applyId (List.zip xs ys) y)
hx : List.get? xs i = some x
j : ℕ
hy : List.get? xs j = some y
h₂ : List.length xs = List.length ys
⊢ List.Nodup xs
[PROOFSTEP]
assumption
[GOAL]
case pos.intro.intro.e_a.h₁
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : List.Nodup xs
h₁ : xs ~ ys
x y : α
i : ℕ
h : List.get? ys i = some (applyId (List.zip xs ys) y)
hx : List.get? xs i = some x
j : ℕ
hy : List.get? xs j = some y
h₂ : List.length xs = List.length ys
⊢ List.length xs = List.length ys
[PROOFSTEP]
assumption
[GOAL]
case pos.intro.intro.e_a.h₂
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : List.Nodup xs
h₁ : xs ~ ys
x y : α
i : ℕ
h : List.get? ys i = some (applyId (List.zip xs ys) y)
hx : List.get? xs i = some x
j : ℕ
hy : List.get? xs j = some y
h₂ : List.length xs = List.length ys
⊢ List.get? xs j = some y
[PROOFSTEP]
assumption
[GOAL]
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : List.Nodup xs
h₁ : xs ~ ys
x y : α
i : ℕ
h : List.get? ys i = some (applyId (List.zip xs ys) y)
hx : List.get? xs i = some x
j : ℕ
hy : List.get? xs j = some y
h₂ : List.length xs = List.length ys
⊢ i < List.length ys
[PROOFSTEP]
rw [← h₁.length_eq]
[GOAL]
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : List.Nodup xs
h₁ : xs ~ ys
x y : α
i : ℕ
h : List.get? ys i = some (applyId (List.zip xs ys) y)
hx : List.get? xs i = some x
j : ℕ
hy : List.get? xs j = some y
h₂ : List.length xs = List.length ys
⊢ i < List.length xs
[PROOFSTEP]
rw [List.get?_eq_some] at hx 
[GOAL]
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : List.Nodup xs
h₁ : xs ~ ys
x y : α
i : ℕ
h : List.get? ys i = some (applyId (List.zip xs ys) y)
hx : ∃ h, List.get xs { val := i, isLt := h } = x
j : ℕ
hy : List.get? xs j = some y
h₂ : List.length xs = List.length ys
⊢ i < List.length xs
[PROOFSTEP]
cases' hx with hx hx'
[GOAL]
case intro
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : List.Nodup xs
h₁ : xs ~ ys
x y : α
i : ℕ
h : List.get? ys i = some (applyId (List.zip xs ys) y)
j : ℕ
hy : List.get? xs j = some y
h₂ : List.length xs = List.length ys
hx : i < List.length xs
hx' : List.get xs { val := i, isLt := hx } = x
⊢ i < List.length xs
[PROOFSTEP]
exact hx
[GOAL]
case neg
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : List.Nodup xs
h₁ : xs ~ ys
x y : α
h : applyId (List.zip xs ys) x = applyId (List.zip xs ys) y
hx : x ∈ xs
hy : ¬y ∈ xs
⊢ x = y
[PROOFSTEP]
rw [← applyId_mem_iff h₀ h₁] at hx hy 
[GOAL]
case neg
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : List.Nodup xs
h₁ : xs ~ ys
x y : α
h : applyId (List.zip xs ys) x = applyId (List.zip xs ys) y
hx : applyId (List.zip xs ys) x ∈ ys
hy : ¬applyId (List.zip xs ys) y ∈ ys
⊢ x = y
[PROOFSTEP]
rw [h] at hx 
[GOAL]
case neg
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : List.Nodup xs
h₁ : xs ~ ys
x y : α
h : applyId (List.zip xs ys) x = applyId (List.zip xs ys) y
hx : applyId (List.zip xs ys) y ∈ ys
hy : ¬applyId (List.zip xs ys) y ∈ ys
⊢ x = y
[PROOFSTEP]
contradiction
[GOAL]
case pos
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : List.Nodup xs
h₁ : xs ~ ys
x y : α
h : applyId (List.zip xs ys) x = applyId (List.zip xs ys) y
hx : ¬x ∈ xs
hy : y ∈ xs
⊢ x = y
[PROOFSTEP]
rw [← applyId_mem_iff h₀ h₁] at hx hy 
[GOAL]
case pos
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : List.Nodup xs
h₁ : xs ~ ys
x y : α
h : applyId (List.zip xs ys) x = applyId (List.zip xs ys) y
hx : ¬applyId (List.zip xs ys) x ∈ ys
hy : applyId (List.zip xs ys) y ∈ ys
⊢ x = y
[PROOFSTEP]
rw [h] at hx 
[GOAL]
case pos
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : List.Nodup xs
h₁ : xs ~ ys
x y : α
h : applyId (List.zip xs ys) x = applyId (List.zip xs ys) y
hx : ¬applyId (List.zip xs ys) y ∈ ys
hy : applyId (List.zip xs ys) y ∈ ys
⊢ x = y
[PROOFSTEP]
contradiction
[GOAL]
case neg
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : List.Nodup xs
h₁ : xs ~ ys
x y : α
h : applyId (List.zip xs ys) x = applyId (List.zip xs ys) y
hx : ¬x ∈ xs
hy : ¬y ∈ xs
⊢ x = y
[PROOFSTEP]
rwa [List.applyId_eq_self, List.applyId_eq_self] at h 
[GOAL]
case neg.a
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : List.Nodup xs
h₁ : xs ~ ys
x y : α
h : x = applyId (List.zip xs ys) y
hx : ¬x ∈ xs
hy : ¬y ∈ xs
⊢ ¬y ∈ xs
[PROOFSTEP]
assumption
[GOAL]
case neg.a
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs ys : List α
h₀ : List.Nodup xs
h₁ : xs ~ ys
x y : α
h : applyId (List.zip xs ys) x = applyId (List.zip xs ys) y
hx : ¬x ∈ xs
hy : ¬y ∈ xs
⊢ ¬x ∈ xs
[PROOFSTEP]
assumption
[GOAL]
α : Type u
β : Type v
γ : Sort w
x✝ : ℕ
n : ℕ := x✝
h : 0 < n
⊢ 1 < 2
[PROOFSTEP]
decide
[GOAL]
α✝ : Type u
β : Type v
γ : Sort w
α : Type
inst✝ : DecidableEq α
xs : List ((_ : α) × α)
h₀✝ : List.map Sigma.fst xs ~ List.map Sigma.snd xs
h₁✝ : List.Nodup (List.map Sigma.snd xs)
xs' ys' : List α
h₀ : xs' ~ ys'
h₁ : List.Nodup ys'
h₃ : List.length xs' ≤ List.length ys'
h₄ : List.length ys' ≤ List.length xs'
⊢ List.map Sigma.fst (List.map Prod.toSigma (List.zip xs' ys')) ~
    List.map Sigma.snd (List.map Prod.toSigma (List.zip xs' ys'))
[PROOFSTEP]
simp only [comp, List.map_fst_zip, List.map_snd_zip, *, Prod.fst_toSigma, Prod.snd_toSigma, List.map_map]
[GOAL]
α✝ : Type u
β : Type v
γ : Sort w
α : Type
inst✝ : DecidableEq α
xs : List ((_ : α) × α)
h₀✝ : List.map Sigma.fst xs ~ List.map Sigma.snd xs
h₁✝ : List.Nodup (List.map Sigma.snd xs)
xs' ys' : List α
h₀ : xs' ~ ys'
h₁ : List.Nodup ys'
h₃ : List.length xs' ≤ List.length ys'
h₄ : List.length ys' ≤ List.length xs'
⊢ List.Nodup (List.map Sigma.snd (List.map Prod.toSigma (List.zip xs' ys')))
[PROOFSTEP]
simp only [comp, List.map_snd_zip, *, Prod.snd_toSigma, List.map_map]
[GOAL]
α : Type u
β : Type v
γ : Sort w
xs ys : List α
h : xs ~ ys
h' : List.Nodup ys
h₀ : List.length xs ≤ List.length ys
h₁ : List.length ys ≤ List.length xs
⊢ List.map Sigma.fst (List.toFinmap' (List.zip xs ys)) ~ List.map Sigma.snd (List.toFinmap' (List.zip xs ys))
[PROOFSTEP]
simp only [List.toFinmap', comp, List.map_fst_zip, List.map_snd_zip, *, Prod.fst_toSigma, Prod.snd_toSigma,
  List.map_map]
[GOAL]
α : Type u
β : Type v
γ : Sort w
xs ys : List α
h : xs ~ ys
h' : List.Nodup ys
h₀ : List.length xs ≤ List.length ys
h₁ : List.length ys ≤ List.length xs
⊢ List.Nodup (List.map Sigma.snd (List.toFinmap' (List.zip xs ys)))
[PROOFSTEP]
simp only [List.toFinmap', comp, List.map_snd_zip, *, Prod.snd_toSigma, List.map_map]
[GOAL]
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
f : InjectiveFunction α
⊢ Injective (apply f)
[PROOFSTEP]
cases' f with xs hperm hnodup
[GOAL]
case mapToSelf
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs : List ((_ : α) × α)
hperm : List.map Sigma.fst xs ~ List.map Sigma.snd xs
hnodup : List.Nodup (List.map Sigma.snd xs)
⊢ Injective (apply (mapToSelf xs hperm hnodup))
[PROOFSTEP]
generalize h₀ : List.map Sigma.fst xs = xs₀
[GOAL]
case mapToSelf
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs : List ((_ : α) × α)
hperm : List.map Sigma.fst xs ~ List.map Sigma.snd xs
hnodup : List.Nodup (List.map Sigma.snd xs)
xs₀ : List α
h₀ : List.map Sigma.fst xs = xs₀
⊢ Injective (apply (mapToSelf xs hperm hnodup))
[PROOFSTEP]
generalize h₁ : xs.map (@id ((Σ _ : α, α) → α) <| @Sigma.snd α fun _ : α => α) = xs₁
[GOAL]
case mapToSelf
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs : List ((_ : α) × α)
hperm : List.map Sigma.fst xs ~ List.map Sigma.snd xs
hnodup : List.Nodup (List.map Sigma.snd xs)
xs₀ : List α
h₀ : List.map Sigma.fst xs = xs₀
xs₁ : List α
h₁ : List.map (id Sigma.snd) xs = xs₁
⊢ Injective (apply (mapToSelf xs hperm hnodup))
[PROOFSTEP]
dsimp [id] at h₁ 
[GOAL]
case mapToSelf
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs : List ((_ : α) × α)
hperm : List.map Sigma.fst xs ~ List.map Sigma.snd xs
hnodup : List.Nodup (List.map Sigma.snd xs)
xs₀ : List α
h₀ : List.map Sigma.fst xs = xs₀
xs₁ : List α
h₁ : List.map Sigma.snd xs = xs₁
⊢ Injective (apply (mapToSelf xs hperm hnodup))
[PROOFSTEP]
have hxs : xs = TotalFunction.List.toFinmap' (xs₀.zip xs₁) :=
  by
  rw [← h₀, ← h₁, List.toFinmap']; clear h₀ h₁ xs₀ xs₁ hperm hnodup
  induction xs
  case nil => simp only [List.zip_nil_right, List.map_nil]
  case cons xs_hd xs_tl
    xs_ih =>
    simp only [true_and_iff, Prod.toSigma, eq_self_iff_true, Sigma.eta, List.zip_cons_cons, List.map, List.cons_inj]
    exact xs_ih
[GOAL]
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs : List ((_ : α) × α)
hperm : List.map Sigma.fst xs ~ List.map Sigma.snd xs
hnodup : List.Nodup (List.map Sigma.snd xs)
xs₀ : List α
h₀ : List.map Sigma.fst xs = xs₀
xs₁ : List α
h₁ : List.map Sigma.snd xs = xs₁
⊢ xs = List.toFinmap' (List.zip xs₀ xs₁)
[PROOFSTEP]
rw [← h₀, ← h₁, List.toFinmap']
[GOAL]
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs : List ((_ : α) × α)
hperm : List.map Sigma.fst xs ~ List.map Sigma.snd xs
hnodup : List.Nodup (List.map Sigma.snd xs)
xs₀ : List α
h₀ : List.map Sigma.fst xs = xs₀
xs₁ : List α
h₁ : List.map Sigma.snd xs = xs₁
⊢ xs = List.map Prod.toSigma (List.zip (List.map Sigma.fst xs) (List.map Sigma.snd xs))
[PROOFSTEP]
clear h₀ h₁ xs₀ xs₁ hperm hnodup
[GOAL]
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs : List ((_ : α) × α)
⊢ xs = List.map Prod.toSigma (List.zip (List.map Sigma.fst xs) (List.map Sigma.snd xs))
[PROOFSTEP]
induction xs
[GOAL]
case nil
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
⊢ [] = List.map Prod.toSigma (List.zip (List.map Sigma.fst []) (List.map Sigma.snd []))
case cons
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
head✝ : (_ : α) × α
tail✝ : List ((_ : α) × α)
tail_ih✝ : tail✝ = List.map Prod.toSigma (List.zip (List.map Sigma.fst tail✝) (List.map Sigma.snd tail✝))
⊢ head✝ :: tail✝ =
    List.map Prod.toSigma (List.zip (List.map Sigma.fst (head✝ :: tail✝)) (List.map Sigma.snd (head✝ :: tail✝)))
[PROOFSTEP]
case nil => simp only [List.zip_nil_right, List.map_nil]
[GOAL]
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
⊢ [] = List.map Prod.toSigma (List.zip (List.map Sigma.fst []) (List.map Sigma.snd []))
[PROOFSTEP]
case nil => simp only [List.zip_nil_right, List.map_nil]
[GOAL]
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
⊢ [] = List.map Prod.toSigma (List.zip (List.map Sigma.fst []) (List.map Sigma.snd []))
[PROOFSTEP]
simp only [List.zip_nil_right, List.map_nil]
[GOAL]
case cons
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
head✝ : (_ : α) × α
tail✝ : List ((_ : α) × α)
tail_ih✝ : tail✝ = List.map Prod.toSigma (List.zip (List.map Sigma.fst tail✝) (List.map Sigma.snd tail✝))
⊢ head✝ :: tail✝ =
    List.map Prod.toSigma (List.zip (List.map Sigma.fst (head✝ :: tail✝)) (List.map Sigma.snd (head✝ :: tail✝)))
[PROOFSTEP]
case cons xs_hd xs_tl
  xs_ih =>
  simp only [true_and_iff, Prod.toSigma, eq_self_iff_true, Sigma.eta, List.zip_cons_cons, List.map, List.cons_inj]
  exact xs_ih
[GOAL]
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs_hd : (_ : α) × α
xs_tl : List ((_ : α) × α)
xs_ih : xs_tl = List.map Prod.toSigma (List.zip (List.map Sigma.fst xs_tl) (List.map Sigma.snd xs_tl))
⊢ xs_hd :: xs_tl =
    List.map Prod.toSigma (List.zip (List.map Sigma.fst (xs_hd :: xs_tl)) (List.map Sigma.snd (xs_hd :: xs_tl)))
[PROOFSTEP]
case cons xs_hd xs_tl
  xs_ih =>
  simp only [true_and_iff, Prod.toSigma, eq_self_iff_true, Sigma.eta, List.zip_cons_cons, List.map, List.cons_inj]
  exact xs_ih
[GOAL]
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs_hd : (_ : α) × α
xs_tl : List ((_ : α) × α)
xs_ih : xs_tl = List.map Prod.toSigma (List.zip (List.map Sigma.fst xs_tl) (List.map Sigma.snd xs_tl))
⊢ xs_hd :: xs_tl =
    List.map Prod.toSigma (List.zip (List.map Sigma.fst (xs_hd :: xs_tl)) (List.map Sigma.snd (xs_hd :: xs_tl)))
[PROOFSTEP]
simp only [true_and_iff, Prod.toSigma, eq_self_iff_true, Sigma.eta, List.zip_cons_cons, List.map, List.cons_inj]
[GOAL]
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs_hd : (_ : α) × α
xs_tl : List ((_ : α) × α)
xs_ih : xs_tl = List.map Prod.toSigma (List.zip (List.map Sigma.fst xs_tl) (List.map Sigma.snd xs_tl))
⊢ xs_tl =
    List.map (fun p => { fst := p.fst, snd := p.snd })
      (List.zipWith Prod.mk (List.map Sigma.fst xs_tl) (List.map Sigma.snd xs_tl))
[PROOFSTEP]
exact xs_ih
[GOAL]
case mapToSelf
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs : List ((_ : α) × α)
hperm : List.map Sigma.fst xs ~ List.map Sigma.snd xs
hnodup : List.Nodup (List.map Sigma.snd xs)
xs₀ : List α
h₀ : List.map Sigma.fst xs = xs₀
xs₁ : List α
h₁ : List.map Sigma.snd xs = xs₁
hxs : xs = List.toFinmap' (List.zip xs₀ xs₁)
⊢ Injective (apply (mapToSelf xs hperm hnodup))
[PROOFSTEP]
revert hperm hnodup
[GOAL]
case mapToSelf
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs : List ((_ : α) × α)
xs₀ : List α
h₀ : List.map Sigma.fst xs = xs₀
xs₁ : List α
h₁ : List.map Sigma.snd xs = xs₁
hxs : xs = List.toFinmap' (List.zip xs₀ xs₁)
⊢ ∀ (hperm : List.map Sigma.fst xs ~ List.map Sigma.snd xs) (hnodup : List.Nodup (List.map Sigma.snd xs)),
    Injective (apply (mapToSelf xs hperm hnodup))
[PROOFSTEP]
rw [hxs]
[GOAL]
case mapToSelf
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs : List ((_ : α) × α)
xs₀ : List α
h₀ : List.map Sigma.fst xs = xs₀
xs₁ : List α
h₁ : List.map Sigma.snd xs = xs₁
hxs : xs = List.toFinmap' (List.zip xs₀ xs₁)
⊢ ∀
    (hperm :
      List.map Sigma.fst (List.toFinmap' (List.zip xs₀ xs₁)) ~ List.map Sigma.snd (List.toFinmap' (List.zip xs₀ xs₁)))
    (hnodup : List.Nodup (List.map Sigma.snd (List.toFinmap' (List.zip xs₀ xs₁)))),
    Injective (apply (mapToSelf (List.toFinmap' (List.zip xs₀ xs₁)) hperm hnodup))
[PROOFSTEP]
intros hperm hnodup
[GOAL]
case mapToSelf
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs : List ((_ : α) × α)
xs₀ : List α
h₀ : List.map Sigma.fst xs = xs₀
xs₁ : List α
h₁ : List.map Sigma.snd xs = xs₁
hxs : xs = List.toFinmap' (List.zip xs₀ xs₁)
hperm : List.map Sigma.fst (List.toFinmap' (List.zip xs₀ xs₁)) ~ List.map Sigma.snd (List.toFinmap' (List.zip xs₀ xs₁))
hnodup : List.Nodup (List.map Sigma.snd (List.toFinmap' (List.zip xs₀ xs₁)))
⊢ Injective (apply (mapToSelf (List.toFinmap' (List.zip xs₀ xs₁)) hperm hnodup))
[PROOFSTEP]
apply InjectiveFunction.applyId_injective
[GOAL]
case mapToSelf.h₀
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs : List ((_ : α) × α)
xs₀ : List α
h₀ : List.map Sigma.fst xs = xs₀
xs₁ : List α
h₁ : List.map Sigma.snd xs = xs₁
hxs : xs = List.toFinmap' (List.zip xs₀ xs₁)
hperm : List.map Sigma.fst (List.toFinmap' (List.zip xs₀ xs₁)) ~ List.map Sigma.snd (List.toFinmap' (List.zip xs₀ xs₁))
hnodup : List.Nodup (List.map Sigma.snd (List.toFinmap' (List.zip xs₀ xs₁)))
⊢ List.Nodup xs₀
[PROOFSTEP]
rwa [← h₀, hxs, hperm.nodup_iff]
[GOAL]
case mapToSelf.h₁
α : Type u
β : Type v
γ : Sort w
inst✝ : DecidableEq α
xs : List ((_ : α) × α)
xs₀ : List α
h₀ : List.map Sigma.fst xs = xs₀
xs₁ : List α
h₁ : List.map Sigma.snd xs = xs₁
hxs : xs = List.toFinmap' (List.zip xs₀ xs₁)
hperm : List.map Sigma.fst (List.toFinmap' (List.zip xs₀ xs₁)) ~ List.map Sigma.snd (List.toFinmap' (List.zip xs₀ xs₁))
hnodup : List.Nodup (List.map Sigma.snd (List.toFinmap' (List.zip xs₀ xs₁)))
⊢ xs₀ ~ xs₁
[PROOFSTEP]
rwa [← hxs, h₀, h₁] at hperm 
