l3lab/ntp-mathlib huggingface dataset:
/-- Summing the count of `x` over a list filtered by some `p` is just `countP` applied to `p` -/
theorem sum_map_count_dedup_filter_eq_countP (p : α → Bool) (l : List α) :
    ((l.dedup.filter p).map fun x => l.count x).sum = l.countP p := by
  induction' l with a as h
  · simp
  · simp_rw [List.countP_cons, List.count_cons, List.sum_map_add]
    congr 1
    · refine' _root_.trans _ h
      by_cases ha : a ∈ as
      · simp [dedup_cons_of_mem ha]
      · simp only [dedup_cons_of_not_mem ha, List.filter]
        match p a with
        | true => simp only [List.map_cons, List.sum_cons, List.count_eq_zero.2 ha, zero_add]
        | false => simp only
    · by_cases hp : p a
      · refine' _root_.trans (sum_map_eq_nsmul_single a _ fun _ h _ => by simp [h]) _
        simp [hp, count_dedup]
      · refine' _root_.trans (List.sum_eq_zero fun n hn => _) (by simp [hp])
        

Proof state:
case neg
α : Type u
inst✝ : DecidableEq α
p : α → Bool
a : α
as : List α
h : sum (map (fun x => count x as) (filter p (dedup as))) = countP p as
hp : ¬p a = true
n : ℕ
hn : n ∈ map (fun i => if i = a then 1 else 0) (filter p (dedup (a :: as)))
⊢ n = 0

Next tactic:
obtain ⟨a', ha'⟩ := List.mem_map.1 hn
/-- Summing the count of `x` over a list filtered by some `p` is just `countP` applied to `p` -/
theorem sum_map_count_dedup_filter_eq_countP (p : α → Bool) (l : List α) :
    ((l.dedup.filter p).map fun x => l.count x).sum = l.countP p := by
  induction' l with a as h
  · simp
  · simp_rw [List.countP_cons, List.count_cons, List.sum_map_add]
    congr 1
    · refine' _root_.trans _ h
      by_cases ha : a ∈ as
      · simp [dedup_cons_of_mem ha]
      · simp only [dedup_cons_of_not_mem ha, List.filter]
        match p a with
        | true => simp only [List.map_cons, List.sum_cons, List.count_eq_zero.2 ha, zero_add]
        | false => simp only
    · by_cases hp : p a
      · refine' _root_.trans (sum_map_eq_nsmul_single a _ fun _ h _ => by simp [h]) _
        simp [hp, count_dedup]
      · refine' _root_.trans (List.sum_eq_zero fun n hn => _) (by simp [hp])
        obtain ⟨a', ha'⟩ := List.mem_map.1 hn
        

