l3lab/ntp-mathlib huggingface dataset:
theorem head?_lookupAll (a : α) : ∀ l : List (Sigma β), head? (lookupAll a l) = dlookup a l
  | [] => by simp
  | ⟨a', b⟩ :: l => by
    by_cases h : a = a'
    · subst h; 

Proof state:
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)

Next tactic:
simp
theorem head?_lookupAll (a : α) : ∀ l : List (Sigma β), head? (lookupAll a l) = dlookup a l
  | [] => by simp
  | ⟨a', b⟩ :: l => by
    by_cases h : a = a'
    · subst h; simp
    · 

Proof state:
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)

Next tactic:
rw [lookupAll_cons_ne, dlookup_cons_ne, head?_lookupAll a l]
theorem head?_lookupAll (a : α) : ∀ l : List (Sigma β), head? (lookupAll a l) = dlookup a l
  | [] => by simp
  | ⟨a', b⟩ :: l => by
    by_cases h : a = a'
    · subst h; simp
    · rw [lookupAll_cons_ne, dlookup_cons_ne, head?_lookupAll a l] <;> 

Proof state:
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

Next tactic:
assumption
theorem mem_lookupAll {a : α} {b : β a} :
    ∀ {l : List (Sigma β)}, b ∈ lookupAll a l ↔ Sigma.mk a b ∈ l
  | [] => by 

Proof state:
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
b : β a
⊢ b ∈ lookupAll a [] ↔ { fst := a, snd := b } ∈ []

Next tactic:
simp
theorem mem_lookupAll {a : α} {b : β a} :
    ∀ {l : List (Sigma β)}, b ∈ lookupAll a l ↔ Sigma.mk a b ∈ l
  | [] => by simp
  | ⟨a', b'⟩ :: l => by
    

Proof state:
α : 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

Next tactic:
by_cases h : a = a'
theorem mem_lookupAll {a : α} {b : β a} :
    ∀ {l : List (Sigma β)}, b ∈ lookupAll a l ↔ Sigma.mk a b ∈ l
  | [] => by simp
  | ⟨a', b'⟩ :: l => by
    by_cases h : a = a'
    · 

Proof state:
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

Next tactic:
subst h
theorem mem_lookupAll {a : α} {b : β a} :
    ∀ {l : List (Sigma β)}, b ∈ lookupAll a l ↔ Sigma.mk a b ∈ l
  | [] => by simp
  | ⟨a', b'⟩ :: l => by
    by_cases h : a = a'
    · subst h
      

Proof state:
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

Next tactic:
simp [*, mem_lookupAll]
theorem mem_lookupAll {a : α} {b : β a} :
    ∀ {l : List (Sigma β)}, b ∈ lookupAll a l ↔ Sigma.mk a b ∈ l
  | [] => by simp
  | ⟨a', b'⟩ :: l => by
    by_cases h : a = a'
    · subst h
      simp [*, mem_lookupAll]
    · 

Proof state:
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

Next tactic:
simp [*, mem_lookupAll]
theorem lookupAll_sublist (a : α) : ∀ l : List (Sigma β), (lookupAll a l).map (Sigma.mk a) <+ l
  | [] => by 

Proof state:
α : Type u
β : α → Type v
l l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
⊢ map (Sigma.mk a) (lookupAll a []) <+ []

Next tactic:
simp
theorem lookupAll_sublist (a : α) : ∀ l : List (Sigma β), (lookupAll a l).map (Sigma.mk a) <+ l
  | [] => by simp
  | ⟨a', b'⟩ :: l => by
    

Proof state:
α : 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

Next tactic:
by_cases h : a = a'
theorem lookupAll_sublist (a : α) : ∀ l : List (Sigma β), (lookupAll a l).map (Sigma.mk a) <+ l
  | [] => by simp
  | ⟨a', b'⟩ :: l => by
    by_cases h : a = a'
    · 

Proof state:
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

Next tactic:
subst h
theorem lookupAll_sublist (a : α) : ∀ l : List (Sigma β), (lookupAll a l).map (Sigma.mk a) <+ l
  | [] => by simp
  | ⟨a', b'⟩ :: l => by
    by_cases h : a = a'
    · subst h
      

Proof state:
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

