Theorem: Finset.card_add_card_sub_one_le_card_mul
File: Mathlib/Combinatorics/SetFamily/CauchyDavenport.lean

Proof steps:
state_before: α : Type u_1
inst✝⁴ : LinearOrder α
inst✝³ : Semigroup α
inst✝² : IsCancelMul α
inst✝¹ : CovariantClass α α (fun x x_1 => x * x_1) fun x x_1 => x ≤ x_1
inst✝ : CovariantClass α α (swap fun x x_1 => x * x_1) fun x x_1 => x ≤ x_1
s t : Finset α
hs : s.Nonempty
ht : t.Nonempty
⊢ s.card + t.card - 1 ≤ (s * t).card
state_after: α : Type u_1
inst✝⁴ : LinearOrder α
inst✝³ : Semigroup α
inst✝² : IsCancelMul α
inst✝¹ : CovariantClass α α (fun x x_1 => x * x_1) fun x x_1 => x ≤ x_1
inst✝ : CovariantClass α α (swap fun x x_1 => x * x_1) fun x x_1 => x ≤ x_1
s t : Finset α
hs : s.Nonempty
ht : t.Nonempty
⊢ s * {t.min' ht} ∩ ({s.max' hs} * t) = {s.max' hs * t.min' ht}
tactic: suffices s * {t.min' ht} ∩ ({s.max' hs} * t) = {s.max' hs * t.min' ht} by
    rw [← card_singleton_mul t (s.max' hs), ← card_mul_singleton s (t.min' ht),
      ← card_union_add_card_inter, ← card_singleton _, ← this, Nat.add_sub_cancel]
    exact card_mono (union_subset (mul_subset_mul_left <| singleton_subset_iff.2 <| min'_mem _ _) <|
      mul_subset_mul_right <| singleton_subset_iff.2 <| max'_mem _ _)
state_before: α : Type u_1
inst✝⁴ : LinearOrder α
inst✝³ : Semigroup α
inst✝² : IsCancelMul α
inst✝¹ : CovariantClass α α (fun x x_1 => x * x_1) fun x x_1 => x ≤ x_1
inst✝ : CovariantClass α α (swap fun x x_1 => x * x_1) fun x x_1 => x ≤ x_1
s t : Finset α
hs : s.Nonempty
ht : t.Nonempty
⊢ s * {t.min' ht} ∩ ({s.max' hs} * t) = {s.max' hs * t.min' ht}
state_after: α : Type u_1
inst✝⁴ : LinearOrder α
inst✝³ : Semigroup α
inst✝² : IsCancelMul α
inst✝¹ : CovariantClass α α (fun x x_1 => x * x_1) fun x x_1 => x ≤ x_1
inst✝ : CovariantClass α α (swap fun x x_1 => x * x_1) fun x x_1 => x ≤ x_1
s t : Finset α
hs : s.Nonempty
ht : t.Nonempty
⊢ ∀ x ∈ s * {t.min' ht} ∩ ({s.max' hs} * t), x = s.max' hs * t.min' ht
tactic: refine eq_singleton_iff_unique_mem.2 ⟨mem_inter.2 ⟨mul_mem_mul (max'_mem _ _) <|
    mem_singleton_self _, mul_mem_mul (mem_singleton_self _) <| min'_mem _ _⟩, ?_⟩
state_before: α : Type u_1
inst✝⁴ : LinearOrder α
inst✝³ : Semigroup α
inst✝² : IsCancelMul α
inst✝¹ : CovariantClass α α (fun x x_1 => x * x_1) fun x x_1 => x ≤ x_1
inst✝ : CovariantClass α α (swap fun x x_1 => x * x_1) fun x x_1 => x ≤ x_1
s t : Finset α
hs : s.Nonempty
ht : t.Nonempty
⊢ ∀ x ∈ s * {t.min' ht} ∩ ({s.max' hs} * t), x = s.max' hs * t.min' ht
state_after: α : Type u_1
inst✝⁴ : LinearOrder α
inst✝³ : Semigroup α
inst✝² : IsCancelMul α
inst✝¹ : CovariantClass α α (fun x x_1 => x * x_1) fun x x_1 => x ≤ x_1
inst✝ : CovariantClass α α (swap fun x x_1 => x * x_1) fun x x_1 => x ≤ x_1
s t : Finset α
hs : s.Nonempty
ht : t.Nonempty
⊢ ∀ a ∈ s, ∀ x ∈ t, s.max' hs * x = a * t.min' ht → a = s.max' hs
tactic: simp only [mem_inter, and_imp, mem_mul, mem_singleton, exists_and_left, exists_eq_left,
    forall_exists_index, and_imp, forall_apply_eq_imp_iff₂, mul_left_inj]
state_before: α : Type u_1
inst✝⁴ : LinearOrder α
inst✝³ : Semigroup α
inst✝² : IsCancelMul α
inst✝¹ : CovariantClass α α (fun x x_1 => x * x_1) fun x x_1 => x ≤ x_1
inst✝ : CovariantClass α α (swap fun x x_1 => x * x_1) fun x x_1 => x ≤ x_1
s t : Finset α
hs : s.Nonempty
ht : t.Nonempty
⊢ ∀ a ∈ s, ∀ x ∈ t, s.max' hs * x = a * t.min' ht → a = s.max' hs
state_after: no goals
tactic: exact fun a' ha' b' hb' h ↦ (le_max' _ _ ha').eq_of_not_lt fun ha ↦
    ((mul_lt_mul_right' ha _).trans_eq' h).not_le <| mul_le_mul_left' (min'_le _ _ hb') _