Proof state:
case neg.intro
α : Type u
inst✝ : DecidableEq α
p : α → Bool
a : α
as : List α
h : sum (map (fun x => count x as) (filter p (dedup as))) = countP p as
hp : ¬p a = true
n : ℕ
hn : n ∈ map (fun i => if i = a then 1 else 0) (filter p (dedup (a :: as)))
a' : α
ha' : a' ∈ filter p (dedup (a :: as)) ∧ (if a' = a then 1 else 0) = n
⊢ n = 0

Next tactic:
split_ifs at ha' with ha
/-- Summing the count of `x` over a list filtered by some `p` is just `countP` applied to `p` -/
theorem sum_map_count_dedup_filter_eq_countP (p : α → Bool) (l : List α) :
    ((l.dedup.filter p).map fun x => l.count x).sum = l.countP p := by
  induction' l with a as h
  · simp
  · simp_rw [List.countP_cons, List.count_cons, List.sum_map_add]
    congr 1
    · refine' _root_.trans _ h
      by_cases ha : a ∈ as
      · simp [dedup_cons_of_mem ha]
      · simp only [dedup_cons_of_not_mem ha, List.filter]
        match p a with
        | true => simp only [List.map_cons, List.sum_cons, List.count_eq_zero.2 ha, zero_add]
        | false => simp only
    · by_cases hp : p a
      · refine' _root_.trans (sum_map_eq_nsmul_single a _ fun _ h _ => by simp [h]) _
        simp [hp, count_dedup]
      · refine' _root_.trans (List.sum_eq_zero fun n hn => _) (by simp [hp])
        obtain ⟨a', ha'⟩ := List.mem_map.1 hn
        split_ifs at ha' with ha
        · 

Proof state:
case pos
α : Type u
inst✝ : DecidableEq α
p : α → Bool
a : α
as : List α
h : sum (map (fun x => count x as) (filter p (dedup as))) = countP p as
hp : ¬p a = true
n : ℕ
hn : n ∈ map (fun i => if i = a then 1 else 0) (filter p (dedup (a :: as)))
a' : α
ha : a' = a
ha' : a' ∈ filter p (dedup (a :: as)) ∧ 1 = n
⊢ n = 0

Next tactic:
simp only [ha, mem_filter, mem_dedup, find?, mem_cons, true_or, hp,
            and_false, false_and] at ha'
/-- Summing the count of `x` over a list filtered by some `p` is just `countP` applied to `p` -/
theorem sum_map_count_dedup_filter_eq_countP (p : α → Bool) (l : List α) :
    ((l.dedup.filter p).map fun x => l.count x).sum = l.countP p := by
  induction' l with a as h
  · simp
  · simp_rw [List.countP_cons, List.count_cons, List.sum_map_add]
    congr 1
    · refine' _root_.trans _ h
      by_cases ha : a ∈ as
      · simp [dedup_cons_of_mem ha]
      · simp only [dedup_cons_of_not_mem ha, List.filter]
        match p a with
        | true => simp only [List.map_cons, List.sum_cons, List.count_eq_zero.2 ha, zero_add]
        | false => simp only
    · by_cases hp : p a
      · refine' _root_.trans (sum_map_eq_nsmul_single a _ fun _ h _ => by simp [h]) _
        simp [hp, count_dedup]
      · refine' _root_.trans (List.sum_eq_zero fun n hn => _) (by simp [hp])
        obtain ⟨a', ha'⟩ := List.mem_map.1 hn
        split_ifs at ha' with ha
        · simp only [ha, mem_filter, mem_dedup, find?, mem_cons, true_or, hp,
            and_false, false_and] at ha'
        · 

Proof state:
case neg
α : Type u
inst✝ : DecidableEq α
p : α → Bool
a : α
as : List α
h : sum (map (fun x => count x as) (filter p (dedup as))) = countP p as
hp : ¬p a = true
n : ℕ
hn : n ∈ map (fun i => if i = a then 1 else 0) (filter p (dedup (a :: as)))
a' : α
ha : ¬a' = a
ha' : a' ∈ filter p (dedup (a :: as)) ∧ 0 = n
⊢ n = 0

Next tactic:
exact ha'.2.symm
theorem sum_map_count_dedup_eq_length (l : List α) :
    (l.dedup.map fun x => l.count x).sum = l.length := by
  

Proof state:
α : Type u
inst✝ : DecidableEq α
l : List α
⊢ sum (map (fun x => count x l) (dedup l)) = length l

Next tactic:
simpa using sum_map_count_dedup_filter_eq_countP (fun _ => True) l
theorem mem_antidiagonalTuple {n : ℕ} {k : ℕ} {x : Fin k → ℕ} :
    x ∈ antidiagonalTuple k n ↔ ∑ i, x i = n := by
  

Proof state:
n k : ℕ
x : Fin k → ℕ
⊢ x ∈ antidiagonalTuple k n ↔ ∑ i : Fin k, x i = n

Next tactic:
induction x using Fin.consInduction generalizing n with
  | h0 =>
    cases n
    · decide
    · simp [eq_comm]
  | h x₀ x ih =>
    simp_rw [Fin.sum_cons]
    rw [antidiagonalTuple]  -- porting note: simp_rw doesn't use the equation lemma properly
    simp_rw [List.mem_bind, List.mem_map,
      List.Nat.mem_antidiagonal, Fin.cons_eq_cons, exists_eq_right_right, ih,
      @eq_comm _ _ (Prod.snd _), and_comm (a := Prod.snd _ = _),
      ← Prod.mk.inj_iff (a₁ := Prod.fst _), exists_eq_right]
theorem mem_antidiagonalTuple {n : ℕ} {k : ℕ} {x : Fin k → ℕ} :
    x ∈ antidiagonalTuple k n ↔ ∑ i, x i = n := by
  induction x using Fin.consInduction generalizing n with
  

Proof state:
case h0
k n : ℕ
⊢ Fin.elim0 ∈ antidiagonalTuple 0 n ↔ ∑ i : Fin 0, Fin.elim0 i = n

Next tactic:
| h0 =>
    cases n
    · decide
    · simp [eq_comm]
theorem mem_antidiagonalTuple {n : ℕ} {k : ℕ} {x : Fin k → ℕ} :
    x ∈ antidiagonalTuple k n ↔ ∑ i, x i = n := by
  induction x using Fin.consInduction generalizing n with
  | h0 =>
    

Proof state:
case h0
k n : ℕ
⊢ Fin.elim0 ∈ antidiagonalTuple 0 n ↔ ∑ i : Fin 0, Fin.elim0 i = n

Next tactic:
cases n
theorem mem_antidiagonalTuple {n : ℕ} {k : ℕ} {x : Fin k → ℕ} :
    x ∈ antidiagonalTuple k n ↔ ∑ i, x i = n := by
  induction x using Fin.consInduction generalizing n with
  | h0 =>
    cases n
    · 

Proof state:
case h0.zero
k : ℕ
⊢ Fin.elim0 ∈ antidiagonalTuple 0 Nat.zero ↔ ∑ i : Fin 0, Fin.elim0 i = Nat.zero

Next tactic:
decide
theorem mem_antidiagonalTuple {n : ℕ} {k : ℕ} {x : Fin k → ℕ} :
    x ∈ antidiagonalTuple k n ↔ ∑ i, x i = n := by
  induction x using Fin.consInduction generalizing n with
  | h0 =>
    cases n
    · decide
    · 

Proof state:
case h0.succ
k n✝ : ℕ
⊢ Fin.elim0 ∈ antidiagonalTuple 0 (Nat.succ n✝) ↔ ∑ i : Fin 0, Fin.elim0 i = Nat.succ n✝

Next tactic:
simp [eq_comm]
theorem mem_antidiagonalTuple {n : ℕ} {k : ℕ} {x : Fin k → ℕ} :
    x ∈ antidiagonalTuple k n ↔ ∑ i, x i = n := by
  induction x using Fin.consInduction generalizing n with
  | h0 =>
    cases n
    · decide
    · simp [eq_comm]
  

Proof state:
case h
k n✝ x₀ : ℕ
x : Fin n✝ → ℕ
ih : ∀ {n : ℕ}, x ∈ antidiagonalTuple n✝ n ↔ ∑ i : Fin n✝, x i = n
n : ℕ
⊢ Fin.cons x₀ x ∈ antidiagonalTuple (n✝ + 1) n ↔ ∑ i : Fin (n✝ + 1), Fin.cons x₀ x i = n

Next tactic:
| h x₀ x ih =>
    simp_rw [Fin.sum_cons]
    rw [antidiagonalTuple]  -- porting note: simp_rw doesn't use the equation lemma properly
    simp_rw [List.mem_bind, List.mem_map,
      List.Nat.mem_antidiagonal, Fin.cons_eq_cons, exists_eq_right_right, ih,
      @eq_comm _ _ (Prod.snd _), and_comm (a := Prod.snd _ = _),
      ← Prod.mk.inj_iff (a₁ := Prod.fst _), exists_eq_right]
theorem mem_antidiagonalTuple {n : ℕ} {k : ℕ} {x : Fin k → ℕ} :
    x ∈ antidiagonalTuple k n ↔ ∑ i, x i = n := by
  induction x using Fin.consInduction generalizing n with
  | h0 =>
    cases n
    · decide
    · simp [eq_comm]
  | h x₀ x ih =>
    

Proof state:
case h
k n✝ x₀ : ℕ
x : Fin n✝ → ℕ
ih : ∀ {n : ℕ}, x ∈ antidiagonalTuple n✝ n ↔ ∑ i : Fin n✝, x i = n
n : ℕ
⊢ Fin.cons x₀ x ∈ antidiagonalTuple (n✝ + 1) n ↔ ∑ i : Fin (n✝ + 1), Fin.cons x₀ x i = n

Next tactic:
simp_rw [Fin.sum_cons]
theorem mem_antidiagonalTuple {n : ℕ} {k : ℕ} {x : Fin k → ℕ} :
    x ∈ antidiagonalTuple k n ↔ ∑ i, x i = n := by
  induction x using Fin.consInduction generalizing n with
  | h0 =>
    cases n
    · decide
    · simp [eq_comm]
  | h x₀ x ih =>
    simp_rw [Fin.sum_cons]
    

Proof state:
case h
k n✝ x₀ : ℕ
x : Fin n✝ → ℕ
ih : ∀ {n : ℕ}, x ∈ antidiagonalTuple n✝ n ↔ ∑ i : Fin n✝, x i = n
n : ℕ
⊢ Fin.cons x₀ x ∈ antidiagonalTuple (n✝ + 1) n ↔ x₀ + ∑ i : Fin n✝, x i = n

Next tactic:
rw [antidiagonalTuple]
theorem mem_antidiagonalTuple {n : ℕ} {k : ℕ} {x : Fin k → ℕ} :
    x ∈ antidiagonalTuple k n ↔ ∑ i, x i = n := by
  induction x using Fin.consInduction generalizing n with
  | h0 =>
    cases n
    · decide
    · simp [eq_comm]
  | h x₀ x ih =>
    simp_rw [Fin.sum_cons]
    rw [antidiagonalTuple]  -- porting note: simp_rw doesn't use the equation lemma properly
    

Proof state:
case h
k n✝ x₀ : ℕ
x : Fin n✝ → ℕ
ih : ∀ {n : ℕ}, x ∈ antidiagonalTuple n✝ n ↔ ∑ i : Fin n✝, x i = n
n : ℕ
⊢ (Fin.cons x₀ x ∈ List.bind (antidiagonal n) fun ni => map (fun x => Fin.cons ni.1 x) (antidiagonalTuple n✝ ni.2)) ↔
    x₀ + ∑ i : Fin n✝, x i = n

Next tactic:
simp_rw [List.mem_bind, List.mem_map,
      List.Nat.mem_antidiagonal, Fin.cons_eq_cons, exists_eq_right_right, ih,
      @eq_comm _ _ (Prod.snd _), and_comm (a := Prod.snd _ = _),
      ← Prod.mk.inj_iff (a₁ := Prod.fst _), exists_eq_right]
/-- The antidiagonal of `n` does not contain duplicate entries. -/
theorem nodup_antidiagonalTuple (k n : ℕ) : List.Nodup (antidiagonalTuple k n) := by
  

Proof state:
k n : ℕ
⊢ Nodup (antidiagonalTuple k n)

Next tactic:
induction' k with k ih generalizing n
/-- The antidiagonal of `n` does not contain duplicate entries. -/
theorem nodup_antidiagonalTuple (k n : ℕ) : List.Nodup (antidiagonalTuple k n) := by
  induction' k with k ih generalizing n
  · 

Proof state:
case zero
n : ℕ
⊢ Nodup (antidiagonalTuple Nat.zero n)

Next tactic:
cases n
/-- The antidiagonal of `n` does not contain duplicate entries. -/
theorem nodup_antidiagonalTuple (k n : ℕ) : List.Nodup (antidiagonalTuple k n) := by
  induction' k with k ih generalizing n
  · cases n
    · 

Proof state:
case zero.zero
⊢ Nodup (antidiagonalTuple Nat.zero Nat.zero)

Next tactic:
simp
/-- The antidiagonal of `n` does not contain duplicate entries. -/
theorem nodup_antidiagonalTuple (k n : ℕ) : List.Nodup (antidiagonalTuple k n) := by
  induction' k with k ih generalizing n
  · cases n
    · simp
    · 

Proof state:
case zero.succ
n✝ : ℕ
⊢ Nodup (antidiagonalTuple Nat.zero (Nat.succ n✝))

Next tactic:
simp [eq_comm]
/-- The antidiagonal of `n` does not contain duplicate entries. -/
theorem nodup_antidiagonalTuple (k n : ℕ) : List.Nodup (antidiagonalTuple k n) := by
  induction' k with k ih generalizing n
  · cases n
    · simp
    · simp [eq_comm]
  

Proof state:
case succ
k : ℕ
ih : ∀ (n : ℕ), Nodup (antidiagonalTuple k n)
n : ℕ
⊢ Nodup (antidiagonalTuple (Nat.succ k) n)

Next tactic:
simp_rw [antidiagonalTuple, List.nodup_bind]
/-- The antidiagonal of `n` does not contain duplicate entries. -/
theorem nodup_antidiagonalTuple (k n : ℕ) : List.Nodup (antidiagonalTuple k n) := by
  induction' k with k ih generalizing n
  · cases n
    · simp
    · simp [eq_comm]
  simp_rw [antidiagonalTuple, List.nodup_bind]
  

Proof state:
case succ
k : ℕ
ih : ∀ (n : ℕ), Nodup (antidiagonalTuple k n)
n : ℕ
⊢ (∀ x ∈ antidiagonal n, Nodup (map (fun x_1 => Fin.cons x.1 x_1) (antidiagonalTuple k x.2))) ∧
    Pairwise
      (fun a b =>
        Disjoint (map (fun x => Fin.cons a.1 x) (antidiagonalTuple k a.2))
          (map (fun x => Fin.cons b.1 x) (antidiagonalTuple k b.2)))
      (antidiagonal n)

Next tactic:
constructor
/-- The antidiagonal of `n` does not contain duplicate entries. -/
theorem nodup_antidiagonalTuple (k n : ℕ) : List.Nodup (antidiagonalTuple k n) := by
  induction' k with k ih generalizing n
  · cases n
    · simp
    · simp [eq_comm]
  simp_rw [antidiagonalTuple, List.nodup_bind]
  constructor
  · 

Proof state:
case succ.left
k : ℕ
ih : ∀ (n : ℕ), Nodup (antidiagonalTuple k n)
n : ℕ
⊢ ∀ x ∈ antidiagonal n, Nodup (map (fun x_1 => Fin.cons x.1 x_1) (antidiagonalTuple k x.2))

Next tactic:
intro i _
/-- The antidiagonal of `n` does not contain duplicate entries. -/
theorem nodup_antidiagonalTuple (k n : ℕ) : List.Nodup (antidiagonalTuple k n) := by
  induction' k with k ih generalizing n
  · cases n
    · simp
    · simp [eq_comm]
  simp_rw [antidiagonalTuple, List.nodup_bind]
  constructor
  · intro i _
    

Proof state:
case succ.left
k : ℕ
ih : ∀ (n : ℕ), Nodup (antidiagonalTuple k n)
n : ℕ
i : ℕ × ℕ
a✝ : i ∈ antidiagonal n
⊢ Nodup (map (fun x => Fin.cons i.1 x) (antidiagonalTuple k i.2))

Next tactic:
exact (ih i.snd).map (Fin.cons_right_injective (α := fun _ => ℕ) i.fst)
/-- The antidiagonal of `n` does not contain duplicate entries. -/
theorem nodup_antidiagonalTuple (k n : ℕ) : List.Nodup (antidiagonalTuple k n) := by
  induction' k with k ih generalizing n
  · cases n
    · simp
    · simp [eq_comm]
  simp_rw [antidiagonalTuple, List.nodup_bind]
  constructor
  · intro i _
    exact (ih i.snd).map (Fin.cons_right_injective (α := fun _ => ℕ) i.fst)
  

Proof state:
case succ.right
k : ℕ
ih : ∀ (n : ℕ), Nodup (antidiagonalTuple k n)
n : ℕ
⊢ Pairwise
    (fun a b =>
      Disjoint (map (fun x => Fin.cons a.1 x) (antidiagonalTuple k a.2))
        (map (fun x => Fin.cons b.1 x) (antidiagonalTuple k b.2)))
    (antidiagonal n)

Next tactic:
induction' n with n n_ih
/-- The antidiagonal of `n` does not contain duplicate entries. -/
theorem nodup_antidiagonalTuple (k n : ℕ) : List.Nodup (antidiagonalTuple k n) := by
  induction' k with k ih generalizing n
  · cases n
    · simp
    · simp [eq_comm]
  simp_rw [antidiagonalTuple, List.nodup_bind]
  constructor
  · intro i _
    exact (ih i.snd).map (Fin.cons_right_injective (α := fun _ => ℕ) i.fst)
  induction' n with n n_ih
  · 

Proof state:
case succ.right.zero
k : ℕ
ih : ∀ (n : ℕ), Nodup (antidiagonalTuple k n)
⊢ Pairwise
    (fun a b =>
      Disjoint (map (fun x => Fin.cons a.1 x) (antidiagonalTuple k a.2))
        (map (fun x => Fin.cons b.1 x) (antidiagonalTuple k b.2)))
    (antidiagonal Nat.zero)

Next tactic:
exact List.pairwise_singleton _ _
/-- The antidiagonal of `n` does not contain duplicate entries. -/
theorem nodup_antidiagonalTuple (k n : ℕ) : List.Nodup (antidiagonalTuple k n) := by
  induction' k with k ih generalizing n
  · cases n
    · simp
    · simp [eq_comm]
  simp_rw [antidiagonalTuple, List.nodup_bind]
  constructor
  · intro i _
    exact (ih i.snd).map (Fin.cons_right_injective (α := fun _ => ℕ) i.fst)
  induction' n with n n_ih
  · exact List.pairwise_singleton _ _
  · 

Proof state:
case succ.right.succ
k : ℕ
ih : ∀ (n : ℕ), Nodup (antidiagonalTuple k n)
n : ℕ
n_ih :
  Pairwise
    (fun a b =>
      Disjoint (map (fun x => Fin.cons a.1 x) (antidiagonalTuple k a.2))
        (map (fun x => Fin.cons b.1 x) (antidiagonalTuple k b.2)))
    (antidiagonal n)
⊢ Pairwise
    (fun a b =>
      Disjoint (map (fun x => Fin.cons a.1 x) (antidiagonalTuple k a.2))
        (map (fun x => Fin.cons b.1 x) (antidiagonalTuple k b.2)))
    (antidiagonal (Nat.succ n))

Next tactic:
rw [List.Nat.antidiagonal_succ]
/-- The antidiagonal of `n` does not contain duplicate entries. -/
theorem nodup_antidiagonalTuple (k n : ℕ) : List.Nodup (antidiagonalTuple k n) := by
  induction' k with k ih generalizing n
  · cases n
    · simp
    · simp [eq_comm]
  simp_rw [antidiagonalTuple, List.nodup_bind]
  constructor
  · intro i _
    exact (ih i.snd).map (Fin.cons_right_injective (α := fun _ => ℕ) i.fst)
  induction' n with n n_ih
  · exact List.pairwise_singleton _ _
  · rw [List.Nat.antidiagonal_succ]
    

Proof state:
case succ.right.succ
k : ℕ
ih : ∀ (n : ℕ), Nodup (antidiagonalTuple k n)
n : ℕ
n_ih :
  Pairwise
    (fun a b =>
      Disjoint (map (fun x => Fin.cons a.1 x) (antidiagonalTuple k a.2))
        (map (fun x => Fin.cons b.1 x) (antidiagonalTuple k b.2)))
    (antidiagonal n)
⊢ Pairwise
    (fun a b =>
      Disjoint (map (fun x => Fin.cons a.1 x) (antidiagonalTuple k a.2))
        (map (fun x => Fin.cons b.1 x) (antidiagonalTuple k b.2)))
    ((0, n + 1) :: map (Prod.map Nat.succ id) (antidiagonal n))

Next tactic:
refine' List.Pairwise.cons (fun a ha x hx₁ hx₂ => _) (n_ih.map _ fun a b h x hx₁ hx₂ => _)
/-- The antidiagonal of `n` does not contain duplicate entries. -/
theorem nodup_antidiagonalTuple (k n : ℕ) : List.Nodup (antidiagonalTuple k n) := by
  induction' k with k ih generalizing n
  · cases n
    · simp
    · simp [eq_comm]
  simp_rw [antidiagonalTuple, List.nodup_bind]
  constructor
  · intro i _
    exact (ih i.snd).map (Fin.cons_right_injective (α := fun _ => ℕ) i.fst)
  induction' n with n n_ih
  · exact List.pairwise_singleton _ _
  · rw [List.Nat.antidiagonal_succ]
    refine' List.Pairwise.cons (fun a ha x hx₁ hx₂ => _) (n_ih.map _ fun a b h x hx₁ hx₂ => _)
    · 

Proof state:
case succ.right.succ.refine'_1
k : ℕ
ih : ∀ (n : ℕ), Nodup (antidiagonalTuple k n)
n : ℕ
n_ih :
  Pairwise
    (fun a b =>
      Disjoint (map (fun x => Fin.cons a.1 x) (antidiagonalTuple k a.2))
        (map (fun x => Fin.cons b.1 x) (antidiagonalTuple k b.2)))
    (antidiagonal n)
a : ℕ × ℕ
ha : a ∈ map (Prod.map Nat.succ id) (antidiagonal n)
x : Fin (Nat.succ k) → ℕ
hx₁ : x ∈ map (fun x => Fin.cons (0, n + 1).1 x) (antidiagonalTuple k (0, n + 1).2)
hx₂ : x ∈ map (fun x => Fin.cons a.1 x) (antidiagonalTuple k a.2)
⊢ False

Next tactic:
rw [List.mem_map] at hx₁ hx₂ ha
/-- The antidiagonal of `n` does not contain duplicate entries. -/
theorem nodup_antidiagonalTuple (k n : ℕ) : List.Nodup (antidiagonalTuple k n) := by
  induction' k with k ih generalizing n
  · cases n
    · simp
    · simp [eq_comm]
  simp_rw [antidiagonalTuple, List.nodup_bind]
  constructor
  · intro i _
    exact (ih i.snd).map (Fin.cons_right_injective (α := fun _ => ℕ) i.fst)
  induction' n with n n_ih
  · exact List.pairwise_singleton _ _
  · rw [List.Nat.antidiagonal_succ]
    refine' List.Pairwise.cons (fun a ha x hx₁ hx₂ => _) (n_ih.map _ fun a b h x hx₁ hx₂ => _)
    · rw [List.mem_map] at hx₁ hx₂ ha
      

Proof state:
case succ.right.succ.refine'_1
k : ℕ
ih : ∀ (n : ℕ), Nodup (antidiagonalTuple k n)
n : ℕ
n_ih :
  Pairwise
    (fun a b =>
      Disjoint (map (fun x => Fin.cons a.1 x) (antidiagonalTuple k a.2))
        (map (fun x => Fin.cons b.1 x) (antidiagonalTuple k b.2)))
    (antidiagonal n)
a : ℕ × ℕ
ha : ∃ a_1 ∈ antidiagonal n, Prod.map Nat.succ id a_1 = a
x : Fin (Nat.succ k) → ℕ
hx₁ : ∃ a ∈ antidiagonalTuple k (0, n + 1).2, Fin.cons (0, n + 1).1 a = x
hx₂ : ∃ a_1 ∈ antidiagonalTuple k a.2, Fin.cons a.1 a_1 = x
⊢ False

Next tactic:
obtain ⟨⟨a, -, rfl⟩, ⟨x₁, -, rfl⟩, ⟨x₂, -, h⟩⟩ := ha, hx₁, hx₂
/-- The antidiagonal of `n` does not contain duplicate entries. -/
theorem nodup_antidiagonalTuple (k n : ℕ) : List.Nodup (antidiagonalTuple k n) := by
  induction' k with k ih generalizing n
  · cases n
    · simp
    · simp [eq_comm]
  simp_rw [antidiagonalTuple, List.nodup_bind]
  constructor
  · intro i _
    exact (ih i.snd).map (Fin.cons_right_injective (α := fun _ => ℕ) i.fst)
  induction' n with n n_ih
  · exact List.pairwise_singleton _ _
  · rw [List.Nat.antidiagonal_succ]
    refine' List.Pairwise.cons (fun a ha x hx₁ hx₂ => _) (n_ih.map _ fun a b h x hx₁ hx₂ => _)
    · rw [List.mem_map] at hx₁ hx₂ ha
      obtain ⟨⟨a, -, rfl⟩, ⟨x₁, -, rfl⟩, ⟨x₂, -, h⟩⟩ := ha, hx₁, hx₂
      

Proof state:
case succ.right.succ.refine'_1.intro.intro.intro.intro.intro.intro
k : ℕ
ih : ∀ (n : ℕ), Nodup (antidiagonalTuple k n)
n : ℕ
n_ih :
  Pairwise
    (fun a b =>
      Disjoint (map (fun x => Fin.cons a.1 x) (antidiagonalTuple k a.2))
        (map (fun x => Fin.cons b.1 x) (antidiagonalTuple k b.2)))
    (antidiagonal n)
a : ℕ × ℕ
x₁ x₂ : Fin k → ℕ
h : Fin.cons (Prod.map Nat.succ id a).1 x₂ = Fin.cons (0, n + 1).1 x₁
⊢ False

Next tactic:
rw [Fin.cons_eq_cons] at h
/-- The antidiagonal of `n` does not contain duplicate entries. -/
theorem nodup_antidiagonalTuple (k n : ℕ) : List.Nodup (antidiagonalTuple k n) := by
  induction' k with k ih generalizing n
  · cases n
    · simp
    · simp [eq_comm]
  simp_rw [antidiagonalTuple, List.nodup_bind]
  constructor
  · intro i _
    exact (ih i.snd).map (Fin.cons_right_injective (α := fun _ => ℕ) i.fst)
  induction' n with n n_ih
  · exact List.pairwise_singleton _ _
  · rw [List.Nat.antidiagonal_succ]
    refine' List.Pairwise.cons (fun a ha x hx₁ hx₂ => _) (n_ih.map _ fun a b h x hx₁ hx₂ => _)
    · rw [List.mem_map] at hx₁ hx₂ ha
      obtain ⟨⟨a, -, rfl⟩, ⟨x₁, -, rfl⟩, ⟨x₂, -, h⟩⟩ := ha, hx₁, hx₂
      rw [Fin.cons_eq_cons] at h
      

Proof state:
case succ.right.succ.refine'_1.intro.intro.intro.intro.intro.intro
k : ℕ
ih : ∀ (n : ℕ), Nodup (antidiagonalTuple k n)
n : ℕ
n_ih :
  Pairwise
    (fun a b =>
      Disjoint (map (fun x => Fin.cons a.1 x) (antidiagonalTuple k a.2))
        (map (fun x => Fin.cons b.1 x) (antidiagonalTuple k b.2)))
    (antidiagonal n)
a : ℕ × ℕ
x₁ x₂ : Fin k → ℕ
h : (Prod.map Nat.succ id a).1 = (0, n + 1).1 ∧ x₂ = x₁
⊢ False

Next tactic:
injection h.1
/-- The antidiagonal of `n` does not contain duplicate entries. -/
theorem nodup_antidiagonalTuple (k n : ℕ) : List.Nodup (antidiagonalTuple k n) := by
  induction' k with k ih generalizing n
  · cases n
    · simp
    · simp [eq_comm]
  simp_rw [antidiagonalTuple, List.nodup_bind]
  constructor
  · intro i _
    exact (ih i.snd).map (Fin.cons_right_injective (α := fun _ => ℕ) i.fst)
  induction' n with n n_ih
  · exact List.pairwise_singleton _ _
  · rw [List.Nat.antidiagonal_succ]
    refine' List.Pairwise.cons (fun a ha x hx₁ hx₂ => _) (n_ih.map _ fun a b h x hx₁ hx₂ => _)
    · rw [List.mem_map] at hx₁ hx₂ ha
      obtain ⟨⟨a, -, rfl⟩, ⟨x₁, -, rfl⟩, ⟨x₂, -, h⟩⟩ := ha, hx₁, hx₂
      rw [Fin.cons_eq_cons] at h
      injection h.1
    · 

Proof state:
case succ.right.succ.refine'_2
k : ℕ
ih : ∀ (n : ℕ), Nodup (antidiagonalTuple k n)
n : ℕ
n_ih :
  Pairwise
    (fun a b =>
      Disjoint (map (fun x => Fin.cons a.1 x) (antidiagonalTuple k a.2))
        (map (fun x => Fin.cons b.1 x) (antidiagonalTuple k b.2)))
    (antidiagonal n)
a b : ℕ × ℕ
h :
  Disjoint (map (fun x => Fin.cons a.1 x) (antidiagonalTuple k a.2))
    (map (fun x => Fin.cons b.1 x) (antidiagonalTuple k b.2))
x : Fin (Nat.succ k) → ℕ
hx₁ : x ∈ map (fun x => Fin.cons (Prod.map Nat.succ id a).1 x) (antidiagonalTuple k (Prod.map Nat.succ id a).2)
hx₂ : x ∈ map (fun x => Fin.cons (Prod.map Nat.succ id b).1 x) (antidiagonalTuple k (Prod.map Nat.succ id b).2)
⊢ False

Next tactic:
rw [List.mem_map] at hx₁ hx₂