Next tactic:
simp only [ne_eq, not_true, lookupAll_cons_eq, List.map]
theorem lookupAll_sublist (a : α) : ∀ l : List (Sigma β), (lookupAll a l).map (Sigma.mk a) <+ l
  | [] => by simp
  | ⟨a', b'⟩ :: l => by
    by_cases h : a = a'
    · subst h
      simp only [ne_eq, not_true, lookupAll_cons_eq, List.map]
      

Proof state:
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

Next tactic:
exact (lookupAll_sublist a l).cons₂ _
theorem lookupAll_sublist (a : α) : ∀ l : List (Sigma β), (lookupAll a l).map (Sigma.mk a) <+ l
  | [] => by simp
  | ⟨a', b'⟩ :: l => by
    by_cases h : a = a'
    · subst h
      simp only [ne_eq, not_true, lookupAll_cons_eq, List.map]
      exact (lookupAll_sublist a l).cons₂ _
    · 

Proof state:
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

Next tactic:
simp only [ne_eq, h, not_false_iff, lookupAll_cons_ne]
theorem lookupAll_sublist (a : α) : ∀ l : List (Sigma β), (lookupAll a l).map (Sigma.mk a) <+ l
  | [] => by simp
  | ⟨a', b'⟩ :: l => by
    by_cases h : a = a'
    · subst h
      simp only [ne_eq, not_true, lookupAll_cons_eq, List.map]
      exact (lookupAll_sublist a l).cons₂ _
    · simp only [ne_eq, h, not_false_iff, lookupAll_cons_ne]
      

Proof state:
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

Next tactic:
exact (lookupAll_sublist a l).cons _
theorem lookupAll_length_le_one (a : α) {l : List (Sigma β)} (h : l.NodupKeys) :
    length (lookupAll a l) ≤ 1 := by
  

Proof state:
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l : List (Sigma β)
h : NodupKeys l
⊢ length (lookupAll a l) ≤ 1

Next tactic:
have := Nodup.sublist ((lookupAll_sublist a l).map _) h
theorem lookupAll_length_le_one (a : α) {l : List (Sigma β)} (h : l.NodupKeys) :
    length (lookupAll a l) ≤ 1 := by
  have := Nodup.sublist ((lookupAll_sublist a l).map _) h
  

Proof state:
α : 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

Next tactic:
rw [map_map] at this
theorem lookupAll_length_le_one (a : α) {l : List (Sigma β)} (h : l.NodupKeys) :
    length (lookupAll a l) ≤ 1 := by
  have := Nodup.sublist ((lookupAll_sublist a l).map _) h
  rw [map_map] at this
  

Proof state:
α : 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

Next tactic:
rwa [← nodup_replicate, ← map_const]
theorem lookupAll_eq_dlookup (a : α) {l : List (Sigma β)} (h : l.NodupKeys) :
    lookupAll a l = (dlookup a l).toList := by
  

Proof state:
α : 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)

Next tactic:
rw [← head?_lookupAll]
theorem lookupAll_eq_dlookup (a : α) {l : List (Sigma β)} (h : l.NodupKeys) :
    lookupAll a l = (dlookup a l).toList := by
  rw [← head?_lookupAll]
  

Proof state:
α : 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))

Next tactic:
have h1 := lookupAll_length_le_one a h
theorem lookupAll_eq_dlookup (a : α) {l : List (Sigma β)} (h : l.NodupKeys) :
    lookupAll a l = (dlookup a l).toList := by
  rw [← head?_lookupAll]
  have h1 := lookupAll_length_le_one a h; 

Proof state:
α : 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))

Next tactic:
revert h1
theorem lookupAll_eq_dlookup (a : α) {l : List (Sigma β)} (h : l.NodupKeys) :
    lookupAll a l = (dlookup a l).toList := by
  rw [← head?_lookupAll]
  have h1 := lookupAll_length_le_one a h; revert h1
  

Proof state:
α : 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))

Next tactic:
rcases lookupAll a l with (_ | ⟨b, _ | ⟨c, l⟩⟩)
theorem lookupAll_eq_dlookup (a : α) {l : List (Sigma β)} (h : l.NodupKeys) :
    lookupAll a l = (dlookup a l).toList := by
  rw [← head?_lookupAll]
  have h1 := lookupAll_length_le_one a h; revert h1
  rcases lookupAll a l with (_ | ⟨b, _ | ⟨c, l⟩⟩) <;> 

