[GOAL]
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
a : α
l : List (Sigma β)
h₁ : ¬a ∈ keys l
s : Sigma β
h₂ : s ∈ l
e : a = s.fst
⊢ ¬s.fst ∈ keys l
[PROOFSTEP]
rwa [e] at h₁ 
[GOAL]
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
s : Sigma β
l : List (Sigma β)
⊢ NodupKeys (s :: l) ↔ ¬s.fst ∈ keys l ∧ NodupKeys l
[PROOFSTEP]
simp [keys, NodupKeys]
[GOAL]
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
a : α
b b' : β a
l : List (Sigma β)
nd : NodupKeys l
h : { fst := a, snd := b } ∈ l
h' : { fst := a, snd := b' } ∈ l
⊢ b = b'
[PROOFSTEP]
cases nd.eq_of_fst_eq h h' rfl
[GOAL]
case refl
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
a : α
b : β a
l : List (Sigma β)
nd : NodupKeys l
h h' : { fst := a, snd := b } ∈ l
⊢ b = b
[PROOFSTEP]
rfl
[GOAL]
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
L : List (List (Sigma β))
⊢ NodupKeys (join L) ↔ (∀ (l : List (Sigma β)), l ∈ L → NodupKeys l) ∧ Pairwise Disjoint (map keys L)
[PROOFSTEP]
rw [nodupKeys_iff_pairwise, pairwise_join, pairwise_map]
[GOAL]
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
L : List (List (Sigma β))
⊢ (∀ (l : List (Sigma β)), l ∈ L → Pairwise (fun s s' => s.fst ≠ s'.fst) l) ∧
      Pairwise (fun l₁ l₂ => ∀ (x : Sigma β), x ∈ l₁ → ∀ (y : Sigma β), y ∈ l₂ → x.fst ≠ y.fst) L ↔
    (∀ (l : List (Sigma β)), l ∈ L → NodupKeys l) ∧ Pairwise (fun a b => Disjoint (keys a) (keys b)) L
[PROOFSTEP]
refine' and_congr (ball_congr fun l _ => by simp [nodupKeys_iff_pairwise]) _
[GOAL]
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
L : List (List (Sigma β))
l : List (Sigma β)
x✝ : l ∈ L
⊢ Pairwise (fun s s' => s.fst ≠ s'.fst) l ↔ NodupKeys l
[PROOFSTEP]
simp [nodupKeys_iff_pairwise]
[GOAL]
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
L : List (List (Sigma β))
⊢ Pairwise (fun l₁ l₂ => ∀ (x : Sigma β), x ∈ l₁ → ∀ (y : Sigma β), y ∈ l₂ → x.fst ≠ y.fst) L ↔
    Pairwise (fun a b => Disjoint (keys a) (keys b)) L
[PROOFSTEP]
apply iff_of_eq
[GOAL]
case a
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
L : List (List (Sigma β))
⊢ Pairwise (fun l₁ l₂ => ∀ (x : Sigma β), x ∈ l₁ → ∀ (y : Sigma β), y ∈ l₂ → x.fst ≠ y.fst) L =
    Pairwise (fun a b => Disjoint (keys a) (keys b)) L