Proof state:
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? [])

Next tactic:
intro h1
theorem lookupAll_eq_dlookup (a : α) {l : List (Sigma β)} (h : l.NodupKeys) :
    lookupAll a l = (dlookup a l).toList := by
  rw [← head?_lookupAll]
  have h1 := lookupAll_length_le_one a h; revert h1
  rcases lookupAll a l with (_ | ⟨b, _ | ⟨c, l⟩⟩) <;> 

Proof state:
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])

Next tactic:
intro h1
theorem lookupAll_eq_dlookup (a : α) {l : List (Sigma β)} (h : l.NodupKeys) :
    lookupAll a l = (dlookup a l).toList := by
  rw [← head?_lookupAll]
  have h1 := lookupAll_length_le_one a h; revert h1
  rcases lookupAll a l with (_ | ⟨b, _ | ⟨c, l⟩⟩) <;> 

Proof state:
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))

Next tactic:
intro h1
theorem lookupAll_eq_dlookup (a : α) {l : List (Sigma β)} (h : l.NodupKeys) :
    lookupAll a l = (dlookup a l).toList := by
  rw [← head?_lookupAll]
  have h1 := lookupAll_length_le_one a h; revert h1
  rcases lookupAll a l with (_ | ⟨b, _ | ⟨c, l⟩⟩) <;> intro h1 <;> 

Proof state:
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? [])

Next tactic:
try rfl
theorem lookupAll_eq_dlookup (a : α) {l : List (Sigma β)} (h : l.NodupKeys) :
    lookupAll a l = (dlookup a l).toList := by
  rw [← head?_lookupAll]
  have h1 := lookupAll_length_le_one a h; revert h1
  rcases lookupAll a l with (_ | ⟨b, _ | ⟨c, l⟩⟩) <;> intro h1 <;> try 

Proof state:
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? [])

Next tactic:
rfl
theorem lookupAll_eq_dlookup (a : α) {l : List (Sigma β)} (h : l.NodupKeys) :
    lookupAll a l = (dlookup a l).toList := by
  rw [← head?_lookupAll]
  have h1 := lookupAll_length_le_one a h; revert h1
  rcases lookupAll a l with (_ | ⟨b, _ | ⟨c, l⟩⟩) <;> intro h1 <;> 

Proof state:
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])

Next tactic:
try rfl
theorem lookupAll_eq_dlookup (a : α) {l : List (Sigma β)} (h : l.NodupKeys) :
    lookupAll a l = (dlookup a l).toList := by
  rw [← head?_lookupAll]
  have h1 := lookupAll_length_le_one a h; revert h1
  rcases lookupAll a l with (_ | ⟨b, _ | ⟨c, l⟩⟩) <;> intro h1 <;> try 

Proof state:
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])

Next tactic:
rfl
theorem lookupAll_eq_dlookup (a : α) {l : List (Sigma β)} (h : l.NodupKeys) :
    lookupAll a l = (dlookup a l).toList := by
  rw [← head?_lookupAll]
  have h1 := lookupAll_length_le_one a h; revert h1
  rcases lookupAll a l with (_ | ⟨b, _ | ⟨c, l⟩⟩) <;> intro h1 <;> 

Proof state:
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))

Next tactic:
try rfl
theorem lookupAll_eq_dlookup (a : α) {l : List (Sigma β)} (h : l.NodupKeys) :
    lookupAll a l = (dlookup a l).toList := by
  rw [← head?_lookupAll]
  have h1 := lookupAll_length_le_one a h; revert h1
  rcases lookupAll a l with (_ | ⟨b, _ | ⟨c, l⟩⟩) <;> intro h1 <;> try 

Proof state:
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))

Next tactic:
rfl
theorem lookupAll_eq_dlookup (a : α) {l : List (Sigma β)} (h : l.NodupKeys) :
    lookupAll a l = (dlookup a l).toList := by
  rw [← head?_lookupAll]
  have h1 := lookupAll_length_le_one a h; revert h1
  rcases lookupAll a l with (_ | ⟨b, _ | ⟨c, l⟩⟩) <;> intro h1 <;> try rfl
  

Proof state:
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))

Next tactic:
exact absurd h1 (by simp)
theorem lookupAll_eq_dlookup (a : α) {l : List (Sigma β)} (h : l.NodupKeys) :
    lookupAll a l = (dlookup a l).toList := by
  rw [← head?_lookupAll]
  have h1 := lookupAll_length_le_one a h; revert h1
  rcases lookupAll a l with (_ | ⟨b, _ | ⟨c, l⟩⟩) <;> intro h1 <;> try rfl
  exact absurd h1 (by 

Proof state:
α : 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

Next tactic:
simp
theorem lookupAll_nodup (a : α) {l : List (Sigma β)} (h : l.NodupKeys) : (lookupAll a l).Nodup :=
  by (

Proof state:
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l : List (Sigma β)
h : NodupKeys l
⊢ Nodup (lookupAll a l)

Next tactic:
rw [lookupAll_eq_dlookup a h]
theorem lookupAll_nodup (a : α) {l : List (Sigma β)} (h : l.NodupKeys) : (lookupAll a l).Nodup :=
  by (rw [lookupAll_eq_dlookup a h]; 

Proof state:
α : Type u
β : α → Type v
l✝ l₁ l₂ : List (Sigma β)
inst✝ : DecidableEq α
a : α
l : List (Sigma β)
h : NodupKeys l
⊢ Nodup (Option.toList (dlookup a l))

Next tactic:
apply Option.toList_nodup
theorem perm_lookupAll (a : α) {l₁ l₂ : List (Sigma β)} (nd₁ : l₁.NodupKeys) (nd₂ : l₂.NodupKeys)
    (p : l₁ ~ l₂) : lookupAll a l₁ = lookupAll a l₂ := by
  

Proof state:
α : 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₂

Next tactic:
simp [lookupAll_eq_dlookup, nd₁, nd₂, perm_dlookup a nd₁ nd₂ p]
theorem kreplace_of_forall_not (a : α) (b : β a) {l : List (Sigma β)}
    (H : ∀ b : β a, Sigma.mk a b ∉ l) : kreplace a b l = l :=
  lookmap_of_forall_not _ <| by
    

Proof state:
α : 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 ∈ l, (if a = a_1.fst then some { fst := a, snd := b } else none) = none

Next tactic:
rintro ⟨a', b'⟩ h
theorem kreplace_of_forall_not (a : α) (b : β a) {l : List (Sigma β)}
    (H : ∀ b : β a, Sigma.mk a b ∉ l) : kreplace a b l = l :=
  lookmap_of_forall_not _ <| by
    rintro ⟨a', b'⟩ h; 

Proof state:
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

Next tactic:
dsimp
theorem kreplace_of_forall_not (a : α) (b : β a) {l : List (Sigma β)}
    (H : ∀ b : β a, Sigma.mk a b ∉ l) : kreplace a b l = l :=
  lookmap_of_forall_not _ <| by
    rintro ⟨a', b'⟩ h; dsimp; 

Proof state:
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

Next tactic:
split_ifs
theorem kreplace_of_forall_not (a : α) (b : β a) {l : List (Sigma β)}
    (H : ∀ b : β a, Sigma.mk a b ∉ l) : kreplace a b l = l :=
  lookmap_of_forall_not _ <| by
    rintro ⟨a', b'⟩ h; dsimp; split_ifs
    · 

Proof state:
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

Next tactic:
subst a'
theorem kreplace_of_forall_not (a : α) (b : β a) {l : List (Sigma β)}
    (H : ∀ b : β a, Sigma.mk a b ∉ l) : kreplace a b l = l :=
  lookmap_of_forall_not _ <| by
    rintro ⟨a', b'⟩ h; dsimp; split_ifs
    · subst a'
      

Proof state:
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

Next tactic:
exact H _ h
theorem kreplace_of_forall_not (a : α) (b : β a) {l : List (Sigma β)}
    (H : ∀ b : β a, Sigma.mk a b ∉ l) : kreplace a b l = l :=
  lookmap_of_forall_not _ <| by
    rintro ⟨a', b'⟩ h; dsimp; split_ifs
    · subst a'
      exact H _ h
    · 

Proof state:
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

Next tactic:
rfl
theorem kreplace_self {a : α} {b : β a} {l : List (Sigma β)} (nd : NodupKeys l)
    (h : Sigma.mk a b ∈ l) : kreplace a b l = l := by
  

Proof state:
α : 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

Next tactic:
refine' (lookmap_congr _).trans (lookmap_id' (Option.guard fun (s : Sigma β) => a = s.1) _ _)
theorem kreplace_self {a : α} {b : β a} {l : List (Sigma β)} (nd : NodupKeys l)
    (h : Sigma.mk a b ∈ l) : kreplace a b l = l := by
  refine' (lookmap_congr _).trans (lookmap_id' (Option.guard fun (s : Sigma β) => a = s.1) _ _)
  · 

Proof state:
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 ∈ l, (if a = a_1.fst then some { fst := a, snd := b } else none) = Option.guard (fun s => a = s.fst) a_1

Next tactic:
rintro ⟨a', b'⟩ h'
theorem kreplace_self {a : α} {b : β a} {l : List (Sigma β)} (nd : NodupKeys l)
    (h : Sigma.mk a b ∈ l) : kreplace a b l = l := by
  refine' (lookmap_congr _).trans (lookmap_id' (Option.guard fun (s : Sigma β) => a = s.1) _ _)
  · rintro ⟨a', b'⟩ h'
    