[PROOFSTEP]
congr with (l₁ l₂)
[GOAL]
case a.e_R.h.h.a
α : Type u
β : α → Type v
l l₁✝ l₂✝ : List (Sigma β)
L : List (List (Sigma β))
l₁ l₂ : List (Sigma β)
⊢ (∀ (x : Sigma β), x ∈ l₁ → ∀ (y : Sigma β), y ∈ l₂ → x.fst ≠ y.fst) ↔ Disjoint (keys l₁) (keys l₂)
[PROOFSTEP]
simp [keys, disjoint_iff_ne]
[GOAL]
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
l : List α
⊢ Nodup (map Prod.fst (enum l))
[PROOFSTEP]
simp [List.nodup_range]
[GOAL]
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
⊢ Option.isSome (dlookup a []) = true ↔ a ∈ keys []
[PROOFSTEP]
simp
[GOAL]
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a a' : α
b : β a'
l : List (Sigma β)
⊢ Option.isSome (dlookup a ({ fst := a', snd := b } :: l)) = true ↔ a ∈ keys ({ fst := a', snd := b } :: l)
[PROOFSTEP]
by_cases h : a = a'
[GOAL]
case pos
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a a' : α
b : β a'
l : List (Sigma β)
h : a = a'
⊢ Option.isSome (dlookup a ({ fst := a', snd := b } :: l)) = true ↔ a ∈ keys ({ fst := a', snd := b } :: l)
[PROOFSTEP]
subst a'
[GOAL]
case pos
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l : List (Sigma β)
b : β a
⊢ Option.isSome (dlookup a ({ fst := a, snd := b } :: l)) = true ↔ a ∈ keys ({ fst := a, snd := b } :: l)
[PROOFSTEP]
simp
[GOAL]
case neg
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a a' : α
b : β a'
l : List (Sigma β)
h : ¬a = a'
⊢ Option.isSome (dlookup a ({ fst := a', snd := b } :: l)) = true ↔ a ∈ keys ({ fst := a', snd := b } :: l)
[PROOFSTEP]
simp [h, dlookup_isSome]
[GOAL]
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l : List (Sigma β)
⊢ dlookup a l = none ↔ ¬a ∈ keys l
[PROOFSTEP]
simp [← dlookup_isSome, Option.isNone_iff_eq_none]
[GOAL]
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
b : β a
a' : α
b' : β a'
l : List (Sigma β)
H : b ∈ dlookup a ({ fst := a', snd := b' } :: l)
⊢ { fst := a, snd := b } ∈ { fst := a', snd := b' } :: l
[PROOFSTEP]
by_cases h : a = a'
[GOAL]
case pos
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
b : β a
a' : α
b' : β a'
l : List (Sigma β)
H : b ∈ dlookup a ({ fst := a', snd := b' } :: l)
h : a = a'
⊢ { fst := a, snd := b } ∈ { fst := a', snd := b' } :: l
[PROOFSTEP]
subst a'
[GOAL]
case pos
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
b : β a
l : List (Sigma β)
b' : β a
H : b ∈ dlookup a ({ fst := a, snd := b' } :: l)
⊢ { fst := a, snd := b } ∈ { fst := a, snd := b' } :: l
[PROOFSTEP]
simp at H 
[GOAL]
case pos
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
b : β a
l : List (Sigma β)
b' : β a
H : b' = b
⊢ { fst := a, snd := b } ∈ { fst := a, snd := b' } :: l
[PROOFSTEP]
simp [H]
[GOAL]
case neg
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
b : β a
a' : α
b' : β a'
l : List (Sigma β)
H : b ∈ dlookup a ({ fst := a', snd := b' } :: l)
h : ¬a = a'
⊢ { fst := a, snd := b } ∈ { fst := a', snd := b' } :: l
[PROOFSTEP]
simp only [ne_eq, h, not_false_iff, dlookup_cons_ne] at H 
[GOAL]
case neg
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
b : β a
a' : α
b' : β a'
l : List (Sigma β)
h : ¬a = a'
H : b ∈ dlookup a l
⊢ { fst := a, snd := b } ∈ { fst := a', snd := b' } :: l
[PROOFSTEP]
simp [of_mem_dlookup H]
[GOAL]
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
b : β a
l : List (Sigma β)
nd : NodupKeys l
h : { fst := a, snd := b } ∈ l
⊢ b ∈ dlookup a l
[PROOFSTEP]
cases' Option.isSome_iff_exists.mp (dlookup_isSome.mpr (mem_keys_of_mem h)) with b' h'
[GOAL]
case intro
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
b : β a
l : List (Sigma β)
nd : NodupKeys l
h : { fst := a, snd := b } ∈ l
b' : β { fst := a, snd := b }.fst
h' : dlookup { fst := a, snd := b }.fst l = some b'
⊢ b ∈ dlookup a l
[PROOFSTEP]
cases nd.eq_of_mk_mem h (of_mem_dlookup h')
[GOAL]
case intro.refl
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
b : β a
l : List (Sigma β)
nd : NodupKeys l
h : { fst := a, snd := b } ∈ l
h' : dlookup { fst := a, snd := b }.fst l = some b
⊢ b ∈ dlookup a l
[PROOFSTEP]
exact h'
[GOAL]
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a a' : α
b' : β a'
l : List (Sigma β)
⊢ Option.map (Sigma.mk a) (dlookup a ({ fst := a', snd := b' } :: l)) =
    find? (fun s => decide (a = s.fst)) ({ fst := a', snd := b' } :: l)
[PROOFSTEP]
by_cases h : a = a'
[GOAL]
case pos
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a a' : α
b' : β a'
l : List (Sigma β)
h : a = a'
⊢ Option.map (Sigma.mk a) (dlookup a ({ fst := a', snd := b' } :: l)) =
    find? (fun s => decide (a = s.fst)) ({ fst := a', snd := b' } :: l)
[PROOFSTEP]
subst a'
[GOAL]
case pos
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l : List (Sigma β)
b' : β a
⊢ Option.map (Sigma.mk a) (dlookup a ({ fst := a, snd := b' } :: l)) =
    find? (fun s => decide (a = s.fst)) ({ fst := a, snd := b' } :: l)
[PROOFSTEP]
simp
[GOAL]
case neg
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a a' : α
b' : β a'
l : List (Sigma β)
h : ¬a = a'
⊢ Option.map (Sigma.mk a) (dlookup a ({ fst := a', snd := b' } :: l)) =
    find? (fun s => decide (a = s.fst)) ({ fst := a', snd := b' } :: l)
[PROOFSTEP]
simp [h]
[GOAL]
case neg
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a a' : α
b' : β a'
l : List (Sigma β)
h : ¬a = a'
⊢ Option.map (Sigma.mk a) (dlookup a l) = find? (fun s => decide (a = s.fst)) l
[PROOFSTEP]
exact map_dlookup_eq_find a l
[GOAL]
α : Type u
β : α → Type v
l l₁✝ l₂✝ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l₁ l₂ : List (Sigma β)
nd₁ : NodupKeys l₁
nd₂ : NodupKeys l₂
p : l₁ ~ l₂
⊢ dlookup a l₁ = dlookup a l₂
[PROOFSTEP]
ext b
[GOAL]
case a
α : Type u
β : α → Type v
l l₁✝ l₂✝ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l₁ l₂ : List (Sigma β)
nd₁ : NodupKeys l₁
nd₂ : NodupKeys l₂
p : l₁ ~ l₂
b : β a
⊢ b ∈ dlookup a l₁ ↔ b ∈ dlookup a l₂
[PROOFSTEP]
simp only [mem_dlookup_iff nd₁, mem_dlookup_iff nd₂]
[GOAL]
case a
α : Type u
β : α → Type v
l l₁✝ l₂✝ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l₁ l₂ : List (Sigma β)
nd₁ : NodupKeys l₁
nd₂ : NodupKeys l₂
p : l₁ ~ l₂
b : β a
⊢ { fst := a, snd := b } ∈ l₁ ↔ { fst := a, snd := b } ∈ l₂
[PROOFSTEP]
exact p.mem_iff
[GOAL]
α : Type u
β : α → Type v
l l₁✝ l₂ : List (Sigma β)
inst✝ : DecidableEq α
l₀ l₁ : List (Sigma β)
nd₀ : NodupKeys l₀
nd₁ : NodupKeys l₁
h : ∀ (x : α) (y : β x), y ∈ dlookup x l₀ ↔ y ∈ dlookup x l₁
x✝ : Sigma β
a : α
b : β a
⊢ { fst := a, snd := b } ∈ l₀ ↔ { fst := a, snd := b } ∈ l₁
[PROOFSTEP]
rw [← mem_dlookup_iff, ← mem_dlookup_iff, h]
[GOAL]
α : Type u
β : α → Type v
l l₁✝ l₂ : List (Sigma β)
inst✝ : DecidableEq α
l₀ l₁ : List (Sigma β)
nd₀ : NodupKeys l₀
nd₁ : NodupKeys l₁
h : ∀ (x : α) (y : β x), y ∈ dlookup x l₀ ↔ y ∈ dlookup x l₁
x✝ : Sigma β
a : α
b : β a
⊢ NodupKeys l₁
[PROOFSTEP]
assumption
[GOAL]
α : Type u
β : α → Type v
l l₁✝ l₂ : List (Sigma β)
inst✝ : DecidableEq α
l₀ l₁ : List (Sigma β)
nd₀ : NodupKeys l₀
nd₁ : NodupKeys l₁
h : ∀ (x : α) (y : β x), y ∈ dlookup x l₀ ↔ y ∈ dlookup x l₁
x✝ : Sigma β
a : α
b : β a
⊢ NodupKeys l₀
[PROOFSTEP]
assumption
[GOAL]
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
⊢ lookupAll a [] = [] ↔ ∀ (b : β a), ¬{ fst := a, snd := b } ∈ []
[PROOFSTEP]
simp
[GOAL]
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a a' : α
b : β a'
l : List (Sigma β)
⊢ lookupAll a ({ fst := a', snd := b } :: l) = [] ↔
    ∀ (b_1 : β a), ¬{ fst := a, snd := b_1 } ∈ { fst := a', snd := b } :: l
[PROOFSTEP]
by_cases h : a = a'
[GOAL]
case pos
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a a' : α
b : β a'
l : List (Sigma β)
h : a = a'
⊢ lookupAll a ({ fst := a', snd := b } :: l) = [] ↔
    ∀ (b_1 : β a), ¬{ fst := a, snd := b_1 } ∈ { fst := a', snd := b } :: l
[PROOFSTEP]
subst a'
[GOAL]
case pos
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l : List (Sigma β)
b : β a
⊢ lookupAll a ({ fst := a, snd := b } :: l) = [] ↔
    ∀ (b_1 : β a), ¬{ fst := a, snd := b_1 } ∈ { fst := a, snd := b } :: l
[PROOFSTEP]
simp
[GOAL]
case neg
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a a' : α
b : β a'
l : List (Sigma β)
h : ¬a = a'
⊢ lookupAll a ({ fst := a', snd := b } :: l) = [] ↔
    ∀ (b_1 : β a), ¬{ fst := a, snd := b_1 } ∈ { fst := a', snd := b } :: l
[PROOFSTEP]
simp [h, lookupAll_eq_nil]
[GOAL]
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
⊢ head? (lookupAll a []) = dlookup a []
[PROOFSTEP]
simp
[GOAL]
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a a' : α
b : β a'
l : List (Sigma β)
⊢ head? (lookupAll a ({ fst := a', snd := b } :: l)) = dlookup a ({ fst := a', snd := b } :: l)
[PROOFSTEP]
by_cases h : a = a'
[GOAL]
case pos
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a a' : α
b : β a'
l : List (Sigma β)
h : a = a'
⊢ head? (lookupAll a ({ fst := a', snd := b } :: l)) = dlookup a ({ fst := a', snd := b } :: l)
[PROOFSTEP]
subst h
[GOAL]
case pos
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l : List (Sigma β)
b : β a
⊢ head? (lookupAll a ({ fst := a, snd := b } :: l)) = dlookup a ({ fst := a, snd := b } :: l)
[PROOFSTEP]
simp
[GOAL]
case neg
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a a' : α
b : β a'
l : List (Sigma β)
h : ¬a = a'
⊢ head? (lookupAll a ({ fst := a', snd := b } :: l)) = dlookup a ({ fst := a', snd := b } :: l)
[PROOFSTEP]
rw [lookupAll_cons_ne, dlookup_cons_ne, head?_lookupAll a l]
[GOAL]
case neg.a
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a a' : α
b : β a'
l : List (Sigma β)
h : ¬a = a'
⊢ a ≠ { fst := a', snd := b }.fst
[PROOFSTEP]
assumption
[GOAL]
case neg.a
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a a' : α
b : β a'
l : List (Sigma β)
h : ¬a = a'
⊢ a ≠ { fst := a', snd := b }.fst
[PROOFSTEP]
assumption
[GOAL]
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
b : β a
⊢ b ∈ lookupAll a [] ↔ { fst := a, snd := b } ∈ []
[PROOFSTEP]
simp
[GOAL]
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
b : β a
a' : α
b' : β a'
l : List (Sigma β)
⊢ b ∈ lookupAll a ({ fst := a', snd := b' } :: l) ↔ { fst := a, snd := b } ∈ { fst := a', snd := b' } :: l
[PROOFSTEP]
by_cases h : a = a'
[GOAL]
case pos
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
b : β a
a' : α
b' : β a'
l : List (Sigma β)
h : a = a'
⊢ b ∈ lookupAll a ({ fst := a', snd := b' } :: l) ↔ { fst := a, snd := b } ∈ { fst := a', snd := b' } :: l
[PROOFSTEP]
subst h
[GOAL]
case pos
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
b : β a
l : List (Sigma β)
b' : β a
⊢ b ∈ lookupAll a ({ fst := a, snd := b' } :: l) ↔ { fst := a, snd := b } ∈ { fst := a, snd := b' } :: l
[PROOFSTEP]
simp [*, mem_lookupAll]
[GOAL]
case neg
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
b : β a
a' : α
b' : β a'
l : List (Sigma β)
h : ¬a = a'
⊢ b ∈ lookupAll a ({ fst := a', snd := b' } :: l) ↔ { fst := a, snd := b } ∈ { fst := a', snd := b' } :: l
[PROOFSTEP]
simp [*, mem_lookupAll]
[GOAL]
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
⊢ map (Sigma.mk a) (lookupAll a []) <+ []
[PROOFSTEP]
simp
[GOAL]
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a a' : α
b' : β a'
l : List (Sigma β)
⊢ map (Sigma.mk a) (lookupAll a ({ fst := a', snd := b' } :: l)) <+ { fst := a', snd := b' } :: l
[PROOFSTEP]
by_cases h : a = a'
[GOAL]
case pos
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a a' : α
b' : β a'
l : List (Sigma β)
h : a = a'
⊢ map (Sigma.mk a) (lookupAll a ({ fst := a', snd := b' } :: l)) <+ { fst := a', snd := b' } :: l
[PROOFSTEP]
subst h
[GOAL]
case pos
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l : List (Sigma β)
b' : β a
⊢ map (Sigma.mk a) (lookupAll a ({ fst := a, snd := b' } :: l)) <+ { fst := a, snd := b' } :: l
[PROOFSTEP]
simp only [ne_eq, not_true, lookupAll_cons_eq, List.map]
[GOAL]
case pos
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l : List (Sigma β)
b' : β a
⊢ { fst := a, snd := b' } :: map (Sigma.mk a) (lookupAll a l) <+ { fst := a, snd := b' } :: l
[PROOFSTEP]
exact (lookupAll_sublist a l).cons₂ _
[GOAL]
case neg
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a a' : α
b' : β a'
l : List (Sigma β)
h : ¬a = a'
⊢ map (Sigma.mk a) (lookupAll a ({ fst := a', snd := b' } :: l)) <+ { fst := a', snd := b' } :: l
[PROOFSTEP]
simp only [ne_eq, h, not_false_iff, lookupAll_cons_ne]
[GOAL]
case neg
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a a' : α
b' : β a'
l : List (Sigma β)
h : ¬a = a'
⊢ map (Sigma.mk a) (lookupAll a l) <+ { fst := a', snd := b' } :: l
[PROOFSTEP]
exact (lookupAll_sublist a l).cons _
[GOAL]
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l : List (Sigma β)
h : NodupKeys l
⊢ length (lookupAll a l) ≤ 1
[PROOFSTEP]
have := Nodup.sublist ((lookupAll_sublist a l).map _) h
[GOAL]
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l : List (Sigma β)
h : NodupKeys l
this : Nodup (map Sigma.fst (map (Sigma.mk a) (lookupAll a l)))
⊢ length (lookupAll a l) ≤ 1
[PROOFSTEP]
rw [map_map] at this 
[GOAL]
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l : List (Sigma β)
h : NodupKeys l
this : Nodup (map (Sigma.fst ∘ Sigma.mk a) (lookupAll a l))
⊢ length (lookupAll a l) ≤ 1
[PROOFSTEP]
rwa [← nodup_replicate, ← map_const]
[GOAL]
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l : List (Sigma β)
h : NodupKeys l
⊢ lookupAll a l = Option.toList (dlookup a l)
[PROOFSTEP]
rw [← head?_lookupAll]
[GOAL]
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l : List (Sigma β)
h : NodupKeys l
⊢ lookupAll a l = Option.toList (head? (lookupAll a l))
[PROOFSTEP]
have h1 := lookupAll_length_le_one a h
[GOAL]
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l : List (Sigma β)
h : NodupKeys l
h1 : length (lookupAll a l) ≤ 1
⊢ lookupAll a l = Option.toList (head? (lookupAll a l))
[PROOFSTEP]
revert h1
[GOAL]
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l : List (Sigma β)
h : NodupKeys l
⊢ length (lookupAll a l) ≤ 1 → lookupAll a l = Option.toList (head? (lookupAll a l))
[PROOFSTEP]
rcases lookupAll a l with (_ | ⟨b, _ | ⟨c, l⟩⟩)
[GOAL]
case nil
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l : List (Sigma β)
h : NodupKeys l
⊢ length [] ≤ 1 → [] = Option.toList (head? [])
[PROOFSTEP]
intro h1
[GOAL]
case cons.nil
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l : List (Sigma β)
h : NodupKeys l
b : β a
⊢ length [b] ≤ 1 → [b] = Option.toList (head? [b])
[PROOFSTEP]
intro h1
[GOAL]
case cons.cons
α : Type u
β : α → Type v
l✝¹ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l✝ : List (Sigma β)
h : NodupKeys l✝
b c : β a
l : List (β a)
⊢ length (b :: c :: l) ≤ 1 → b :: c :: l = Option.toList (head? (b :: c :: l))
[PROOFSTEP]
intro h1
[GOAL]
case nil
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l : List (Sigma β)
h : NodupKeys l
h1 : length [] ≤ 1
⊢ [] = Option.toList (head? [])
[PROOFSTEP]
try rfl
[GOAL]
case nil
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l : List (Sigma β)
h : NodupKeys l
h1 : length [] ≤ 1
⊢ [] = Option.toList (head? [])
[PROOFSTEP]
rfl
[GOAL]
case cons.nil
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l : List (Sigma β)
h : NodupKeys l
b : β a
h1 : length [b] ≤ 1
⊢ [b] = Option.toList (head? [b])
[PROOFSTEP]
try rfl
[GOAL]
case cons.nil
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l : List (Sigma β)
h : NodupKeys l
b : β a
h1 : length [b] ≤ 1
⊢ [b] = Option.toList (head? [b])
[PROOFSTEP]
rfl
[GOAL]
case cons.cons
α : Type u
β : α → Type v
l✝¹ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l✝ : List (Sigma β)
h : NodupKeys l✝
b c : β a
l : List (β a)
h1 : length (b :: c :: l) ≤ 1
⊢ b :: c :: l = Option.toList (head? (b :: c :: l))
[PROOFSTEP]
try rfl
[GOAL]
case cons.cons
α : Type u
β : α → Type v
l✝¹ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l✝ : List (Sigma β)
h : NodupKeys l✝
b c : β a
l : List (β a)
h1 : length (b :: c :: l) ≤ 1
⊢ b :: c :: l = Option.toList (head? (b :: c :: l))
[PROOFSTEP]
rfl
[GOAL]
case cons.cons
α : Type u
β : α → Type v
l✝¹ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l✝ : List (Sigma β)
h : NodupKeys l✝
b c : β a
l : List (β a)
h1 : length (b :: c :: l) ≤ 1
⊢ b :: c :: l = Option.toList (head? (b :: c :: l))
[PROOFSTEP]
exact absurd h1 (by simp)
[GOAL]
α : Type u
β : α → Type v
l✝¹ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l✝ : List (Sigma β)
h : NodupKeys l✝
b c : β a
l : List (β a)
h1 : length (b :: c :: l) ≤ 1
⊢ ¬length (b :: c :: l) ≤ 1
[PROOFSTEP]
simp
[GOAL]
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l : List (Sigma β)
h : NodupKeys l
⊢ Nodup (lookupAll a l)
[PROOFSTEP]
rw [lookupAll_eq_dlookup a h]
[GOAL]
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l : List (Sigma β)
h : NodupKeys l
⊢ Nodup (Option.toList (dlookup a l))
[PROOFSTEP]
apply Option.toList_nodup
[GOAL]
α : Type u
β : α → Type v
l l₁✝ l₂✝ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l₁ l₂ : List (Sigma β)
nd₁ : NodupKeys l₁
nd₂ : NodupKeys l₂
p : l₁ ~ l₂
⊢ lookupAll a l₁ = lookupAll a l₂
[PROOFSTEP]
simp [lookupAll_eq_dlookup, nd₁, nd₂, perm_dlookup a nd₁ nd₂ p]
[GOAL]
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
b : β a
l : List (Sigma β)
H : ∀ (b : β a), ¬{ fst := a, snd := b } ∈ l
⊢ ∀ (a_1 : Sigma β), a_1 ∈ l → (if a = a_1.fst then some { fst := a, snd := b } else none) = none
[PROOFSTEP]
rintro ⟨a', b'⟩ h
[GOAL]
case mk
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
b : β a
l : List (Sigma β)
H : ∀ (b : β a), ¬{ fst := a, snd := b } ∈ l
a' : α
b' : β a'
h : { fst := a', snd := b' } ∈ l
⊢ (if a = { fst := a', snd := b' }.fst then some { fst := a, snd := b } else none) = none
[PROOFSTEP]
dsimp
[GOAL]
case mk
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
b : β a
l : List (Sigma β)
H : ∀ (b : β a), ¬{ fst := a, snd := b } ∈ l
a' : α
b' : β a'
h : { fst := a', snd := b' } ∈ l
⊢ (if a = a' then some { fst := a, snd := b } else none) = none
[PROOFSTEP]
split_ifs
[GOAL]
case pos
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
b : β a
l : List (Sigma β)
H : ∀ (b : β a), ¬{ fst := a, snd := b } ∈ l
a' : α
b' : β a'
h : { fst := a', snd := b' } ∈ l
h✝ : a = a'
⊢ False
[PROOFSTEP]
subst a'
[GOAL]
case pos
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
b : β a
l : List (Sigma β)
H : ∀ (b : β a), ¬{ fst := a, snd := b } ∈ l
b' : β a
h : { fst := a, snd := b' } ∈ l
⊢ False
[PROOFSTEP]
exact H _ h
[GOAL]
case neg
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
b : β a
l : List (Sigma β)
H : ∀ (b : β a), ¬{ fst := a, snd := b } ∈ l
a' : α
b' : β a'
h : { fst := a', snd := b' } ∈ l
h✝ : ¬a = a'
⊢ none = none
[PROOFSTEP]
rfl
[GOAL]
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
b : β a
l : List (Sigma β)
nd : NodupKeys l
h : { fst := a, snd := b } ∈ l
⊢ kreplace a b l = l
[PROOFSTEP]
refine' (lookmap_congr _).trans (lookmap_id' (Option.guard fun (s : Sigma β) => a = s.1) _ _)
[GOAL]
case refine'_1
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
b : β a
l : List (Sigma β)
nd : NodupKeys l
h : { fst := a, snd := b } ∈ l
⊢ ∀ (a_1 : Sigma β),
    a_1 ∈ l → (if a = a_1.fst then some { fst := a, snd := b } else none) = Option.guard (fun s => a = s.fst) a_1
[PROOFSTEP]
rintro ⟨a', b'⟩ h'
[GOAL]
case refine'_1.mk
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
b : β a
l : List (Sigma β)
nd : NodupKeys l
h : { fst := a, snd := b } ∈ l
a' : α
b' : β a'
h' : { fst := a', snd := b' } ∈ l
⊢ (if a = { fst := a', snd := b' }.fst then some { fst := a, snd := b } else none) =
    Option.guard (fun s => a = s.fst) { fst := a', snd := b' }
[PROOFSTEP]
dsimp [Option.guard]
[GOAL]
case refine'_1.mk
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
b : β a
l : List (Sigma β)
nd : NodupKeys l
h : { fst := a, snd := b } ∈ l
a' : α
b' : β a'
h' : { fst := a', snd := b' } ∈ l
⊢ (if a = a' then some { fst := a, snd := b } else none) = if a = a' then some { fst := a', snd := b' } else none
[PROOFSTEP]
split_ifs
[GOAL]
case pos
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
b : β a
l : List (Sigma β)
nd : NodupKeys l
h : { fst := a, snd := b } ∈ l
a' : α
b' : β a'
h' : { fst := a', snd := b' } ∈ l
h✝ : a = a'
⊢ some { fst := a, snd := b } = some { fst := a', snd := b' }
[PROOFSTEP]
subst a'
[GOAL]
case pos
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
b : β a
l : List (Sigma β)
nd : NodupKeys l
h : { fst := a, snd := b } ∈ l
b' : β a
h' : { fst := a, snd := b' } ∈ l
⊢ some { fst := a, snd := b } = some { fst := a, snd := b' }
[PROOFSTEP]
simp [nd.eq_of_mk_mem h h']
[GOAL]
case neg
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
b : β a
l : List (Sigma β)
nd : NodupKeys l
h : { fst := a, snd := b } ∈ l
a' : α
b' : β a'
h' : { fst := a', snd := b' } ∈ l
h✝ : ¬a = a'
⊢ none = none
[PROOFSTEP]
rfl
[GOAL]
case refine'_2
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
b : β a
l : List (Sigma β)
nd : NodupKeys l
h : { fst := a, snd := b } ∈ l
⊢ ∀ (a_1 b : Sigma β), b ∈ Option.guard (fun s => a = s.fst) a_1 → a_1 = b
[PROOFSTEP]
rintro ⟨a₁, b₁⟩ ⟨a₂, b₂⟩
[GOAL]
case refine'_2.mk.mk
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
b : β a
l : List (Sigma β)
nd : NodupKeys l
h : { fst := a, snd := b } ∈ l
a₁ : α
b₁ : β a₁
a₂ : α
b₂ : β a₂
⊢ { fst := a₂, snd := b₂ } ∈ Option.guard (fun s => a = s.fst) { fst := a₁, snd := b₁ } →
    { fst := a₁, snd := b₁ } = { fst := a₂, snd := b₂ }
[PROOFSTEP]
dsimp [Option.guard]
[GOAL]
case refine'_2.mk.mk
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
b : β a
l : List (Sigma β)
nd : NodupKeys l
h : { fst := a, snd := b } ∈ l
a₁ : α
b₁ : β a₁
a₂ : α
b₂ : β a₂
⊢ ({ fst := a₂, snd := b₂ } ∈ if a = a₁ then some { fst := a₁, snd := b₁ } else none) →
    { fst := a₁, snd := b₁ } = { fst := a₂, snd := b₂ }
[PROOFSTEP]
split_ifs
[GOAL]
case pos
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
b : β a
l : List (Sigma β)
nd : NodupKeys l
h : { fst := a, snd := b } ∈ l
a₁ : α
b₁ : β a₁
a₂ : α
b₂ : β a₂
h✝ : a = a₁
⊢ { fst := a₂, snd := b₂ } ∈ some { fst := a₁, snd := b₁ } → { fst := a₁, snd := b₁ } = { fst := a₂, snd := b₂ }
[PROOFSTEP]
simp
[GOAL]
case neg
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
b : β a
l : List (Sigma β)
nd : NodupKeys l
h : { fst := a, snd := b } ∈ l
a₁ : α
b₁ : β a₁
a₂ : α
b₂ : β a₂
h✝ : ¬a = a₁
⊢ { fst := a₂, snd := b₂ } ∈ none → { fst := a₁, snd := b₁ } = { fst := a₂, snd := b₂ }
[PROOFSTEP]
rintro ⟨⟩
[GOAL]
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
b : β a
⊢ ∀ (a_1 b_1 : Sigma β), (b_1 ∈ if a = a_1.fst then some { fst := a, snd := b } else none) → a_1.fst = b_1.fst
[PROOFSTEP]
rintro ⟨a₁, b₂⟩ ⟨a₂, b₂⟩
[GOAL]
case mk.mk
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
b : β a
a₁ : α
b₂✝ : β a₁
a₂ : α
b₂ : β a₂
⊢ ({ fst := a₂, snd := b₂ } ∈ if a = { fst := a₁, snd := b₂✝ }.fst then some { fst := a, snd := b } else none) →
    { fst := a₁, snd := b₂✝ }.fst = { fst := a₂, snd := b₂ }.fst
[PROOFSTEP]
dsimp
[GOAL]
case mk.mk
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
b : β a
a₁ : α
b₂✝ : β a₁
a₂ : α
b₂ : β a₂
⊢ ({ fst := a₂, snd := b₂ } ∈ if a = a₁ then some { fst := a, snd := b } else none) → a₁ = a₂
[PROOFSTEP]
split_ifs with h
[GOAL]
case pos
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
b : β a
a₁ : α
b₂✝ : β a₁
a₂ : α
b₂ : β a₂
h : a = a₁
⊢ { fst := a₂, snd := b₂ } ∈ some { fst := a, snd := b } → a₁ = a₂
[PROOFSTEP]
simp (config := { contextual := true }) [h]
[GOAL]
case neg
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
b : β a
a₁ : α
b₂✝ : β a₁
a₂ : α
b₂ : β a₂
h : ¬a = a₁
⊢ { fst := a₂, snd := b₂ } ∈ none → a₁ = a₂
[PROOFSTEP]
simp (config := { contextual := true }) [h]
[GOAL]
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
b : β a
l : List (Sigma β)
⊢ NodupKeys (kreplace a b l) ↔ NodupKeys l
[PROOFSTEP]
simp [NodupKeys, keys_kreplace]
[GOAL]
α : Type u
β : α → Type v
l l₁✝ l₂✝ : List (Sigma β)
inst✝ : DecidableEq α
a : α
b : β a
l₁ l₂ : List (Sigma β)
nd : NodupKeys l₁
⊢ Pairwise
    (fun a_1 b_1 =>
      ∀ (c : Sigma β),
        (c ∈ if a = a_1.fst then some { fst := a, snd := b } else none) →
          ∀ (d : Sigma β), (d ∈ if a = b_1.fst then some { fst := a, snd := b } else none) → a_1 = b_1 ∧ c = d)
    l₁
[PROOFSTEP]
refine' nd.pairwise_ne.imp _
[GOAL]
α : Type u
β : α → Type v
l l₁✝ l₂✝ : List (Sigma β)
inst✝ : DecidableEq α
a : α
b : β a
l₁ l₂ : List (Sigma β)
nd : NodupKeys l₁
⊢ ∀ {a_1 b_1 : Sigma β},
    a_1.fst ≠ b_1.fst →
      ∀ (c : Sigma β),
        (c ∈ if a = a_1.fst then some { fst := a, snd := b } else none) →
          ∀ (d : Sigma β), (d ∈ if a = b_1.fst then some { fst := a, snd := b } else none) → a_1 = b_1 ∧ c = d
[PROOFSTEP]
intro x y h z h₁ w h₂
[GOAL]
α : Type u
β : α → Type v
l l₁✝ l₂✝ : List (Sigma β)
inst✝ : DecidableEq α
a : α
b : β a
l₁ l₂ : List (Sigma β)
nd : NodupKeys l₁
x y : Sigma β
h : x.fst ≠ y.fst
z : Sigma β
h₁ : z ∈ if a = x.fst then some { fst := a, snd := b } else none
w : Sigma β
h₂ : w ∈ if a = y.fst then some { fst := a, snd := b } else none
⊢ x = y ∧ z = w
[PROOFSTEP]
split_ifs at h₁ h₂  with h_2 h_1
[GOAL]
case pos
α : Type u
β : α → Type v
l l₁✝ l₂✝ : List (Sigma β)
inst✝ : DecidableEq α
a : α
b : β a
l₁ l₂ : List (Sigma β)
nd : NodupKeys l₁
x y : Sigma β
h : x.fst ≠ y.fst
z w : Sigma β
h_2 : a = x.fst
h₁ : z ∈ some { fst := a, snd := b }
h_1 : a = y.fst
h₂ : w ∈ some { fst := a, snd := b }
⊢ x = y ∧ z = w
[PROOFSTEP]
cases h₁
[GOAL]
case neg
α : Type u
β : α → Type v
l l₁✝ l₂✝ : List (Sigma β)
inst✝ : DecidableEq α
a : α
b : β a
l₁ l₂ : List (Sigma β)
nd : NodupKeys l₁
x y : Sigma β
h : x.fst ≠ y.fst
z w : Sigma β
h_2 : a = x.fst
h₁ : z ∈ some { fst := a, snd := b }
h_1 : ¬a = y.fst
h₂ : w ∈ none
⊢ x = y ∧ z = w
[PROOFSTEP]
cases h₁
[GOAL]
case pos
α : Type u
β : α → Type v
l l₁✝ l₂✝ : List (Sigma β)
inst✝ : DecidableEq α
a : α
b : β a
l₁ l₂ : List (Sigma β)
nd : NodupKeys l₁
x y : Sigma β
h : x.fst ≠ y.fst
z w : Sigma β
h_2 : ¬a = x.fst
h₁ : z ∈ none
h✝ : a = y.fst
h₂ : w ∈ some { fst := a, snd := b }
⊢ x = y ∧ z = w
[PROOFSTEP]
cases h₁
[GOAL]
case neg
α : Type u
β : α → Type v
l l₁✝ l₂✝ : List (Sigma β)
inst✝ : DecidableEq α
a : α
b : β a
l₁ l₂ : List (Sigma β)
nd : NodupKeys l₁
x y : Sigma β
h : x.fst ≠ y.fst
z w : Sigma β
h_2 : ¬a = x.fst
h₁ : z ∈ none
h✝ : ¬a = y.fst
h₂ : w ∈ none
⊢ x = y ∧ z = w
[PROOFSTEP]
cases h₁
[GOAL]
case pos.refl
α : Type u
β : α → Type v
l l₁✝ l₂✝ : List (Sigma β)
inst✝ : DecidableEq α
a : α
b : β a
l₁ l₂ : List (Sigma β)
nd : NodupKeys l₁
x y : Sigma β
h : x.fst ≠ y.fst
w : Sigma β
h_2 : a = x.fst
h_1 : a = y.fst
h₂ : w ∈ some { fst := a, snd := b }
⊢ x = y ∧ { fst := a, snd := b } = w
[PROOFSTEP]
cases h₂
[GOAL]
case neg.refl
α : Type u
β : α → Type v
l l₁✝ l₂✝ : List (Sigma β)
inst✝ : DecidableEq α
a : α
b : β a
l₁ l₂ : List (Sigma β)
nd : NodupKeys l₁
x y : Sigma β
h : x.fst ≠ y.fst
w : Sigma β
h_2 : a = x.fst
h_1 : ¬a = y.fst
h₂ : w ∈ none
⊢ x = y ∧ { fst := a, snd := b } = w
[PROOFSTEP]
cases h₂
[GOAL]
case pos.refl.refl
α : Type u
β : α → Type v
l l₁✝ l₂✝ : List (Sigma β)
inst✝ : DecidableEq α
a : α
b : β a
l₁ l₂ : List (Sigma β)
nd : NodupKeys l₁
x y : Sigma β
h : x.fst ≠ y.fst
h_2 : a = x.fst
h_1 : a = y.fst
⊢ x = y ∧ { fst := a, snd := b } = { fst := a, snd := b }
[PROOFSTEP]
exact (h (h_2.symm.trans h_1)).elim
[GOAL]
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
s : Sigma β
l : List (Sigma β)
h : a = s.fst
⊢ kerase a (s :: l) = l
[PROOFSTEP]
simp [kerase, h]
[GOAL]
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
s : Sigma β
l : List (Sigma β)
h : a ≠ s.fst
⊢ kerase a (s :: l) = s :: kerase a l
[PROOFSTEP]
simp [kerase, h]
[GOAL]
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l : List (Sigma β)
h : ¬a ∈ keys l
⊢ kerase a l = l
[PROOFSTEP]
induction' l with _ _ ih <;> [rfl; (simp [not_or] at h ; simp [h.1, ih h.2])]
[GOAL]
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l : List (Sigma β)
h : ¬a ∈ keys l
⊢ kerase a l = l
[PROOFSTEP]
induction' l with _ _ ih
[GOAL]
case nil
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l : List (Sigma β)
h✝ : ¬a ∈ keys l
h : ¬a ∈ keys []
⊢ kerase a [] = []
[PROOFSTEP]
rfl
[GOAL]
case cons
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l : List (Sigma β)
h✝ : ¬a ∈ keys l
head✝ : Sigma β
tail✝ : List (Sigma β)
ih : ¬a ∈ keys tail✝ → kerase a tail✝ = tail✝
h : ¬a ∈ keys (head✝ :: tail✝)
⊢ kerase a (head✝ :: tail✝) = head✝ :: tail✝
[PROOFSTEP]
simp [not_or] at h 
[GOAL]
case cons
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l : List (Sigma β)
h✝ : ¬a ∈ keys l
head✝ : Sigma β
tail✝ : List (Sigma β)
ih : ¬a ∈ keys tail✝ → kerase a tail✝ = tail✝
h : ¬a = head✝.fst ∧ ¬a ∈ keys tail✝
⊢ kerase a (head✝ :: tail✝) = head✝ :: tail✝
[PROOFSTEP]
simp [h.1, ih h.2]
[GOAL]
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l : List (Sigma β)
h : a ∈ keys l
⊢ ∃ b l₁ l₂, ¬a ∈ keys l₁ ∧ l = l₁ ++ { fst := a, snd := b } :: l₂ ∧ kerase a l = l₁ ++ l₂
[PROOFSTEP]
induction l with
| nil => cases h
| cons hd tl ih =>
  by_cases e : a = hd.1
  · subst e
    exact ⟨hd.2, [], tl, by simp, by cases hd; rfl, by simp⟩
  · simp at h 
    cases' h with h h
    exact absurd h e
    rcases ih h with ⟨b, tl₁, tl₂, h₁, h₂, h₃⟩
    exact ⟨b, hd :: tl₁, tl₂, not_mem_cons_of_ne_of_not_mem e h₁, by (rw [h₂]; rfl), by simp [e, h₃]⟩
[GOAL]
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l : List (Sigma β)
h : a ∈ keys l
⊢ ∃ b l₁ l₂, ¬a ∈ keys l₁ ∧ l = l₁ ++ { fst := a, snd := b } :: l₂ ∧ kerase a l = l₁ ++ l₂
[PROOFSTEP]
induction l with
| nil => cases h
| cons hd tl ih =>
  by_cases e : a = hd.1
  · subst e
    exact ⟨hd.2, [], tl, by simp, by cases hd; rfl, by simp⟩
  · simp at h 
    cases' h with h h
    exact absurd h e
    rcases ih h with ⟨b, tl₁, tl₂, h₁, h₂, h₃⟩
    exact ⟨b, hd :: tl₁, tl₂, not_mem_cons_of_ne_of_not_mem e h₁, by (rw [h₂]; rfl), by simp [e, h₃]⟩
[GOAL]
case nil
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
h : a ∈ keys []
⊢ ∃ b l₁ l₂, ¬a ∈ keys l₁ ∧ [] = l₁ ++ { fst := a, snd := b } :: l₂ ∧ kerase a [] = l₁ ++ l₂
[PROOFSTEP]

| nil => cases h
[GOAL]
case nil
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
h : a ∈ keys []
⊢ ∃ b l₁ l₂, ¬a ∈ keys l₁ ∧ [] = l₁ ++ { fst := a, snd := b } :: l₂ ∧ kerase a [] = l₁ ++ l₂
[PROOFSTEP]
cases h
[GOAL]
case cons
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
hd : Sigma β
tl : List (Sigma β)
ih : a ∈ keys tl → ∃ b l₁ l₂, ¬a ∈ keys l₁ ∧ tl = l₁ ++ { fst := a, snd := b } :: l₂ ∧ kerase a tl = l₁ ++ l₂
h : a ∈ keys (hd :: tl)
⊢ ∃ b l₁ l₂, ¬a ∈ keys l₁ ∧ hd :: tl = l₁ ++ { fst := a, snd := b } :: l₂ ∧ kerase a (hd :: tl) = l₁ ++ l₂
[PROOFSTEP]

| cons hd tl ih =>
  by_cases e : a = hd.1
  · subst e
    exact ⟨hd.2, [], tl, by simp, by cases hd; rfl, by simp⟩
  · simp at h 
    cases' h with h h
    exact absurd h e
    rcases ih h with ⟨b, tl₁, tl₂, h₁, h₂, h₃⟩
    exact ⟨b, hd :: tl₁, tl₂, not_mem_cons_of_ne_of_not_mem e h₁, by (rw [h₂]; rfl), by simp [e, h₃]⟩
[GOAL]
case cons
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
hd : Sigma β
tl : List (Sigma β)
ih : a ∈ keys tl → ∃ b l₁ l₂, ¬a ∈ keys l₁ ∧ tl = l₁ ++ { fst := a, snd := b } :: l₂ ∧ kerase a tl = l₁ ++ l₂
h : a ∈ keys (hd :: tl)
⊢ ∃ b l₁ l₂, ¬a ∈ keys l₁ ∧ hd :: tl = l₁ ++ { fst := a, snd := b } :: l₂ ∧ kerase a (hd :: tl) = l₁ ++ l₂
[PROOFSTEP]
by_cases e : a = hd.1
[GOAL]
case pos
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
hd : Sigma β
tl : List (Sigma β)
ih : a ∈ keys tl → ∃ b l₁ l₂, ¬a ∈ keys l₁ ∧ tl = l₁ ++ { fst := a, snd := b } :: l₂ ∧ kerase a tl = l₁ ++ l₂
h : a ∈ keys (hd :: tl)
e : a = hd.fst
⊢ ∃ b l₁ l₂, ¬a ∈ keys l₁ ∧ hd :: tl = l₁ ++ { fst := a, snd := b } :: l₂ ∧ kerase a (hd :: tl) = l₁ ++ l₂
[PROOFSTEP]
subst e
[GOAL]
case pos
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
hd : Sigma β
tl : List (Sigma β)
ih :
  hd.fst ∈ keys tl →
    ∃ b l₁ l₂, ¬hd.fst ∈ keys l₁ ∧ tl = l₁ ++ { fst := hd.fst, snd := b } :: l₂ ∧ kerase hd.fst tl = l₁ ++ l₂
h : hd.fst ∈ keys (hd :: tl)
⊢ ∃ b l₁ l₂,
    ¬hd.fst ∈ keys l₁ ∧ hd :: tl = l₁ ++ { fst := hd.fst, snd := b } :: l₂ ∧ kerase hd.fst (hd :: tl) = l₁ ++ l₂
[PROOFSTEP]
exact ⟨hd.2, [], tl, by simp, by cases hd; rfl, by simp⟩
[GOAL]
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
hd : Sigma β
tl : List (Sigma β)
ih :
  hd.fst ∈ keys tl →
    ∃ b l₁ l₂, ¬hd.fst ∈ keys l₁ ∧ tl = l₁ ++ { fst := hd.fst, snd := b } :: l₂ ∧ kerase hd.fst tl = l₁ ++ l₂
h : hd.fst ∈ keys (hd :: tl)
⊢ ¬hd.fst ∈ keys []
[PROOFSTEP]
simp
[GOAL]
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
hd : Sigma β
tl : List (Sigma β)
ih :
  hd.fst ∈ keys tl →
    ∃ b l₁ l₂, ¬hd.fst ∈ keys l₁ ∧ tl = l₁ ++ { fst := hd.fst, snd := b } :: l₂ ∧ kerase hd.fst tl = l₁ ++ l₂
h : hd.fst ∈ keys (hd :: tl)
⊢ hd :: tl = [] ++ { fst := hd.fst, snd := hd.snd } :: tl
[PROOFSTEP]
cases hd
[GOAL]
case mk
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
tl : List (Sigma β)
fst✝ : α
snd✝ : β fst✝
ih :
  { fst := fst✝, snd := snd✝ }.fst ∈ keys tl →
    ∃ b l₁ l₂,
      ¬{ fst := fst✝, snd := snd✝ }.fst ∈ keys l₁ ∧
        tl = l₁ ++ { fst := { fst := fst✝, snd := snd✝ }.fst, snd := b } :: l₂ ∧
          kerase { fst := fst✝, snd := snd✝ }.fst tl = l₁ ++ l₂
h : { fst := fst✝, snd := snd✝ }.fst ∈ keys ({ fst := fst✝, snd := snd✝ } :: tl)
⊢ { fst := fst✝, snd := snd✝ } :: tl =
    [] ++ { fst := { fst := fst✝, snd := snd✝ }.fst, snd := { fst := fst✝, snd := snd✝ }.snd } :: tl
[PROOFSTEP]
rfl
[GOAL]
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
hd : Sigma β
tl : List (Sigma β)
ih :
  hd.fst ∈ keys tl →
    ∃ b l₁ l₂, ¬hd.fst ∈ keys l₁ ∧ tl = l₁ ++ { fst := hd.fst, snd := b } :: l₂ ∧ kerase hd.fst tl = l₁ ++ l₂
h : hd.fst ∈ keys (hd :: tl)
⊢ kerase hd.fst (hd :: tl) = [] ++ tl
[PROOFSTEP]
simp
[GOAL]
case neg
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
hd : Sigma β
tl : List (Sigma β)
ih : a ∈ keys tl → ∃ b l₁ l₂, ¬a ∈ keys l₁ ∧ tl = l₁ ++ { fst := a, snd := b } :: l₂ ∧ kerase a tl = l₁ ++ l₂
h : a ∈ keys (hd :: tl)
e : ¬a = hd.fst
⊢ ∃ b l₁ l₂, ¬a ∈ keys l₁ ∧ hd :: tl = l₁ ++ { fst := a, snd := b } :: l₂ ∧ kerase a (hd :: tl) = l₁ ++ l₂
[PROOFSTEP]
simp at h 
[GOAL]
case neg
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
hd : Sigma β
tl : List (Sigma β)
ih : a ∈ keys tl → ∃ b l₁ l₂, ¬a ∈ keys l₁ ∧ tl = l₁ ++ { fst := a, snd := b } :: l₂ ∧ kerase a tl = l₁ ++ l₂
e : ¬a = hd.fst
h : a = hd.fst ∨ a ∈ keys tl
⊢ ∃ b l₁ l₂, ¬a ∈ keys l₁ ∧ hd :: tl = l₁ ++ { fst := a, snd := b } :: l₂ ∧ kerase a (hd :: tl) = l₁ ++ l₂
[PROOFSTEP]
cases' h with h h
[GOAL]
case neg.inl
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
hd : Sigma β
tl : List (Sigma β)
ih : a ∈ keys tl → ∃ b l₁ l₂, ¬a ∈ keys l₁ ∧ tl = l₁ ++ { fst := a, snd := b } :: l₂ ∧ kerase a tl = l₁ ++ l₂
e : ¬a = hd.fst
h : a = hd.fst
⊢ ∃ b l₁ l₂, ¬a ∈ keys l₁ ∧ hd :: tl = l₁ ++ { fst := a, snd := b } :: l₂ ∧ kerase a (hd :: tl) = l₁ ++ l₂
case neg.inr
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
hd : Sigma β
tl : List (Sigma β)
ih : a ∈ keys tl → ∃ b l₁ l₂, ¬a ∈ keys l₁ ∧ tl = l₁ ++ { fst := a, snd := b } :: l₂ ∧ kerase a tl = l₁ ++ l₂
e : ¬a = hd.fst
h : a ∈ keys tl
⊢ ∃ b l₁ l₂, ¬a ∈ keys l₁ ∧ hd :: tl = l₁ ++ { fst := a, snd := b } :: l₂ ∧ kerase a (hd :: tl) = l₁ ++ l₂
[PROOFSTEP]
exact absurd h e
[GOAL]
case neg.inr
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
hd : Sigma β
tl : List (Sigma β)
ih : a ∈ keys tl → ∃ b l₁ l₂, ¬a ∈ keys l₁ ∧ tl = l₁ ++ { fst := a, snd := b } :: l₂ ∧ kerase a tl = l₁ ++ l₂
e : ¬a = hd.fst
h : a ∈ keys tl
⊢ ∃ b l₁ l₂, ¬a ∈ keys l₁ ∧ hd :: tl = l₁ ++ { fst := a, snd := b } :: l₂ ∧ kerase a (hd :: tl) = l₁ ++ l₂
[PROOFSTEP]
rcases ih h with ⟨b, tl₁, tl₂, h₁, h₂, h₃⟩
[GOAL]
case neg.inr.intro.intro.intro.intro.intro
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
hd : Sigma β
tl : List (Sigma β)
ih : a ∈ keys tl → ∃ b l₁ l₂, ¬a ∈ keys l₁ ∧ tl = l₁ ++ { fst := a, snd := b } :: l₂ ∧ kerase a tl = l₁ ++ l₂
e : ¬a = hd.fst
h : a ∈ keys tl
b : β a
tl₁ tl₂ : List (Sigma β)
h₁ : ¬a ∈ keys tl₁
h₂ : tl = tl₁ ++ { fst := a, snd := b } :: tl₂
h₃ : kerase a tl = tl₁ ++ tl₂
⊢ ∃ b l₁ l₂, ¬a ∈ keys l₁ ∧ hd :: tl = l₁ ++ { fst := a, snd := b } :: l₂ ∧ kerase a (hd :: tl) = l₁ ++ l₂
[PROOFSTEP]
exact ⟨b, hd :: tl₁, tl₂, not_mem_cons_of_ne_of_not_mem e h₁, by (rw [h₂]; rfl), by simp [e, h₃]⟩
[GOAL]
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
hd : Sigma β
tl : List (Sigma β)
ih : a ∈ keys tl → ∃ b l₁ l₂, ¬a ∈ keys l₁ ∧ tl = l₁ ++ { fst := a, snd := b } :: l₂ ∧ kerase a tl = l₁ ++ l₂
e : ¬a = hd.fst
h : a ∈ keys tl
b : β a
tl₁ tl₂ : List (Sigma β)
h₁ : ¬a ∈ keys tl₁
h₂ : tl = tl₁ ++ { fst := a, snd := b } :: tl₂
h₃ : kerase a tl = tl₁ ++ tl₂
⊢ hd :: tl = hd :: tl₁ ++ { fst := a, snd := b } :: tl₂
[PROOFSTEP]
rw [h₂]
[GOAL]
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
hd : Sigma β
tl : List (Sigma β)
ih : a ∈ keys tl → ∃ b l₁ l₂, ¬a ∈ keys l₁ ∧ tl = l₁ ++ { fst := a, snd := b } :: l₂ ∧ kerase a tl = l₁ ++ l₂
e : ¬a = hd.fst
h : a ∈ keys tl
b : β a
tl₁ tl₂ : List (Sigma β)
h₁ : ¬a ∈ keys tl₁
h₂ : tl = tl₁ ++ { fst := a, snd := b } :: tl₂
h₃ : kerase a tl = tl₁ ++ tl₂
⊢ hd :: (tl₁ ++ { fst := a, snd := b } :: tl₂) = hd :: tl₁ ++ { fst := a, snd := b } :: tl₂
[PROOFSTEP]
rfl
[GOAL]
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
hd : Sigma β
tl : List (Sigma β)
ih : a ∈ keys tl → ∃ b l₁ l₂, ¬a ∈ keys l₁ ∧ tl = l₁ ++ { fst := a, snd := b } :: l₂ ∧ kerase a tl = l₁ ++ l₂
e : ¬a = hd.fst
h : a ∈ keys tl
b : β a
tl₁ tl₂ : List (Sigma β)
h₁ : ¬a ∈ keys tl₁
h₂ : tl = tl₁ ++ { fst := a, snd := b } :: tl₂
h₃ : kerase a tl = tl₁ ++ tl₂
⊢ kerase a (hd :: tl) = hd :: tl₁ ++ tl₂
[PROOFSTEP]
simp [e, h₃]
[GOAL]
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a₁ a₂ : α
l : List (Sigma β)
h : a₁ ≠ a₂
p✝ : a₁ ∈ keys l
w✝² : β a₂
w✝¹ w✝ : List (Sigma β)
left✝ : ¬a₂ ∈ keys w✝¹
p : a₁ ∈ keys (w✝¹ ++ { fst := a₂, snd := w✝² } :: w✝)
q : a₂ ∈ keys (w✝¹ ++ { fst := a₂, snd := w✝² } :: w✝)
⊢ a₁ ∈ keys (w✝¹ ++ w✝)
[PROOFSTEP]
simpa [keys, h] using p
[GOAL]
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a₁ a₂ : α
l : List (Sigma β)
h : a₁ ≠ a₂
p : a₁ ∈ keys l
q : ¬a₂ ∈ keys l
⊢ a₁ ∈ keys (kerase a₂ l)
[PROOFSTEP]
simp [q, p]
[GOAL]
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l : List (Sigma β)
⊢ keys (kerase a l) = List.erase (keys l) a
[PROOFSTEP]
rw [keys, kerase, erase_eq_eraseP, eraseP_map]
[GOAL]
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l : List (Sigma β)
⊢ map Sigma.fst (eraseP (fun s => decide (a = s.fst)) l) =
    map Sigma.fst (eraseP ((fun b => decide (a = b)) ∘ Sigma.fst) l)
[PROOFSTEP]
dsimp [Function.comp]
[GOAL]
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a a' : α
l : List (Sigma β)
⊢ kerase a (kerase a' l) = kerase a' (kerase a l)
[PROOFSTEP]
by_cases h : a = a'
[GOAL]
case pos
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a a' : α
l : List (Sigma β)
h : a = a'
⊢ kerase a (kerase a' l) = kerase a' (kerase a l)
[PROOFSTEP]
subst a'
[GOAL]
case pos
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l : List (Sigma β)
⊢ kerase a (kerase a l) = kerase a (kerase a l)
[PROOFSTEP]
rfl
[GOAL]
case neg
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a a' : α
l : List (Sigma β)
h : ¬a = a'
⊢ kerase a (kerase a' l) = kerase a' (kerase a l)
[PROOFSTEP]
induction' l with x xs
[GOAL]
case neg.nil
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a a' : α
h : ¬a = a'
⊢ kerase a (kerase a' []) = kerase a' (kerase a [])
[PROOFSTEP]
rfl
[GOAL]
case neg.cons
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a a' : α
h : ¬a = a'
x : Sigma β
xs : List (Sigma β)
tail_ih✝ : kerase a (kerase a' xs) = kerase a' (kerase a xs)
⊢ kerase a (kerase a' (x :: xs)) = kerase a' (kerase a (x :: xs))
[PROOFSTEP]
by_cases a' = x.1
[GOAL]
case neg.cons
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a a' : α
h : ¬a = a'
x : Sigma β
xs : List (Sigma β)
tail_ih✝ : kerase a (kerase a' xs) = kerase a' (kerase a xs)
⊢ kerase a (kerase a' (x :: xs)) = kerase a' (kerase a (x :: xs))
[PROOFSTEP]
by_cases a' = x.1
[GOAL]
case pos
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a a' : α
h✝ : ¬a = a'
x : Sigma β
xs : List (Sigma β)
tail_ih✝ : kerase a (kerase a' xs) = kerase a' (kerase a xs)
h : a' = x.fst
⊢ kerase a (kerase a' (x :: xs)) = kerase a' (kerase a (x :: xs))
[PROOFSTEP]
subst a'
[GOAL]
case pos
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
x : Sigma β
xs : List (Sigma β)
h : ¬a = x.fst
tail_ih✝ : kerase a (kerase x.fst xs) = kerase x.fst (kerase a xs)
⊢ kerase a (kerase x.fst (x :: xs)) = kerase x.fst (kerase a (x :: xs))
[PROOFSTEP]
simp [kerase_cons_ne h, kerase_cons_eq rfl]
[GOAL]
case neg
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a a' : α
h✝ : ¬a = a'
x : Sigma β
xs : List (Sigma β)
tail_ih✝ : kerase a (kerase a' xs) = kerase a' (kerase a xs)
h : ¬a' = x.fst
⊢ kerase a (kerase a' (x :: xs)) = kerase a' (kerase a (x :: xs))
[PROOFSTEP]
by_cases h' : a = x.1
[GOAL]
case pos
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a a' : α
h✝ : ¬a = a'
x : Sigma β
xs : List (Sigma β)
tail_ih✝ : kerase a (kerase a' xs) = kerase a' (kerase a xs)
h : ¬a' = x.fst
h' : a = x.fst
⊢ kerase a (kerase a' (x :: xs)) = kerase a' (kerase a (x :: xs))
[PROOFSTEP]
subst a
[GOAL]
case pos
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a' : α
x : Sigma β
xs : List (Sigma β)
h✝ : ¬a' = x.fst
h : ¬x.fst = a'
tail_ih✝ : kerase x.fst (kerase a' xs) = kerase a' (kerase x.fst xs)
⊢ kerase x.fst (kerase a' (x :: xs)) = kerase a' (kerase x.fst (x :: xs))
[PROOFSTEP]
simp [kerase_cons_eq rfl, kerase_cons_ne (Ne.symm h)]
[GOAL]
case neg
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a a' : α
h✝ : ¬a = a'
x : Sigma β
xs : List (Sigma β)
tail_ih✝ : kerase a (kerase a' xs) = kerase a' (kerase a xs)
h : ¬a' = x.fst
h' : ¬a = x.fst
⊢ kerase a (kerase a' (x :: xs)) = kerase a' (kerase a (x :: xs))
[PROOFSTEP]
simp [kerase_cons_ne, *]
[GOAL]
α : Type u
β : α → Type v
l l₁✝ l₂✝ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l₁ l₂ : List (Sigma β)
nd : NodupKeys l₁
⊢ ∀ {a_1 b : Sigma β}, a_1.fst ≠ b.fst → a = a_1.fst → a = b.fst → False
[PROOFSTEP]
rintro x y h rfl
[GOAL]
α : Type u
β : α → Type v
l l₁✝ l₂✝ : List (Sigma β)
inst✝ : DecidableEq α
l₁ l₂ : List (Sigma β)
nd : NodupKeys l₁
x y : Sigma β
h : x.fst ≠ y.fst
⊢ x.fst = y.fst → False
[PROOFSTEP]
exact h
[GOAL]
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l : List (Sigma β)
nd : NodupKeys l
⊢ ¬a ∈ keys (kerase a l)
[PROOFSTEP]
induction l with
| nil => simp
| cons hd tl ih =>
  simp at nd 
  by_cases h : a = hd.1
  · subst h
    simp [nd.1]
  · simp [h, ih nd.2]
[GOAL]
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l : List (Sigma β)
nd : NodupKeys l
⊢ ¬a ∈ keys (kerase a l)
[PROOFSTEP]
induction l with
| nil => simp
| cons hd tl ih =>
  simp at nd 
  by_cases h : a = hd.1
  · subst h
    simp [nd.1]
  · simp [h, ih nd.2]
[GOAL]
case nil
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
nd : NodupKeys []
⊢ ¬a ∈ keys (kerase a [])
[PROOFSTEP]

| nil => simp
[GOAL]
case nil
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
nd : NodupKeys []
⊢ ¬a ∈ keys (kerase a [])
[PROOFSTEP]
simp
[GOAL]
case cons
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
hd : Sigma β
tl : List (Sigma β)
ih : NodupKeys tl → ¬a ∈ keys (kerase a tl)
nd : NodupKeys (hd :: tl)
⊢ ¬a ∈ keys (kerase a (hd :: tl))
[PROOFSTEP]

| cons hd tl ih =>
  simp at nd 
  by_cases h : a = hd.1
  · subst h
    simp [nd.1]
  · simp [h, ih nd.2]
[GOAL]
case cons
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
hd : Sigma β
tl : List (Sigma β)
ih : NodupKeys tl → ¬a ∈ keys (kerase a tl)
nd : NodupKeys (hd :: tl)
⊢ ¬a ∈ keys (kerase a (hd :: tl))
[PROOFSTEP]
simp at nd 
[GOAL]
case cons
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
hd : Sigma β
tl : List (Sigma β)
ih : NodupKeys tl → ¬a ∈ keys (kerase a tl)
nd : ¬hd.fst ∈ keys tl ∧ NodupKeys tl
⊢ ¬a ∈ keys (kerase a (hd :: tl))
[PROOFSTEP]
by_cases h : a = hd.1
[GOAL]
case pos
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
hd : Sigma β
tl : List (Sigma β)
ih : NodupKeys tl → ¬a ∈ keys (kerase a tl)
nd : ¬hd.fst ∈ keys tl ∧ NodupKeys tl
h : a = hd.fst
⊢ ¬a ∈ keys (kerase a (hd :: tl))
[PROOFSTEP]
subst h
[GOAL]
case pos
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
hd : Sigma β
tl : List (Sigma β)
nd : ¬hd.fst ∈ keys tl ∧ NodupKeys tl
ih : NodupKeys tl → ¬hd.fst ∈ keys (kerase hd.fst tl)
⊢ ¬hd.fst ∈ keys (kerase hd.fst (hd :: tl))
[PROOFSTEP]
simp [nd.1]
[GOAL]
case neg
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
hd : Sigma β
tl : List (Sigma β)
ih : NodupKeys tl → ¬a ∈ keys (kerase a tl)
nd : ¬hd.fst ∈ keys tl ∧ NodupKeys tl
h : ¬a = hd.fst
⊢ ¬a ∈ keys (kerase a (hd :: tl))
[PROOFSTEP]
simp [h, ih nd.2]
[GOAL]
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a a' : α
l : List (Sigma β)
h : a ≠ a'
⊢ dlookup a (kerase a' l) = dlookup a l
[PROOFSTEP]
induction l with
| nil => rfl
| cons hd tl ih =>
  cases' hd with ah bh
  by_cases h₁ : a = ah <;> by_cases h₂ : a' = ah
  · substs h₁ h₂
    cases Ne.irrefl h
  · subst h₁
    simp [h₂]
  · subst h₂
    simp [h]
  · simp [h₁, h₂, ih]
[GOAL]
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a a' : α
l : List (Sigma β)
h : a ≠ a'
⊢ dlookup a (kerase a' l) = dlookup a l
[PROOFSTEP]
induction l with
| nil => rfl
| cons hd tl ih =>
  cases' hd with ah bh
  by_cases h₁ : a = ah <;> by_cases h₂ : a' = ah
  · substs h₁ h₂
    cases Ne.irrefl h
  · subst h₁
    simp [h₂]
  · subst h₂
    simp [h]
  · simp [h₁, h₂, ih]
[GOAL]
case nil
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a a' : α
h : a ≠ a'
⊢ dlookup a (kerase a' []) = dlookup a []
[PROOFSTEP]

| nil => rfl
[GOAL]
case nil
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a a' : α
h : a ≠ a'
⊢ dlookup a (kerase a' []) = dlookup a []
[PROOFSTEP]
rfl
[GOAL]
case cons
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a a' : α
h : a ≠ a'
hd : Sigma β
tl : List (Sigma β)
ih : dlookup a (kerase a' tl) = dlookup a tl
⊢ dlookup a (kerase a' (hd :: tl)) = dlookup a (hd :: tl)
[PROOFSTEP]

| cons hd tl ih =>
  cases' hd with ah bh
  by_cases h₁ : a = ah <;> by_cases h₂ : a' = ah
  · substs h₁ h₂
    cases Ne.irrefl h
  · subst h₁
    simp [h₂]
  · subst h₂
    simp [h]
  · simp [h₁, h₂, ih]
[GOAL]
case cons
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a a' : α
h : a ≠ a'
hd : Sigma β
tl : List (Sigma β)
ih : dlookup a (kerase a' tl) = dlookup a tl
⊢ dlookup a (kerase a' (hd :: tl)) = dlookup a (hd :: tl)
[PROOFSTEP]
cases' hd with ah bh
[GOAL]
case cons.mk
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a a' : α
h : a ≠ a'
tl : List (Sigma β)
ih : dlookup a (kerase a' tl) = dlookup a tl
ah : α
bh : β ah
⊢ dlookup a (kerase a' ({ fst := ah, snd := bh } :: tl)) = dlookup a ({ fst := ah, snd := bh } :: tl)
[PROOFSTEP]
by_cases h₁ : a = ah
[GOAL]
case pos
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a a' : α
h : a ≠ a'
tl : List (Sigma β)
ih : dlookup a (kerase a' tl) = dlookup a tl
ah : α
bh : β ah
h₁ : a = ah
⊢ dlookup a (kerase a' ({ fst := ah, snd := bh } :: tl)) = dlookup a ({ fst := ah, snd := bh } :: tl)
[PROOFSTEP]
by_cases h₂ : a' = ah
[GOAL]
case neg
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a a' : α
h : a ≠ a'
tl : List (Sigma β)
ih : dlookup a (kerase a' tl) = dlookup a tl
ah : α
bh : β ah
h₁ : ¬a = ah
⊢ dlookup a (kerase a' ({ fst := ah, snd := bh } :: tl)) = dlookup a ({ fst := ah, snd := bh } :: tl)
[PROOFSTEP]
by_cases h₂ : a' = ah
[GOAL]
case pos
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a a' : α
h : a ≠ a'
tl : List (Sigma β)
ih : dlookup a (kerase a' tl) = dlookup a tl
ah : α
bh : β ah
h₁ : a = ah
h₂ : a' = ah
⊢ dlookup a (kerase a' ({ fst := ah, snd := bh } :: tl)) = dlookup a ({ fst := ah, snd := bh } :: tl)
[PROOFSTEP]
substs h₁ h₂
[GOAL]
case pos
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a' : α
tl : List (Sigma β)
h : a' ≠ a'
ih : dlookup a' (kerase a' tl) = dlookup a' tl
bh : β a'
⊢ dlookup a' (kerase a' ({ fst := a', snd := bh } :: tl)) = dlookup a' ({ fst := a', snd := bh } :: tl)
[PROOFSTEP]
cases Ne.irrefl h
[GOAL]
case neg
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a a' : α
h : a ≠ a'
tl : List (Sigma β)
ih : dlookup a (kerase a' tl) = dlookup a tl
ah : α
bh : β ah
h₁ : a = ah
h₂ : ¬a' = ah
⊢ dlookup a (kerase a' ({ fst := ah, snd := bh } :: tl)) = dlookup a ({ fst := ah, snd := bh } :: tl)
[PROOFSTEP]
subst h₁
[GOAL]
case neg
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a a' : α
h : a ≠ a'
tl : List (Sigma β)
ih : dlookup a (kerase a' tl) = dlookup a tl
bh : β a
h₂ : ¬a' = a
⊢ dlookup a (kerase a' ({ fst := a, snd := bh } :: tl)) = dlookup a ({ fst := a, snd := bh } :: tl)
[PROOFSTEP]
simp [h₂]
[GOAL]
case pos
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a a' : α
h : a ≠ a'
tl : List (Sigma β)
ih : dlookup a (kerase a' tl) = dlookup a tl
ah : α
bh : β ah
h₁ : ¬a = ah
h₂ : a' = ah
⊢ dlookup a (kerase a' ({ fst := ah, snd := bh } :: tl)) = dlookup a ({ fst := ah, snd := bh } :: tl)
[PROOFSTEP]
subst h₂
[GOAL]
case pos
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a a' : α
h : a ≠ a'
tl : List (Sigma β)
ih : dlookup a (kerase a' tl) = dlookup a tl
bh : β a'
h₁ : ¬a = a'
⊢ dlookup a (kerase a' ({ fst := a', snd := bh } :: tl)) = dlookup a ({ fst := a', snd := bh } :: tl)
[PROOFSTEP]
simp [h]
[GOAL]
case neg
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a a' : α
h : a ≠ a'
tl : List (Sigma β)
ih : dlookup a (kerase a' tl) = dlookup a tl
ah : α
bh : β ah
h₁ : ¬a = ah
h₂ : ¬a' = ah
⊢ dlookup a (kerase a' ({ fst := ah, snd := bh } :: tl)) = dlookup a ({ fst := ah, snd := bh } :: tl)
[PROOFSTEP]
simp [h₁, h₂, ih]
[GOAL]
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
x✝ : List (Sigma β)
h : a ∈ keys []
⊢ kerase a ([] ++ x✝) = kerase a [] ++ x✝
[PROOFSTEP]
cases h
[GOAL]
α : Type u
β : α → Type v
l l₁✝ l₂✝ : List (Sigma β)
inst✝ : DecidableEq α
a : α
s : Sigma β
l₁ : List (Sigma β)
l₂ : List (Sigma β)
h₁ : a ∈ keys (s :: l₁)
⊢ kerase a (s :: l₁ ++ l₂) = kerase a (s :: l₁) ++ l₂
[PROOFSTEP]
if h₂ : a = s.1 then simp [h₂]
else simp at h₁ ; cases' h₁ with h₁ h₁ <;> [exact absurd h₁ h₂; simp [h₂, kerase_append_left h₁]]
[GOAL]
α : Type u
β : α → Type v
l l₁✝ l₂✝ : List (Sigma β)
inst✝ : DecidableEq α
a : α
s : Sigma β
l₁ : List (Sigma β)
l₂ : List (Sigma β)
h₁ : a ∈ keys (s :: l₁)
h₂ : a = s.fst
⊢ kerase a (s :: l₁ ++ l₂) = kerase a (s :: l₁) ++ l₂
[PROOFSTEP]
simp [h₂]
[GOAL]
α : Type u
β : α → Type v
l l₁✝ l₂✝ : List (Sigma β)
inst✝ : DecidableEq α
a : α
s : Sigma β
l₁ : List (Sigma β)
l₂ : List (Sigma β)
h₁ : a ∈ keys (s :: l₁)
h₂ : ¬a = s.fst
⊢ kerase a (s :: l₁ ++ l₂) = kerase a (s :: l₁) ++ l₂
[PROOFSTEP]
simp at h₁ 
[GOAL]
α : Type u
β : α → Type v
l l₁✝ l₂✝ : List (Sigma β)
inst✝ : DecidableEq α
a : α
s : Sigma β
l₁ : List (Sigma β)
l₂ : List (Sigma β)
h₂ : ¬a = s.fst
h₁ : a = s.fst ∨ a ∈ keys l₁
⊢ kerase a (s :: l₁ ++ l₂) = kerase a (s :: l₁) ++ l₂
[PROOFSTEP]
cases' h₁ with h₁ h₁ <;> [exact absurd h₁ h₂; simp [h₂, kerase_append_left h₁]]
[GOAL]
α : Type u
β : α → Type v
l l₁✝ l₂✝ : List (Sigma β)
inst✝ : DecidableEq α
a : α
s : Sigma β
l₁ : List (Sigma β)
l₂ : List (Sigma β)
h₂ : ¬a = s.fst
h₁ : a = s.fst ∨ a ∈ keys l₁
⊢ kerase a (s :: l₁ ++ l₂) = kerase a (s :: l₁) ++ l₂
[PROOFSTEP]
cases' h₁ with h₁ h₁
[GOAL]
case inl
α : Type u
β : α → Type v
l l₁✝ l₂✝ : List (Sigma β)
inst✝ : DecidableEq α
a : α
s : Sigma β
l₁ : List (Sigma β)
l₂ : List (Sigma β)
h₂ : ¬a = s.fst
h₁ : a = s.fst
⊢ kerase a (s :: l₁ ++ l₂) = kerase a (s :: l₁) ++ l₂
[PROOFSTEP]
exact absurd h₁ h₂
[GOAL]
case inr
α : Type u
β : α → Type v
l l₁✝ l₂✝ : List (Sigma β)
inst✝ : DecidableEq α
a : α
s : Sigma β
l₁ : List (Sigma β)
l₂ : List (Sigma β)
h₂ : ¬a = s.fst
h₁ : a ∈ keys l₁
⊢ kerase a (s :: l₁ ++ l₂) = kerase a (s :: l₁) ++ l₂
[PROOFSTEP]
simp [h₂, kerase_append_left h₁]
[GOAL]
α : Type u
β : α → Type v
l l₁✝ l₂✝ : List (Sigma β)
inst✝ : DecidableEq α
a : α
head✝ : Sigma β
l₁ : List (Sigma β)
l₂ : List (Sigma β)
h : ¬a ∈ keys (head✝ :: l₁)
⊢ kerase a (head✝ :: l₁ ++ l₂) = head✝ :: l₁ ++ kerase a l₂
[PROOFSTEP]
simp [not_or] at h 
[GOAL]
α : Type u
β : α → Type v
l l₁✝ l₂✝ : List (Sigma β)
inst✝ : DecidableEq α
a : α
head✝ : Sigma β
l₁ : List (Sigma β)
l₂ : List (Sigma β)
h : ¬a = head✝.fst ∧ ¬a ∈ keys l₁
⊢ kerase a (head✝ :: l₁ ++ l₂) = head✝ :: l₁ ++ kerase a l₂
[PROOFSTEP]
simp [h.1, kerase_append_right h.2]
[GOAL]
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a₁ a₂ : α
l : List (Sigma β)
h : a₁ = a₂
⊢ kerase a₂ (kerase a₁ l) = kerase a₁ (kerase a₂ l)
[PROOFSTEP]
simp [h]
[GOAL]
α : Type u
β : α → Type v
l✝ l₁✝ l₂✝ : List (Sigma β)
inst✝ : DecidableEq α
a₁ a₂ : α
l : List (Sigma β)
h : ¬a₁ = a₂
ha₂ : a₂ ∈ keys l
b₁ : β a₁
l₁ l₂ : List (Sigma β)
a₁_nin_l₁ : ¬a₁ ∈ keys l₁
x✝ : a₂ ∈ keys (l₁ ++ { fst := a₁, snd := b₁ } :: l₂)
ha₁ : a₁ ∈ keys (l₁ ++ { fst := a₁, snd := b₁ } :: l₂)
h' : a₂ ∈ keys l₁
⊢ kerase a₂ (l₁ ++ l₂) = kerase a₁ (kerase a₂ (l₁ ++ { fst := a₁, snd := b₁ } :: l₂))
[PROOFSTEP]
simp [kerase_append_left h', kerase_append_right (mt (mem_keys_kerase_of_ne h).mp a₁_nin_l₁)]
[GOAL]
α : Type u
β : α → Type v
l✝ l₁✝ l₂✝ : List (Sigma β)
inst✝ : DecidableEq α
a₁ a₂ : α
l : List (Sigma β)
h : ¬a₁ = a₂
ha₂ : a₂ ∈ keys l
b₁ : β a₁
l₁ l₂ : List (Sigma β)
a₁_nin_l₁ : ¬a₁ ∈ keys l₁
x✝ : a₂ ∈ keys (l₁ ++ { fst := a₁, snd := b₁ } :: l₂)
ha₁ : a₁ ∈ keys (l₁ ++ { fst := a₁, snd := b₁ } :: l₂)
h' : ¬a₂ ∈ keys l₁
⊢ kerase a₂ (l₁ ++ l₂) = kerase a₁ (kerase a₂ (l₁ ++ { fst := a₁, snd := b₁ } :: l₂))
[PROOFSTEP]
simp [kerase_append_right h', kerase_append_right a₁_nin_l₁, @kerase_cons_ne _ _ _ a₂ ⟨a₁, b₁⟩ _ (Ne.symm h)]
[GOAL]
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a₁ a₂ : α
l : List (Sigma β)
h : ¬a₁ = a₂
ha₁ : a₁ ∈ keys l
ha₂ : ¬a₂ ∈ keys l
⊢ kerase a₂ (kerase a₁ l) = kerase a₁ (kerase a₂ l)
[PROOFSTEP]
simp [ha₂, mt mem_keys_of_mem_keys_kerase ha₂]
[GOAL]
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a₁ a₂ : α
l : List (Sigma β)
h : ¬a₁ = a₂
ha₁ : ¬a₁ ∈ keys l
⊢ kerase a₂ (kerase a₁ l) = kerase a₁ (kerase a₂ l)
[PROOFSTEP]
simp [ha₁, mt mem_keys_of_mem_keys_kerase ha₁]
[GOAL]
α✝ : Type u
β✝ : α✝ → Type v
l l₁ l₂ : List (Sigma β✝)
inst✝² : DecidableEq α✝
α : Type u_2
β : α → Type u_1
inst✝¹ : DecidableEq α
inst✝ : SizeOf (Sigma β)
x : α
xs : List (Sigma β)
⊢ sizeOf (kerase x xs) ≤ sizeOf xs
[PROOFSTEP]
simp only [SizeOf.sizeOf, _sizeOf_1]
[GOAL]
α✝ : Type u
β✝ : α✝ → Type v
l l₁ l₂ : List (Sigma β✝)
inst✝² : DecidableEq α✝
α : Type u_2
β : α → Type u_1
inst✝¹ : DecidableEq α
inst✝ : SizeOf (Sigma β)
x : α
xs : List (Sigma β)
⊢ rec 1 (fun head tail tail_ih => 1 + sizeOf head + tail_ih) (kerase x xs) ≤
    rec 1 (fun head tail tail_ih => 1 + sizeOf head + tail_ih) xs
[PROOFSTEP]
induction' xs with y ys
[GOAL]
case nil
α✝ : Type u
β✝ : α✝ → Type v
l l₁ l₂ : List (Sigma β✝)
inst✝² : DecidableEq α✝
α : Type u_2
β : α → Type u_1
inst✝¹ : DecidableEq α
inst✝ : SizeOf (Sigma β)
x : α
⊢ rec 1 (fun head tail tail_ih => 1 + sizeOf head + tail_ih) (kerase x []) ≤
    rec 1 (fun head tail tail_ih => 1 + sizeOf head + tail_ih) []
[PROOFSTEP]
simp
[GOAL]
case cons
α✝ : Type u
β✝ : α✝ → Type v
l l₁ l₂ : List (Sigma β✝)
inst✝² : DecidableEq α✝
α : Type u_2
β : α → Type u_1
inst✝¹ : DecidableEq α
inst✝ : SizeOf (Sigma β)
x : α
y : Sigma β
ys : List (Sigma β)
tail_ih✝ :
  rec 1 (fun head tail tail_ih => 1 + sizeOf head + tail_ih) (kerase x ys) ≤
    rec 1 (fun head tail tail_ih => 1 + sizeOf head + tail_ih) ys
⊢ rec 1 (fun head tail tail_ih => 1 + sizeOf head + tail_ih) (kerase x (y :: ys)) ≤
    rec 1 (fun head tail tail_ih => 1 + sizeOf head + tail_ih) (y :: ys)
[PROOFSTEP]
by_cases x = y.1
[GOAL]
case cons
α✝ : Type u
β✝ : α✝ → Type v
l l₁ l₂ : List (Sigma β✝)
inst✝² : DecidableEq α✝
α : Type u_2
β : α → Type u_1
inst✝¹ : DecidableEq α
inst✝ : SizeOf (Sigma β)
x : α
y : Sigma β
ys : List (Sigma β)
tail_ih✝ :
  rec 1 (fun head tail tail_ih => 1 + sizeOf head + tail_ih) (kerase x ys) ≤
    rec 1 (fun head tail tail_ih => 1 + sizeOf head + tail_ih) ys
⊢ rec 1 (fun head tail tail_ih => 1 + sizeOf head + tail_ih) (kerase x (y :: ys)) ≤
    rec 1 (fun head tail tail_ih => 1 + sizeOf head + tail_ih) (y :: ys)
[PROOFSTEP]
by_cases x = y.1
[GOAL]
case pos
α✝ : Type u
β✝ : α✝ → Type v
l l₁ l₂ : List (Sigma β✝)
inst✝² : DecidableEq α✝
α : Type u_2
β : α → Type u_1
inst✝¹ : DecidableEq α
inst✝ : SizeOf (Sigma β)
x : α
y : Sigma β
ys : List (Sigma β)
tail_ih✝ :
  rec 1 (fun head tail tail_ih => 1 + sizeOf head + tail_ih) (kerase x ys) ≤
    rec 1 (fun head tail tail_ih => 1 + sizeOf head + tail_ih) ys
h : x = y.fst
⊢ rec 1 (fun head tail tail_ih => 1 + sizeOf head + tail_ih) (kerase x (y :: ys)) ≤
    rec 1 (fun head tail tail_ih => 1 + sizeOf head + tail_ih) (y :: ys)
[PROOFSTEP]
simp [*]
[GOAL]
case neg
α✝ : Type u
β✝ : α✝ → Type v
l l₁ l₂ : List (Sigma β✝)
inst✝² : DecidableEq α✝
α : Type u_2
β : α → Type u_1
inst✝¹ : DecidableEq α
inst✝ : SizeOf (Sigma β)
x : α
y : Sigma β
ys : List (Sigma β)
tail_ih✝ :
  rec 1 (fun head tail tail_ih => 1 + sizeOf head + tail_ih) (kerase x ys) ≤
    rec 1 (fun head tail tail_ih => 1 + sizeOf head + tail_ih) ys
h : ¬x = y.fst
⊢ rec 1 (fun head tail tail_ih => 1 + sizeOf head + tail_ih) (kerase x (y :: ys)) ≤
    rec 1 (fun head tail tail_ih => 1 + sizeOf head + tail_ih) (y :: ys)
[PROOFSTEP]
simp [*]
[GOAL]
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a a' : α
b' : β a'
l : List (Sigma β)
⊢ a ∈ keys (kinsert a' b' l) ↔ a = a' ∨ a ∈ keys l
[PROOFSTEP]
by_cases h : a = a'
[GOAL]
case pos
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a a' : α
b' : β a'
l : List (Sigma β)
h : a = a'
⊢ a ∈ keys (kinsert a' b' l) ↔ a = a' ∨ a ∈ keys l
[PROOFSTEP]
simp [h]
[GOAL]
case neg
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a a' : α
b' : β a'
l : List (Sigma β)
h : ¬a = a'
⊢ a ∈ keys (kinsert a' b' l) ↔ a = a' ∨ a ∈ keys l
[PROOFSTEP]
simp [h]
[GOAL]
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
b : β a
l : List (Sigma β)
⊢ dlookup a (kinsert a b l) = some b
[PROOFSTEP]
simp only [kinsert, dlookup_cons_eq]
[GOAL]
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a a' : α
b' : β a'
l : List (Sigma β)
h : a ≠ a'
⊢ dlookup a (kinsert a' b' l) = dlookup a l
[PROOFSTEP]
simp [h]
[GOAL]
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a a' : α
b : β a'
l : List (Sigma β)
⊢ kextract a ({ fst := a', snd := b } :: l) =
    (dlookup a ({ fst := a', snd := b } :: l), kerase a ({ fst := a', snd := b } :: l))
[PROOFSTEP]
simp [kextract]
[GOAL]
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a a' : α
b : β a'
l : List (Sigma β)
⊢ (if h : a' = a then (some ((_ : { fst := a', snd := b }.fst = a) ▸ b), l)
    else ((kextract a l).fst, { fst := a', snd := b } :: (kextract a l).snd)) =
    (dlookup a ({ fst := a', snd := b } :: l), kerase a ({ fst := a', snd := b } :: l))
[PROOFSTEP]
dsimp
[GOAL]
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a a' : α
b : β a'
l : List (Sigma β)
⊢ (if h : a' = a then (some ((_ : a' = a) ▸ b), l)
    else ((kextract a l).fst, { fst := a', snd := b } :: (kextract a l).snd)) =
    (dlookup a ({ fst := a', snd := b } :: l), kerase a ({ fst := a', snd := b } :: l))
[PROOFSTEP]
split_ifs with h
[GOAL]
case pos
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a a' : α
b : β a'
l : List (Sigma β)
h : a' = a
⊢ (some ((_ : a' = a) ▸ b), l) = (dlookup a ({ fst := a', snd := b } :: l), kerase a ({ fst := a', snd := b } :: l))
[PROOFSTEP]
subst a'
[GOAL]
case pos
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l : List (Sigma β)
b : β a
⊢ (some ((_ : a = a) ▸ b), l) = (dlookup a ({ fst := a, snd := b } :: l), kerase a ({ fst := a, snd := b } :: l))
[PROOFSTEP]
simp [kerase]
[GOAL]
case neg
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a a' : α
b : β a'
l : List (Sigma β)
h : ¬a' = a
⊢ ((kextract a l).fst, { fst := a', snd := b } :: (kextract a l).snd) =
    (dlookup a ({ fst := a', snd := b } :: l), kerase a ({ fst := a', snd := b } :: l))
[PROOFSTEP]
simp [kextract, Ne.symm h, kextract_eq_dlookup_kerase a l, kerase]
[GOAL]
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
l : List (Sigma β)
⊢ NodupKeys (dedupKeys l)
[PROOFSTEP]
dsimp [dedupKeys]
[GOAL]
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
l : List (Sigma β)
⊢ NodupKeys (foldr (fun x => kinsert x.fst x.snd) [] l)
[PROOFSTEP]
generalize hl : nil = l'
[GOAL]
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
l : List (Sigma β)
l' : List (Sigma β)
hl : [] = l'
⊢ NodupKeys (foldr (fun x => kinsert x.fst x.snd) l' l)
[PROOFSTEP]
have : NodupKeys l' := by
  rw [← hl]
  apply nodup_nil
[GOAL]
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
l : List (Sigma β)
l' : List (Sigma β)
hl : [] = l'
⊢ NodupKeys l'
[PROOFSTEP]
rw [← hl]
[GOAL]
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
l : List (Sigma β)
l' : List (Sigma β)
hl : [] = l'
⊢ NodupKeys []
[PROOFSTEP]
apply nodup_nil
[GOAL]
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
l : List (Sigma β)
l' : List (Sigma β)
hl : [] = l'
this : NodupKeys l'
⊢ NodupKeys (foldr (fun x => kinsert x.fst x.snd) l' l)
[PROOFSTEP]
clear hl
[GOAL]
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
l : List (Sigma β)
l' : List (Sigma β)
this : NodupKeys l'
⊢ NodupKeys (foldr (fun x => kinsert x.fst x.snd) l' l)
[PROOFSTEP]
induction' l with x xs l_ih
[GOAL]
case nil
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
l' : List (Sigma β)
this : NodupKeys l'
⊢ NodupKeys (foldr (fun x => kinsert x.fst x.snd) l' [])
[PROOFSTEP]
apply this
[GOAL]
case cons
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
l' : List (Sigma β)
this : NodupKeys l'
x : Sigma β
xs : List (Sigma β)
l_ih : NodupKeys (foldr (fun x => kinsert x.fst x.snd) l' xs)
⊢ NodupKeys (foldr (fun x => kinsert x.fst x.snd) l' (x :: xs))
[PROOFSTEP]
cases x
[GOAL]
case cons.mk
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
l' : List (Sigma β)
this : NodupKeys l'
xs : List (Sigma β)
l_ih : NodupKeys (foldr (fun x => kinsert x.fst x.snd) l' xs)
fst✝ : α
snd✝ : β fst✝
⊢ NodupKeys (foldr (fun x => kinsert x.fst x.snd) l' ({ fst := fst✝, snd := snd✝ } :: xs))
[PROOFSTEP]
simp [dedupKeys]
[GOAL]
case cons.mk
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
l' : List (Sigma β)
this : NodupKeys l'
xs : List (Sigma β)
l_ih : NodupKeys (foldr (fun x => kinsert x.fst x.snd) l' xs)
fst✝ : α
snd✝ : β fst✝
⊢ ¬fst✝ ∈ keys (kerase fst✝ (foldr (fun x => kinsert x.fst x.snd) l' xs)) ∧
    NodupKeys (kerase fst✝ (foldr (fun x => kinsert x.fst x.snd) l' xs))
[PROOFSTEP]
constructor
[GOAL]
case cons.mk.left
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
l' : List (Sigma β)
this : NodupKeys l'
xs : List (Sigma β)
l_ih : NodupKeys (foldr (fun x => kinsert x.fst x.snd) l' xs)
fst✝ : α
snd✝ : β fst✝
⊢ ¬fst✝ ∈ keys (kerase fst✝ (foldr (fun x => kinsert x.fst x.snd) l' xs))
[PROOFSTEP]
simp [keys_kerase]
[GOAL]
case cons.mk.left
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
l' : List (Sigma β)
this : NodupKeys l'
xs : List (Sigma β)
l_ih : NodupKeys (foldr (fun x => kinsert x.fst x.snd) l' xs)
fst✝ : α
snd✝ : β fst✝
⊢ ¬fst✝ ∈ List.erase (keys (foldr (fun x => kinsert x.fst x.snd) l' xs)) fst✝
[PROOFSTEP]
apply l_ih.not_mem_erase
[GOAL]
case cons.mk.right
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
l' : List (Sigma β)
this : NodupKeys l'
xs : List (Sigma β)
l_ih : NodupKeys (foldr (fun x => kinsert x.fst x.snd) l' xs)
fst✝ : α
snd✝ : β fst✝
⊢ NodupKeys (kerase fst✝ (foldr (fun x => kinsert x.fst x.snd) l' xs))
[PROOFSTEP]
exact l_ih.kerase _
[GOAL]
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l : List (Sigma β)
⊢ dlookup a (dedupKeys l) = dlookup a l
[PROOFSTEP]
induction' l with l_hd _ l_ih
[GOAL]
case nil
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
⊢ dlookup a (dedupKeys []) = dlookup a []
case cons
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l_hd : Sigma β
tail✝ : List (Sigma β)
l_ih : dlookup a (dedupKeys tail✝) = dlookup a tail✝
⊢ dlookup a (dedupKeys (l_hd :: tail✝)) = dlookup a (l_hd :: tail✝)
[PROOFSTEP]
rfl
[GOAL]
case cons
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l_hd : Sigma β
tail✝ : List (Sigma β)
l_ih : dlookup a (dedupKeys tail✝) = dlookup a tail✝
⊢ dlookup a (dedupKeys (l_hd :: tail✝)) = dlookup a (l_hd :: tail✝)
[PROOFSTEP]
cases' l_hd with a' b
[GOAL]
case cons.mk
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
tail✝ : List (Sigma β)
l_ih : dlookup a (dedupKeys tail✝) = dlookup a tail✝
a' : α
b : β a'
⊢ dlookup a (dedupKeys ({ fst := a', snd := b } :: tail✝)) = dlookup a ({ fst := a', snd := b } :: tail✝)
[PROOFSTEP]
by_cases h : a = a'
[GOAL]
case pos
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
tail✝ : List (Sigma β)
l_ih : dlookup a (dedupKeys tail✝) = dlookup a tail✝
a' : α
b : β a'
h : a = a'
⊢ dlookup a (dedupKeys ({ fst := a', snd := b } :: tail✝)) = dlookup a ({ fst := a', snd := b } :: tail✝)
[PROOFSTEP]
subst a'
[GOAL]
case pos
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
tail✝ : List (Sigma β)
l_ih : dlookup a (dedupKeys tail✝) = dlookup a tail✝
b : β a
⊢ dlookup a (dedupKeys ({ fst := a, snd := b } :: tail✝)) = dlookup a ({ fst := a, snd := b } :: tail✝)
[PROOFSTEP]
rw [dedupKeys_cons, dlookup_kinsert, dlookup_cons_eq]
[GOAL]
case neg
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
tail✝ : List (Sigma β)
l_ih : dlookup a (dedupKeys tail✝) = dlookup a tail✝
a' : α
b : β a'
h : ¬a = a'
⊢ dlookup a (dedupKeys ({ fst := a', snd := b } :: tail✝)) = dlookup a ({ fst := a', snd := b } :: tail✝)
[PROOFSTEP]
rw [dedupKeys_cons, dlookup_kinsert_ne h, l_ih, dlookup_cons_ne]
[GOAL]
case neg.a
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
tail✝ : List (Sigma β)
l_ih : dlookup a (dedupKeys tail✝) = dlookup a tail✝
a' : α
b : β a'
h : ¬a = a'
⊢ a ≠ { fst := a', snd := b }.fst
[PROOFSTEP]
exact h
[GOAL]
α✝ : Type u
β✝ : α✝ → Type v
l l₁ l₂ : List (Sigma β✝)
inst✝² : DecidableEq α✝
α : Type u_2
β : α → Type u_1
inst✝¹ : DecidableEq α
inst✝ : SizeOf (Sigma β)
xs : List (Sigma β)
⊢ sizeOf (dedupKeys xs) ≤ sizeOf xs
[PROOFSTEP]
simp only [SizeOf.sizeOf, _sizeOf_1]
[GOAL]
α✝ : Type u
β✝ : α✝ → Type v
l l₁ l₂ : List (Sigma β✝)
inst✝² : DecidableEq α✝
α : Type u_2
β : α → Type u_1
inst✝¹ : DecidableEq α
inst✝ : SizeOf (Sigma β)
xs : List (Sigma β)
⊢ rec 1 (fun head tail tail_ih => 1 + sizeOf head + tail_ih) (dedupKeys xs) ≤
    rec 1 (fun head tail tail_ih => 1 + sizeOf head + tail_ih) xs
[PROOFSTEP]
induction' xs with x xs
[GOAL]
case nil
α✝ : Type u
β✝ : α✝ → Type v
l l₁ l₂ : List (Sigma β✝)
inst✝² : DecidableEq α✝
α : Type u_2
β : α → Type u_1
inst✝¹ : DecidableEq α
inst✝ : SizeOf (Sigma β)
⊢ rec 1 (fun head tail tail_ih => 1 + sizeOf head + tail_ih) (dedupKeys []) ≤
    rec 1 (fun head tail tail_ih => 1 + sizeOf head + tail_ih) []
[PROOFSTEP]
simp [dedupKeys]
[GOAL]
case cons
α✝ : Type u
β✝ : α✝ → Type v
l l₁ l₂ : List (Sigma β✝)
inst✝² : DecidableEq α✝
α : Type u_2
β : α → Type u_1
inst✝¹ : DecidableEq α
inst✝ : SizeOf (Sigma β)
x : Sigma β
xs : List (Sigma β)
tail_ih✝ :
  rec 1 (fun head tail tail_ih => 1 + sizeOf head + tail_ih) (dedupKeys xs) ≤
    rec 1 (fun head tail tail_ih => 1 + sizeOf head + tail_ih) xs
⊢ rec 1 (fun head tail tail_ih => 1 + sizeOf head + tail_ih) (dedupKeys (x :: xs)) ≤
    rec 1 (fun head tail tail_ih => 1 + sizeOf head + tail_ih) (x :: xs)
[PROOFSTEP]
simp only [dedupKeys_cons, kinsert_def, add_le_add_iff_left, Sigma.eta]
[GOAL]
case cons
α✝ : Type u
β✝ : α✝ → Type v
l l₁ l₂ : List (Sigma β✝)
inst✝² : DecidableEq α✝
α : Type u_2
β : α → Type u_1
inst✝¹ : DecidableEq α
inst✝ : SizeOf (Sigma β)
x : Sigma β
xs : List (Sigma β)
tail_ih✝ :
  rec 1 (fun head tail tail_ih => 1 + sizeOf head + tail_ih) (dedupKeys xs) ≤
    rec 1 (fun head tail tail_ih => 1 + sizeOf head + tail_ih) xs
⊢ rec 1 (fun head tail tail_ih => 1 + sizeOf head + tail_ih) (kerase x.fst (dedupKeys xs)) ≤
    rec 1 (fun head tail tail_ih => 1 + sizeOf head + tail_ih) xs
[PROOFSTEP]
trans
[GOAL]
α✝ : Type u
β✝ : α✝ → Type v
l l₁ l₂ : List (Sigma β✝)
inst✝² : DecidableEq α✝
α : Type u_2
β : α → Type u_1
inst✝¹ : DecidableEq α
inst✝ : SizeOf (Sigma β)
x : Sigma β
xs : List (Sigma β)
tail_ih✝ :
  rec 1 (fun head tail tail_ih => 1 + sizeOf head + tail_ih) (dedupKeys xs) ≤
    rec 1 (fun head tail tail_ih => 1 + sizeOf head + tail_ih) xs
⊢ rec 1 (fun head tail tail_ih => 1 + sizeOf head + tail_ih) (kerase x.fst (dedupKeys xs)) ≤ ?m.375896
α✝ : Type u
β✝ : α✝ → Type v
l l₁ l₂ : List (Sigma β✝)
inst✝² : DecidableEq α✝
α : Type u_2
β : α → Type u_1
inst✝¹ : DecidableEq α
inst✝ : SizeOf (Sigma β)
x : Sigma β
xs : List (Sigma β)
tail_ih✝ :
  rec 1 (fun head tail tail_ih => 1 + sizeOf head + tail_ih) (dedupKeys xs) ≤
    rec 1 (fun head tail tail_ih => 1 + sizeOf head + tail_ih) xs
⊢ ?m.375896 ≤ rec 1 (fun head tail tail_ih => 1 + sizeOf head + tail_ih) xs
α✝ : Type u
β✝ : α✝ → Type v
l l₁ l₂ : List (Sigma β✝)
inst✝² : DecidableEq α✝
α : Type u_2
β : α → Type u_1
inst✝¹ : DecidableEq α
inst✝ : SizeOf (Sigma β)
x : Sigma β
xs : List (Sigma β)
tail_ih✝ :
  rec 1 (fun head tail tail_ih => 1 + sizeOf head + tail_ih) (dedupKeys xs) ≤
    rec 1 (fun head tail tail_ih => 1 + sizeOf head + tail_ih) xs
⊢ ℕ
[PROOFSTEP]
apply sizeOf_kerase
[GOAL]
α✝ : Type u
β✝ : α✝ → Type v
l l₁ l₂ : List (Sigma β✝)
inst✝² : DecidableEq α✝
α : Type u_2
β : α → Type u_1
inst✝¹ : DecidableEq α
inst✝ : SizeOf (Sigma β)
x : Sigma β
xs : List (Sigma β)
tail_ih✝ :
  rec 1 (fun head tail tail_ih => 1 + sizeOf head + tail_ih) (dedupKeys xs) ≤
    rec 1 (fun head tail tail_ih => 1 + sizeOf head + tail_ih) xs
⊢ sizeOf (dedupKeys xs) ≤ rec 1 (fun head tail tail_ih => 1 + sizeOf head + tail_ih) xs
[PROOFSTEP]
assumption
[GOAL]
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
head✝ : Sigma β
l : List (Sigma β)
⊢ kunion (head✝ :: l) [] = head✝ :: l
[PROOFSTEP]
rw [kunion, kerase_nil, kunion_nil]
[GOAL]
α : Type u
β : α → Type v
l l₁✝ l₂✝ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l₁ l₂ : List (Sigma β)
⊢ a ∈ keys (kunion l₁ l₂) ↔ a ∈ keys l₁ ∨ a ∈ keys l₂
[PROOFSTEP]
induction l₁ generalizing l₂ with
| nil => simp
| cons s l₁ ih => by_cases h : a = s.1 <;> [simp [h]; simp [h, ih]]
[GOAL]
α : Type u
β : α → Type v
l l₁✝ l₂✝ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l₁ l₂ : List (Sigma β)
⊢ a ∈ keys (kunion l₁ l₂) ↔ a ∈ keys l₁ ∨ a ∈ keys l₂
[PROOFSTEP]
induction l₁ generalizing l₂ with
| nil => simp
| cons s l₁ ih => by_cases h : a = s.1 <;> [simp [h]; simp [h, ih]]
[GOAL]
case nil
α : Type u
β : α → Type v
l l₁ l₂✝ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l₂ : List (Sigma β)
⊢ a ∈ keys (kunion [] l₂) ↔ a ∈ keys [] ∨ a ∈ keys l₂
[PROOFSTEP]

| nil => simp
[GOAL]
case nil
α : Type u
β : α → Type v
l l₁ l₂✝ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l₂ : List (Sigma β)
⊢ a ∈ keys (kunion [] l₂) ↔ a ∈ keys [] ∨ a ∈ keys l₂
[PROOFSTEP]
simp
[GOAL]
case cons
α : Type u
β : α → Type v
l l₁✝ l₂✝ : List (Sigma β)
inst✝ : DecidableEq α
a : α
s : Sigma β
l₁ : List (Sigma β)
ih : ∀ {l₂ : List (Sigma β)}, a ∈ keys (kunion l₁ l₂) ↔ a ∈ keys l₁ ∨ a ∈ keys l₂
l₂ : List (Sigma β)
⊢ a ∈ keys (kunion (s :: l₁) l₂) ↔ a ∈ keys (s :: l₁) ∨ a ∈ keys l₂
[PROOFSTEP]

| cons s l₁ ih => by_cases h : a = s.1 <;> [simp [h]; simp [h, ih]]
[GOAL]
case cons
α : Type u
β : α → Type v
l l₁✝ l₂✝ : List (Sigma β)
inst✝ : DecidableEq α
a : α
s : Sigma β
l₁ : List (Sigma β)
ih : ∀ {l₂ : List (Sigma β)}, a ∈ keys (kunion l₁ l₂) ↔ a ∈ keys l₁ ∨ a ∈ keys l₂
l₂ : List (Sigma β)
⊢ a ∈ keys (kunion (s :: l₁) l₂) ↔ a ∈ keys (s :: l₁) ∨ a ∈ keys l₂
[PROOFSTEP]
by_cases h : a = s.1 <;> [simp [h]; simp [h, ih]]
[GOAL]
case cons
α : Type u
β : α → Type v
l l₁✝ l₂✝ : List (Sigma β)
inst✝ : DecidableEq α
a : α
s : Sigma β
l₁ : List (Sigma β)
ih : ∀ {l₂ : List (Sigma β)}, a ∈ keys (kunion l₁ l₂) ↔ a ∈ keys l₁ ∨ a ∈ keys l₂
l₂ : List (Sigma β)
⊢ a ∈ keys (kunion (s :: l₁) l₂) ↔ a ∈ keys (s :: l₁) ∨ a ∈ keys l₂
[PROOFSTEP]
by_cases h : a = s.1
[GOAL]
case pos
α : Type u
β : α → Type v
l l₁✝ l₂✝ : List (Sigma β)
inst✝ : DecidableEq α
a : α
s : Sigma β
l₁ : List (Sigma β)
ih : ∀ {l₂ : List (Sigma β)}, a ∈ keys (kunion l₁ l₂) ↔ a ∈ keys l₁ ∨ a ∈ keys l₂
l₂ : List (Sigma β)
h : a = s.fst
⊢ a ∈ keys (kunion (s :: l₁) l₂) ↔ a ∈ keys (s :: l₁) ∨ a ∈ keys l₂
[PROOFSTEP]
simp [h]
[GOAL]
case neg
α : Type u
β : α → Type v
l l₁✝ l₂✝ : List (Sigma β)
inst✝ : DecidableEq α
a : α
s : Sigma β
l₁ : List (Sigma β)
ih : ∀ {l₂ : List (Sigma β)}, a ∈ keys (kunion l₁ l₂) ↔ a ∈ keys l₁ ∨ a ∈ keys l₂
l₂ : List (Sigma β)
h : ¬a = s.fst
⊢ a ∈ keys (kunion (s :: l₁) l₂) ↔ a ∈ keys (s :: l₁) ∨ a ∈ keys l₂
[PROOFSTEP]
simp [h, ih]
[GOAL]
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
s : Sigma β
tail✝ : List (Sigma β)
l : List (Sigma β)
⊢ kunion (kerase a (s :: tail✝)) (kerase a l) = kerase a (kunion (s :: tail✝) l)
[PROOFSTEP]
by_cases h : a = s.1
[GOAL]
case pos
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
s : Sigma β
tail✝ : List (Sigma β)
l : List (Sigma β)
h : a = s.fst
⊢ kunion (kerase a (s :: tail✝)) (kerase a l) = kerase a (kunion (s :: tail✝) l)
[PROOFSTEP]
simp [h, kerase_comm a s.1 l, kunion_kerase]
[GOAL]
case neg
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
s : Sigma β
tail✝ : List (Sigma β)
l : List (Sigma β)
h : ¬a = s.fst
⊢ kunion (kerase a (s :: tail✝)) (kerase a l) = kerase a (kunion (s :: tail✝) l)
[PROOFSTEP]
simp [h, kerase_comm a s.1 l, kunion_kerase]
[GOAL]
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
nd₁ : NodupKeys l₁
nd₂ : NodupKeys l₂
⊢ NodupKeys (List.kunion l₁ l₂)
[PROOFSTEP]
induction l₁ generalizing l₂ with
| nil => simp only [nil_kunion, nd₂]
| cons s l₁ ih =>
  simp at nd₁ 
  simp [not_or, nd₁.1, nd₂, ih nd₁.2 (nd₂.kerase s.1)]
[GOAL]
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
nd₁ : NodupKeys l₁
nd₂ : NodupKeys l₂
⊢ NodupKeys (List.kunion l₁ l₂)
[PROOFSTEP]
induction l₁ generalizing l₂ with
| nil => simp only [nil_kunion, nd₂]
| cons s l₁ ih =>
  simp at nd₁ 
  simp [not_or, nd₁.1, nd₂, ih nd₁.2 (nd₂.kerase s.1)]
[GOAL]
case nil
α : Type u
β : α → Type v
l : List (Sigma β)
inst✝ : DecidableEq α
l₂ : List (Sigma β)
nd₁ : NodupKeys []
nd₂ : NodupKeys l₂
⊢ NodupKeys (List.kunion [] l₂)
[PROOFSTEP]

| nil => simp only [nil_kunion, nd₂]
[GOAL]
case nil
α : Type u
β : α → Type v
l : List (Sigma β)
inst✝ : DecidableEq α
l₂ : List (Sigma β)
nd₁ : NodupKeys []
nd₂ : NodupKeys l₂
⊢ NodupKeys (List.kunion [] l₂)
[PROOFSTEP]
simp only [nil_kunion, nd₂]
[GOAL]
case cons
α : Type u
β : α → Type v
l : List (Sigma β)
inst✝ : DecidableEq α
s : Sigma β
l₁ : List (Sigma β)
ih : ∀ {l₂ : List (Sigma β)}, NodupKeys l₁ → NodupKeys l₂ → NodupKeys (List.kunion l₁ l₂)
l₂ : List (Sigma β)
nd₁ : NodupKeys (s :: l₁)
nd₂ : NodupKeys l₂
⊢ NodupKeys (List.kunion (s :: l₁) l₂)
[PROOFSTEP]

| cons s l₁ ih =>
  simp at nd₁ 
  simp [not_or, nd₁.1, nd₂, ih nd₁.2 (nd₂.kerase s.1)]
[GOAL]
case cons
α : Type u
β : α → Type v
l : List (Sigma β)
inst✝ : DecidableEq α
s : Sigma β
l₁ : List (Sigma β)
ih : ∀ {l₂ : List (Sigma β)}, NodupKeys l₁ → NodupKeys l₂ → NodupKeys (List.kunion l₁ l₂)
l₂ : List (Sigma β)
nd₁ : NodupKeys (s :: l₁)
nd₂ : NodupKeys l₂
⊢ NodupKeys (List.kunion (s :: l₁) l₂)
[PROOFSTEP]
simp at nd₁ 
[GOAL]
case cons
α : Type u
β : α → Type v
l : List (Sigma β)
inst✝ : DecidableEq α
s : Sigma β
l₁ : List (Sigma β)
ih : ∀ {l₂ : List (Sigma β)}, NodupKeys l₁ → NodupKeys l₂ → NodupKeys (List.kunion l₁ l₂)
l₂ : List (Sigma β)
nd₂ : NodupKeys l₂
nd₁ : ¬s.fst ∈ keys l₁ ∧ NodupKeys l₁
⊢ NodupKeys (List.kunion (s :: l₁) l₂)
[PROOFSTEP]
simp [not_or, nd₁.1, nd₂, ih nd₁.2 (nd₂.kerase s.1)]
[GOAL]
α : Type u
β : α → Type v
l✝ l₁✝ l₂✝ : List (Sigma β)
inst✝ : DecidableEq α
l₁ l₂ : List (Sigma β)
p : l₁ ~ l₂
l : List (Sigma β)
⊢ kunion l₁ l ~ kunion l₂ l
[PROOFSTEP]
induction p generalizing l with
| nil => rfl
| cons hd _ ih => simp [ih (List.kerase _ _), Perm.cons]
| swap s₁ s₂ l => simp [kerase_comm, Perm.swap]
| trans _ _ ih₁₂ ih₂₃ => exact Perm.trans (ih₁₂ l) (ih₂₃ l)
[GOAL]
α : Type u
β : α → Type v
l✝ l₁✝ l₂✝ : List (Sigma β)
inst✝ : DecidableEq α
l₁ l₂ : List (Sigma β)
p : l₁ ~ l₂
l : List (Sigma β)
⊢ kunion l₁ l ~ kunion l₂ l
[PROOFSTEP]
induction p generalizing l with
| nil => rfl
| cons hd _ ih => simp [ih (List.kerase _ _), Perm.cons]
| swap s₁ s₂ l => simp [kerase_comm, Perm.swap]
| trans _ _ ih₁₂ ih₂₃ => exact Perm.trans (ih₁₂ l) (ih₂₃ l)
[GOAL]
case nil
α : Type u
β : α → Type v
l✝ l₁✝ l₂✝ : List (Sigma β)
inst✝ : DecidableEq α
l₁ l₂ l : List (Sigma β)
⊢ kunion [] l ~ kunion [] l
[PROOFSTEP]

| nil => rfl
[GOAL]
case nil
α : Type u
β : α → Type v
l✝ l₁✝ l₂✝ : List (Sigma β)
inst✝ : DecidableEq α
l₁ l₂ l : List (Sigma β)
⊢ kunion [] l ~ kunion [] l
[PROOFSTEP]
rfl
[GOAL]
case cons
α : Type u
β : α → Type v
l✝ l₁✝¹ l₂✝¹ : List (Sigma β)
inst✝ : DecidableEq α
l₁ l₂ : List (Sigma β)
hd : Sigma β
l₁✝ l₂✝ : List (Sigma β)
a✝ : l₁✝ ~ l₂✝
ih : ∀ (l : List (Sigma β)), kunion l₁✝ l ~ kunion l₂✝ l
l : List (Sigma β)
⊢ kunion (hd :: l₁✝) l ~ kunion (hd :: l₂✝) l
[PROOFSTEP]

| cons hd _ ih => simp [ih (List.kerase _ _), Perm.cons]
[GOAL]
case cons
α : Type u
β : α → Type v
l✝ l₁✝¹ l₂✝¹ : List (Sigma β)
inst✝ : DecidableEq α
l₁ l₂ : List (Sigma β)
hd : Sigma β
l₁✝ l₂✝ : List (Sigma β)
a✝ : l₁✝ ~ l₂✝
ih : ∀ (l : List (Sigma β)), kunion l₁✝ l ~ kunion l₂✝ l
l : List (Sigma β)
⊢ kunion (hd :: l₁✝) l ~ kunion (hd :: l₂✝) l
[PROOFSTEP]
simp [ih (List.kerase _ _), Perm.cons]
[GOAL]
case swap
α : Type u
β : α → Type v
l✝¹ l₁✝ l₂✝ : List (Sigma β)
inst✝ : DecidableEq α
l₁ l₂ : List (Sigma β)
s₁ s₂ : Sigma β
l✝ : List (Sigma β)
l : List (Sigma β)
⊢ kunion (s₂ :: s₁ :: l✝) l ~ kunion (s₁ :: s₂ :: l✝) l
[PROOFSTEP]

| swap s₁ s₂ l => simp [kerase_comm, Perm.swap]
[GOAL]
case swap
α : Type u
β : α → Type v
l✝¹ l₁✝ l₂✝ : List (Sigma β)
inst✝ : DecidableEq α
l₁ l₂ : List (Sigma β)
s₁ s₂ : Sigma β
l✝ : List (Sigma β)
l : List (Sigma β)
⊢ kunion (s₂ :: s₁ :: l✝) l ~ kunion (s₁ :: s₂ :: l✝) l
[PROOFSTEP]
simp [kerase_comm, Perm.swap]
[GOAL]
case trans
α : Type u
β : α → Type v
l✝ l₁✝¹ l₂✝¹ : List (Sigma β)
inst✝ : DecidableEq α
l₁ l₂ : List (Sigma β)
l₁✝ l₂✝ l₃✝ : List (Sigma β)
a✝¹ : l₁✝ ~ l₂✝
a✝ : l₂✝ ~ l₃✝
ih₁₂ : ∀ (l : List (Sigma β)), kunion l₁✝ l ~ kunion l₂✝ l
ih₂₃ : ∀ (l : List (Sigma β)), kunion l₂✝ l ~ kunion l₃✝ l
l : List (Sigma β)
⊢ kunion l₁✝ l ~ kunion l₃✝ l
[PROOFSTEP]

| trans _ _ ih₁₂ ih₂₃ => exact Perm.trans (ih₁₂ l) (ih₂₃ l)
[GOAL]
case trans
α : Type u
β : α → Type v
l✝ l₁✝¹ l₂✝¹ : List (Sigma β)
inst✝ : DecidableEq α
l₁ l₂ : List (Sigma β)
l₁✝ l₂✝ l₃✝ : List (Sigma β)
a✝¹ : l₁✝ ~ l₂✝
a✝ : l₂✝ ~ l₃✝
ih₁₂ : ∀ (l : List (Sigma β)), kunion l₁✝ l ~ kunion l₂✝ l
ih₂₃ : ∀ (l : List (Sigma β)), kunion l₂✝ l ~ kunion l₃✝ l
l : List (Sigma β)
⊢ kunion l₁✝ l ~ kunion l₃✝ l
[PROOFSTEP]
exact Perm.trans (ih₁₂ l) (ih₂₃ l)
[GOAL]
α : Type u
β : α → Type v
l l₁✝ l₂✝ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l₁ l₂ : List (Sigma β)
h : a ∈ keys l₁
⊢ dlookup a (kunion l₁ l₂) = dlookup a l₁
[PROOFSTEP]
induction' l₁ with s _ ih generalizing l₂
[GOAL]
case nil
α : Type u
β : α → Type v
l l₁✝ l₂✝¹ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l₁ l₂✝ : List (Sigma β)
h✝ : a ∈ keys l₁
l₂ : List (Sigma β)
h : a ∈ keys []
⊢ dlookup a (kunion [] l₂) = dlookup a []
[PROOFSTEP]
simp at h 
[GOAL]
case cons
α : Type u
β : α → Type v
l l₁✝ l₂✝¹ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l₁ l₂✝ : List (Sigma β)
h✝ : a ∈ keys l₁
s : Sigma β
tail✝ : List (Sigma β)
ih : ∀ {l₂ : List (Sigma β)}, a ∈ keys tail✝ → dlookup a (kunion tail✝ l₂) = dlookup a tail✝
l₂ : List (Sigma β)
h : a ∈ keys (s :: tail✝)
⊢ dlookup a (kunion (s :: tail✝) l₂) = dlookup a (s :: tail✝)
[PROOFSTEP]
simp at h 
[GOAL]
case cons
α : Type u
β : α → Type v
l l₁✝ l₂✝¹ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l₁ l₂✝ : List (Sigma β)
h✝ : a ∈ keys l₁
s : Sigma β
tail✝ : List (Sigma β)
ih : ∀ {l₂ : List (Sigma β)}, a ∈ keys tail✝ → dlookup a (kunion tail✝ l₂) = dlookup a tail✝
l₂ : List (Sigma β)
h : a = s.fst ∨ a ∈ keys tail✝
⊢ dlookup a (kunion (s :: tail✝) l₂) = dlookup a (s :: tail✝)
[PROOFSTEP]
cases' h with h h
[GOAL]
case cons.inl
α : Type u
β : α → Type v
l l₁✝ l₂✝¹ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l₁ l₂✝ : List (Sigma β)
h✝ : a ∈ keys l₁
s : Sigma β
tail✝ : List (Sigma β)
ih : ∀ {l₂ : List (Sigma β)}, a ∈ keys tail✝ → dlookup a (kunion tail✝ l₂) = dlookup a tail✝
l₂ : List (Sigma β)
h : a = s.fst
⊢ dlookup a (kunion (s :: tail✝) l₂) = dlookup a (s :: tail✝)
[PROOFSTEP]
cases' s with a'
[GOAL]
case cons.inr
α : Type u
β : α → Type v
l l₁✝ l₂✝¹ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l₁ l₂✝ : List (Sigma β)
h✝ : a ∈ keys l₁
s : Sigma β
tail✝ : List (Sigma β)
ih : ∀ {l₂ : List (Sigma β)}, a ∈ keys tail✝ → dlookup a (kunion tail✝ l₂) = dlookup a tail✝
l₂ : List (Sigma β)
h : a ∈ keys tail✝
⊢ dlookup a (kunion (s :: tail✝) l₂) = dlookup a (s :: tail✝)
[PROOFSTEP]
cases' s with a'
[GOAL]
case cons.inl.mk
α : Type u
β : α → Type v
l l₁✝ l₂✝¹ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l₁ l₂✝ : List (Sigma β)
h✝ : a ∈ keys l₁
tail✝ : List (Sigma β)
ih : ∀ {l₂ : List (Sigma β)}, a ∈ keys tail✝ → dlookup a (kunion tail✝ l₂) = dlookup a tail✝
l₂ : List (Sigma β)
a' : α
snd✝ : β a'
h : a = { fst := a', snd := snd✝ }.fst
⊢ dlookup a (kunion ({ fst := a', snd := snd✝ } :: tail✝) l₂) = dlookup a ({ fst := a', snd := snd✝ } :: tail✝)
[PROOFSTEP]
subst h
[GOAL]
case cons.inl.mk
α : Type u
β : α → Type v
l l₁✝ l₂✝¹ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l₁ l₂✝ : List (Sigma β)
h : a ∈ keys l₁
tail✝ : List (Sigma β)
ih : ∀ {l₂ : List (Sigma β)}, a ∈ keys tail✝ → dlookup a (kunion tail✝ l₂) = dlookup a tail✝
l₂ : List (Sigma β)
snd✝ : β a
⊢ dlookup a (kunion ({ fst := a, snd := snd✝ } :: tail✝) l₂) = dlookup a ({ fst := a, snd := snd✝ } :: tail✝)
[PROOFSTEP]
simp
[GOAL]
case cons.inr.mk
α : Type u
β : α → Type v
l l₁✝ l₂✝¹ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l₁ l₂✝ : List (Sigma β)
h✝ : a ∈ keys l₁
tail✝ : List (Sigma β)
ih : ∀ {l₂ : List (Sigma β)}, a ∈ keys tail✝ → dlookup a (kunion tail✝ l₂) = dlookup a tail✝
l₂ : List (Sigma β)
h : a ∈ keys tail✝
a' : α
snd✝ : β a'
⊢ dlookup a (kunion ({ fst := a', snd := snd✝ } :: tail✝) l₂) = dlookup a ({ fst := a', snd := snd✝ } :: tail✝)
[PROOFSTEP]
rw [kunion_cons]
[GOAL]
case cons.inr.mk
α : Type u
β : α → Type v
l l₁✝ l₂✝¹ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l₁ l₂✝ : List (Sigma β)
h✝ : a ∈ keys l₁
tail✝ : List (Sigma β)
ih : ∀ {l₂ : List (Sigma β)}, a ∈ keys tail✝ → dlookup a (kunion tail✝ l₂) = dlookup a tail✝
l₂ : List (Sigma β)
h : a ∈ keys tail✝
a' : α
snd✝ : β a'
⊢ dlookup a ({ fst := a', snd := snd✝ } :: kunion tail✝ (kerase { fst := a', snd := snd✝ }.fst l₂)) =
    dlookup a ({ fst := a', snd := snd✝ } :: tail✝)
[PROOFSTEP]
by_cases h' : a = a'
[GOAL]
case pos
α : Type u
β : α → Type v
l l₁✝ l₂✝¹ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l₁ l₂✝ : List (Sigma β)
h✝ : a ∈ keys l₁
tail✝ : List (Sigma β)
ih : ∀ {l₂ : List (Sigma β)}, a ∈ keys tail✝ → dlookup a (kunion tail✝ l₂) = dlookup a tail✝
l₂ : List (Sigma β)
h : a ∈ keys tail✝
a' : α
snd✝ : β a'
h' : a = a'
⊢ dlookup a ({ fst := a', snd := snd✝ } :: kunion tail✝ (kerase { fst := a', snd := snd✝ }.fst l₂)) =
    dlookup a ({ fst := a', snd := snd✝ } :: tail✝)
[PROOFSTEP]
subst h'
[GOAL]
case pos
α : Type u
β : α → Type v
l l₁✝ l₂✝¹ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l₁ l₂✝ : List (Sigma β)
h✝ : a ∈ keys l₁
tail✝ : List (Sigma β)
ih : ∀ {l₂ : List (Sigma β)}, a ∈ keys tail✝ → dlookup a (kunion tail✝ l₂) = dlookup a tail✝
l₂ : List (Sigma β)
h : a ∈ keys tail✝
snd✝ : β a
⊢ dlookup a ({ fst := a, snd := snd✝ } :: kunion tail✝ (kerase { fst := a, snd := snd✝ }.fst l₂)) =
    dlookup a ({ fst := a, snd := snd✝ } :: tail✝)
[PROOFSTEP]
simp
[GOAL]
case neg
α : Type u
β : α → Type v
l l₁✝ l₂✝¹ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l₁ l₂✝ : List (Sigma β)
h✝ : a ∈ keys l₁
tail✝ : List (Sigma β)
ih : ∀ {l₂ : List (Sigma β)}, a ∈ keys tail✝ → dlookup a (kunion tail✝ l₂) = dlookup a tail✝
l₂ : List (Sigma β)
h : a ∈ keys tail✝
a' : α
snd✝ : β a'
h' : ¬a = a'
⊢ dlookup a ({ fst := a', snd := snd✝ } :: kunion tail✝ (kerase { fst := a', snd := snd✝ }.fst l₂)) =
    dlookup a ({ fst := a', snd := snd✝ } :: tail✝)
[PROOFSTEP]
simp [h', ih h]
[GOAL]
α : Type u
β : α → Type v
l l₁✝ l₂✝ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l₁ l₂ : List (Sigma β)
h : ¬a ∈ keys l₁
⊢ dlookup a (kunion l₁ l₂) = dlookup a l₂
[PROOFSTEP]
induction l₁ generalizing l₂ with
| nil => simp
| cons _ _ ih => simp [not_or] at h ; simp [h.1, ih h.2]
[GOAL]
α : Type u
β : α → Type v
l l₁✝ l₂✝ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l₁ l₂ : List (Sigma β)
h : ¬a ∈ keys l₁
⊢ dlookup a (kunion l₁ l₂) = dlookup a l₂
[PROOFSTEP]
induction l₁ generalizing l₂ with
| nil => simp
| cons _ _ ih => simp [not_or] at h ; simp [h.1, ih h.2]
[GOAL]
case nil
α : Type u
β : α → Type v
l l₁ l₂✝ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l₂ : List (Sigma β)
h : ¬a ∈ keys []
⊢ dlookup a (kunion [] l₂) = dlookup a l₂
[PROOFSTEP]

| nil => simp
[GOAL]
case nil
α : Type u
β : α → Type v
l l₁ l₂✝ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l₂ : List (Sigma β)
h : ¬a ∈ keys []
⊢ dlookup a (kunion [] l₂) = dlookup a l₂
[PROOFSTEP]
simp
[GOAL]
case cons
α : Type u
β : α → Type v
l l₁ l₂✝ : List (Sigma β)
inst✝ : DecidableEq α
a : α
head✝ : Sigma β
tail✝ : List (Sigma β)
ih : ∀ {l₂ : List (Sigma β)}, ¬a ∈ keys tail✝ → dlookup a (kunion tail✝ l₂) = dlookup a l₂
l₂ : List (Sigma β)
h : ¬a ∈ keys (head✝ :: tail✝)
⊢ dlookup a (kunion (head✝ :: tail✝) l₂) = dlookup a l₂
[PROOFSTEP]

| cons _ _ ih => simp [not_or] at h ; simp [h.1, ih h.2]
[GOAL]
case cons
α : Type u
β : α → Type v
l l₁ l₂✝ : List (Sigma β)
inst✝ : DecidableEq α
a : α
head✝ : Sigma β
tail✝ : List (Sigma β)
ih : ∀ {l₂ : List (Sigma β)}, ¬a ∈ keys tail✝ → dlookup a (kunion tail✝ l₂) = dlookup a l₂
l₂ : List (Sigma β)
h : ¬a ∈ keys (head✝ :: tail✝)
⊢ dlookup a (kunion (head✝ :: tail✝) l₂) = dlookup a l₂
[PROOFSTEP]
simp [not_or] at h 
[GOAL]
case cons
α : Type u
β : α → Type v
l l₁ l₂✝ : List (Sigma β)
inst✝ : DecidableEq α
a : α
head✝ : Sigma β
tail✝ : List (Sigma β)
ih : ∀ {l₂ : List (Sigma β)}, ¬a ∈ keys tail✝ → dlookup a (kunion tail✝ l₂) = dlookup a l₂
l₂ : List (Sigma β)
h : ¬a = head✝.fst ∧ ¬a ∈ keys tail✝
⊢ dlookup a (kunion (head✝ :: tail✝) l₂) = dlookup a l₂
[PROOFSTEP]
simp [h.1, ih h.2]
[GOAL]
α : Type u
β : α → Type v
l l₁✝ l₂✝ : List (Sigma β)
inst✝ : DecidableEq α
a : α
b : β a
l₁ l₂ : List (Sigma β)
⊢ b ∈ dlookup a (kunion l₁ l₂) ↔ b ∈ dlookup a l₁ ∨ ¬a ∈ keys l₁ ∧ b ∈ dlookup a l₂
[PROOFSTEP]
induction l₁ generalizing l₂ with
| nil => simp
| cons s _ ih =>
  cases' s with a'
  by_cases h₁ : a = a'
  · subst h₁
    simp
  · let h₂ := @ih (kerase a' l₂)
    simp [h₁] at h₂ 
    simp [h₁, h₂]
[GOAL]
α : Type u
β : α → Type v
l l₁✝ l₂✝ : List (Sigma β)
inst✝ : DecidableEq α
a : α
b : β a
l₁ l₂ : List (Sigma β)
⊢ b ∈ dlookup a (kunion l₁ l₂) ↔ b ∈ dlookup a l₁ ∨ ¬a ∈ keys l₁ ∧ b ∈ dlookup a l₂
[PROOFSTEP]
induction l₁ generalizing l₂ with
| nil => simp
| cons s _ ih =>
  cases' s with a'
  by_cases h₁ : a = a'
  · subst h₁
    simp
  · let h₂ := @ih (kerase a' l₂)
    simp [h₁] at h₂ 
    simp [h₁, h₂]
[GOAL]
case nil
α : Type u
β : α → Type v
l l₁ l₂✝ : List (Sigma β)
inst✝ : DecidableEq α
a : α
b : β a
l₂ : List (Sigma β)
⊢ b ∈ dlookup a (kunion [] l₂) ↔ b ∈ dlookup a [] ∨ ¬a ∈ keys [] ∧ b ∈ dlookup a l₂
[PROOFSTEP]

| nil => simp
[GOAL]
case nil
α : Type u
β : α → Type v
l l₁ l₂✝ : List (Sigma β)
inst✝ : DecidableEq α
a : α
b : β a
l₂ : List (Sigma β)
⊢ b ∈ dlookup a (kunion [] l₂) ↔ b ∈ dlookup a [] ∨ ¬a ∈ keys [] ∧ b ∈ dlookup a l₂
[PROOFSTEP]
simp
[GOAL]
case cons
α : Type u
β : α → Type v
l l₁ l₂✝ : List (Sigma β)
inst✝ : DecidableEq α
a : α
b : β a
s : Sigma β
tail✝ : List (Sigma β)
ih : ∀ {l₂ : List (Sigma β)}, b ∈ dlookup a (kunion tail✝ l₂) ↔ b ∈ dlookup a tail✝ ∨ ¬a ∈ keys tail✝ ∧ b ∈ dlookup a l₂
l₂ : List (Sigma β)
⊢ b ∈ dlookup a (kunion (s :: tail✝) l₂) ↔ b ∈ dlookup a (s :: tail✝) ∨ ¬a ∈ keys (s :: tail✝) ∧ b ∈ dlookup a l₂
[PROOFSTEP]

| cons s _ ih =>
  cases' s with a'
  by_cases h₁ : a = a'
  · subst h₁
    simp
  · let h₂ := @ih (kerase a' l₂)
    simp [h₁] at h₂ 
    simp [h₁, h₂]
[GOAL]
case cons
α : Type u
β : α → Type v
l l₁ l₂✝ : List (Sigma β)
inst✝ : DecidableEq α
a : α
b : β a
s : Sigma β
tail✝ : List (Sigma β)
ih : ∀ {l₂ : List (Sigma β)}, b ∈ dlookup a (kunion tail✝ l₂) ↔ b ∈ dlookup a tail✝ ∨ ¬a ∈ keys tail✝ ∧ b ∈ dlookup a l₂
l₂ : List (Sigma β)
⊢ b ∈ dlookup a (kunion (s :: tail✝) l₂) ↔ b ∈ dlookup a (s :: tail✝) ∨ ¬a ∈ keys (s :: tail✝) ∧ b ∈ dlookup a l₂
[PROOFSTEP]
cases' s with a'
[GOAL]
case cons.mk
α : Type u
β : α → Type v
l l₁ l₂✝ : List (Sigma β)
inst✝ : DecidableEq α
a : α
b : β a
tail✝ : List (Sigma β)
ih : ∀ {l₂ : List (Sigma β)}, b ∈ dlookup a (kunion tail✝ l₂) ↔ b ∈ dlookup a tail✝ ∨ ¬a ∈ keys tail✝ ∧ b ∈ dlookup a l₂
l₂ : List (Sigma β)
a' : α
snd✝ : β a'
⊢ b ∈ dlookup a (kunion ({ fst := a', snd := snd✝ } :: tail✝) l₂) ↔
    b ∈ dlookup a ({ fst := a', snd := snd✝ } :: tail✝) ∨
      ¬a ∈ keys ({ fst := a', snd := snd✝ } :: tail✝) ∧ b ∈ dlookup a l₂
[PROOFSTEP]
by_cases h₁ : a = a'
[GOAL]
case pos
α : Type u
β : α → Type v
l l₁ l₂✝ : List (Sigma β)
inst✝ : DecidableEq α
a : α
b : β a
tail✝ : List (Sigma β)
ih : ∀ {l₂ : List (Sigma β)}, b ∈ dlookup a (kunion tail✝ l₂) ↔ b ∈ dlookup a tail✝ ∨ ¬a ∈ keys tail✝ ∧ b ∈ dlookup a l₂
l₂ : List (Sigma β)
a' : α
snd✝ : β a'
h₁ : a = a'
⊢ b ∈ dlookup a (kunion ({ fst := a', snd := snd✝ } :: tail✝) l₂) ↔
    b ∈ dlookup a ({ fst := a', snd := snd✝ } :: tail✝) ∨
      ¬a ∈ keys ({ fst := a', snd := snd✝ } :: tail✝) ∧ b ∈ dlookup a l₂
[PROOFSTEP]
subst h₁
[GOAL]
case pos
α : Type u
β : α → Type v
l l₁ l₂✝ : List (Sigma β)
inst✝ : DecidableEq α
a : α
b : β a
tail✝ : List (Sigma β)
ih : ∀ {l₂ : List (Sigma β)}, b ∈ dlookup a (kunion tail✝ l₂) ↔ b ∈ dlookup a tail✝ ∨ ¬a ∈ keys tail✝ ∧ b ∈ dlookup a l₂
l₂ : List (Sigma β)
snd✝ : β a
⊢ b ∈ dlookup a (kunion ({ fst := a, snd := snd✝ } :: tail✝) l₂) ↔
    b ∈ dlookup a ({ fst := a, snd := snd✝ } :: tail✝) ∨
      ¬a ∈ keys ({ fst := a, snd := snd✝ } :: tail✝) ∧ b ∈ dlookup a l₂
[PROOFSTEP]
simp
[GOAL]
case neg
α : Type u
β : α → Type v
l l₁ l₂✝ : List (Sigma β)
inst✝ : DecidableEq α
a : α
b : β a
tail✝ : List (Sigma β)
ih : ∀ {l₂ : List (Sigma β)}, b ∈ dlookup a (kunion tail✝ l₂) ↔ b ∈ dlookup a tail✝ ∨ ¬a ∈ keys tail✝ ∧ b ∈ dlookup a l₂
l₂ : List (Sigma β)
a' : α
snd✝ : β a'
h₁ : ¬a = a'
⊢ b ∈ dlookup a (kunion ({ fst := a', snd := snd✝ } :: tail✝) l₂) ↔
    b ∈ dlookup a ({ fst := a', snd := snd✝ } :: tail✝) ∨
      ¬a ∈ keys ({ fst := a', snd := snd✝ } :: tail✝) ∧ b ∈ dlookup a l₂
[PROOFSTEP]
let h₂ := @ih (kerase a' l₂)
[GOAL]
case neg
α : Type u
β : α → Type v
l l₁ l₂✝ : List (Sigma β)
inst✝ : DecidableEq α
a : α
b : β a
tail✝ : List (Sigma β)
ih : ∀ {l₂ : List (Sigma β)}, b ∈ dlookup a (kunion tail✝ l₂) ↔ b ∈ dlookup a tail✝ ∨ ¬a ∈ keys tail✝ ∧ b ∈ dlookup a l₂
l₂ : List (Sigma β)
a' : α
snd✝ : β a'
h₁ : ¬a = a'
h₂ : b ∈ dlookup a (kunion tail✝ (kerase a' l₂)) ↔
  b ∈ dlookup a tail✝ ∨ ¬a ∈ keys tail✝ ∧ b ∈ dlookup a (kerase a' l₂) :=
  ih
⊢ b ∈ dlookup a (kunion ({ fst := a', snd := snd✝ } :: tail✝) l₂) ↔
    b ∈ dlookup a ({ fst := a', snd := snd✝ } :: tail✝) ∨
      ¬a ∈ keys ({ fst := a', snd := snd✝ } :: tail✝) ∧ b ∈ dlookup a l₂
[PROOFSTEP]
simp [h₁] at h₂ 
[GOAL]
case neg
α : Type u
β : α → Type v
l l₁ l₂✝ : List (Sigma β)
inst✝ : DecidableEq α
a : α
b : β a
tail✝ : List (Sigma β)
ih : ∀ {l₂ : List (Sigma β)}, b ∈ dlookup a (kunion tail✝ l₂) ↔ b ∈ dlookup a tail✝ ∨ ¬a ∈ keys tail✝ ∧ b ∈ dlookup a l₂
l₂ : List (Sigma β)
a' : α
snd✝ : β a'
h₁ : ¬a = a'
h₂ :
  dlookup a (kunion tail✝ (kerase a' l₂)) = some b ↔ dlookup a tail✝ = some b ∨ ¬a ∈ keys tail✝ ∧ dlookup a l₂ = some b
⊢ b ∈ dlookup a (kunion ({ fst := a', snd := snd✝ } :: tail✝) l₂) ↔
    b ∈ dlookup a ({ fst := a', snd := snd✝ } :: tail✝) ∨
      ¬a ∈ keys ({ fst := a', snd := snd✝ } :: tail✝) ∧ b ∈ dlookup a l₂
[PROOFSTEP]
simp [h₁, h₂]