Proof state:
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' }

Next tactic:
dsimp [Option.guard]
theorem kreplace_self {a : α} {b : β a} {l : List (Sigma β)} (nd : NodupKeys l)
    (h : Sigma.mk a b ∈ l) : kreplace a b l = l := by
  refine' (lookmap_congr _).trans (lookmap_id' (Option.guard fun (s : Sigma β) => a = s.1) _ _)
  · rintro ⟨a', b'⟩ h'
    dsimp [Option.guard]
    

Proof state:
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

Next tactic:
split_ifs
theorem kreplace_self {a : α} {b : β a} {l : List (Sigma β)} (nd : NodupKeys l)
    (h : Sigma.mk a b ∈ l) : kreplace a b l = l := by
  refine' (lookmap_congr _).trans (lookmap_id' (Option.guard fun (s : Sigma β) => a = s.1) _ _)
  · rintro ⟨a', b'⟩ h'
    dsimp [Option.guard]
    split_ifs
    · 

Proof state:
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' }

Next tactic:
subst a'
theorem kreplace_self {a : α} {b : β a} {l : List (Sigma β)} (nd : NodupKeys l)
    (h : Sigma.mk a b ∈ l) : kreplace a b l = l := by
  refine' (lookmap_congr _).trans (lookmap_id' (Option.guard fun (s : Sigma β) => a = s.1) _ _)
  · rintro ⟨a', b'⟩ h'
    dsimp [Option.guard]
    split_ifs
    · subst a'
      

Proof state:
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' }

Next tactic:
simp [nd.eq_of_mk_mem h h']
theorem kreplace_self {a : α} {b : β a} {l : List (Sigma β)} (nd : NodupKeys l)
    (h : Sigma.mk a b ∈ l) : kreplace a b l = l := by
  refine' (lookmap_congr _).trans (lookmap_id' (Option.guard fun (s : Sigma β) => a = s.1) _ _)
  · rintro ⟨a', b'⟩ h'
    dsimp [Option.guard]
    split_ifs
    · subst a'
      simp [nd.eq_of_mk_mem h h']
    · 

Proof state:
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

Next tactic:
rfl
theorem kreplace_self {a : α} {b : β a} {l : List (Sigma β)} (nd : NodupKeys l)
    (h : Sigma.mk a b ∈ l) : kreplace a b l = l := by
  refine' (lookmap_congr _).trans (lookmap_id' (Option.guard fun (s : Sigma β) => a = s.1) _ _)
  · rintro ⟨a', b'⟩ h'
    dsimp [Option.guard]
    split_ifs
    · subst a'
      simp [nd.eq_of_mk_mem h h']
    · rfl
  · 

Proof state:
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

Next tactic:
rintro ⟨a₁, b₁⟩ ⟨a₂, b₂⟩