Theorem: Finset.pluennecke_ruzsa_inequality_nsmul_sub_nsmul_add
File: Mathlib/Combinatorics/Additive/PluenneckeRuzsa.lean

Proof steps:
state_before: α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A B✝ C : Finset α
hA : A.Nonempty
B : Finset α
m n : ℕ
⊢ ↑(B ^ m / B ^ n).card ≤ (↑(A * B).card / ↑A.card) ^ (m + n) * ↑A.card
state_after: α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A B✝ C : Finset α
hA : A.Nonempty
B : Finset α
m n : ℕ
hA' : A ∈ A.powerset.erase ∅
⊢ ↑(B ^ m / B ^ n).card ≤ (↑(A * B).card / ↑A.card) ^ (m + n) * ↑A.card
tactic: have hA' : A ∈ A.powerset.erase ∅ := mem_erase_of_ne_of_mem hA.ne_empty (mem_powerset_self _)
state_before: α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A B✝ C : Finset α
hA : A.Nonempty
B : Finset α
m n : ℕ
hA' : A ∈ A.powerset.erase ∅
⊢ ↑(B ^ m / B ^ n).card ≤ (↑(A * B).card / ↑A.card) ^ (m + n) * ↑A.card
state_after: case intro.intro
α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A B✝ C✝ : Finset α
hA : A.Nonempty
B : Finset α
m n : ℕ
hA' : A ∈ A.powerset.erase ∅
C : Finset α
hC : C ∈ A.powerset.erase ∅
hCA : ∀ x' ∈ A.powerset.erase ∅, ↑(C * B).card / ↑C.card ≤ ↑(x' * B).card / ↑x'.card
⊢ ↑(B ^ m / B ^ n).card ≤ (↑(A * B).card / ↑A.card) ^ (m + n) * ↑A.card
tactic: obtain ⟨C, hC, hCA⟩ :=
    exists_min_image (A.powerset.erase ∅) (fun C ↦ (C * B).card / C.card : _ → ℚ≥0) ⟨A, hA'⟩
state_before: case intro.intro
α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A B✝ C✝ : Finset α
hA : A.Nonempty
B : Finset α
m n : ℕ
hA' : A ∈ A.powerset.erase ∅
C : Finset α
hC : C ∈ A.powerset.erase ∅
hCA : ∀ x' ∈ A.powerset.erase ∅, ↑(C * B).card / ↑C.card ≤ ↑(x' * B).card / ↑x'.card
⊢ ↑(B ^ m / B ^ n).card ≤ (↑(A * B).card / ↑A.card) ^ (m + n) * ↑A.card
state_after: case intro.intro
α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A B✝ C✝ : Finset α
hA : A.Nonempty
B : Finset α
m n : ℕ
hA' : A ∈ A.powerset.erase ∅
C : Finset α
hC : C.Nonempty ∧ C ⊆ A
hCA : ∀ x' ∈ A.powerset.erase ∅, ↑(C * B).card / ↑C.card ≤ ↑(x' * B).card / ↑x'.card
⊢ ↑(B ^ m / B ^ n).card ≤ (↑(A * B).card / ↑A.card) ^ (m + n) * ↑A.card
tactic: rw [mem_erase, mem_powerset, ← nonempty_iff_ne_empty] at hC
state_before: case intro.intro
α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A B✝ C✝ : Finset α
hA : A.Nonempty
B : Finset α
m n : ℕ
hA' : A ∈ A.powerset.erase ∅
C : Finset α
hC : C.Nonempty ∧ C ⊆ A
hCA : ∀ x' ∈ A.powerset.erase ∅, ↑(C * B).card / ↑C.card ≤ ↑(x' * B).card / ↑x'.card
⊢ ↑(B ^ m / B ^ n).card ≤ (↑(A * B).card / ↑A.card) ^ (m + n) * ↑A.card
state_after: case intro.intro
α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A B✝ C✝ : Finset α
hA : A.Nonempty
B : Finset α
m n : ℕ
hA' : A ∈ A.powerset.erase ∅
C : Finset α
hC : C.Nonempty ∧ C ⊆ A
hCA : ∀ x' ∈ A.powerset.erase ∅, ↑(C * B).card / ↑C.card ≤ ↑(x' * B).card / ↑x'.card
⊢ ↑(B ^ m / B ^ n).card * ↑C.card ≤ (↑(A * B).card / ↑A.card) ^ (m + n) * ↑A.card * ↑C.card
tactic: refine (mul_le_mul_right <| cast_pos.2 hC.1.card_pos).1 ?_
state_before: case intro.intro
α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A B✝ C✝ : Finset α
hA : A.Nonempty
B : Finset α
m n : ℕ
hA' : A ∈ A.powerset.erase ∅
C : Finset α
hC : C.Nonempty ∧ C ⊆ A
hCA : ∀ x' ∈ A.powerset.erase ∅, ↑(C * B).card / ↑C.card ≤ ↑(x' * B).card / ↑x'.card
⊢ ↑(B ^ m / B ^ n).card * ↑C.card ≤ (↑(A * B).card / ↑A.card) ^ (m + n) * ↑A.card * ↑C.card
state_after: case intro.intro
α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A B✝ C✝ : Finset α
hA : A.Nonempty
B : Finset α
m n : ℕ
hA' : A ∈ A.powerset.erase ∅
C : Finset α
hC : C.Nonempty ∧ C ⊆ A
hCA : ∀ x' ∈ A.powerset.erase ∅, ↑(C * B).card / ↑C.card ≤ ↑(x' * B).card / ↑x'.card
⊢ ↑((B ^ m / B ^ n).card * C.card) ≤ (↑(A * B).card / ↑A.card) ^ (m + n) * ↑A.card * ↑C.card
tactic: norm_cast
state_before: case intro.intro
α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A B✝ C✝ : Finset α
hA : A.Nonempty
B : Finset α
m n : ℕ
hA' : A ∈ A.powerset.erase ∅
C : Finset α
hC : C.Nonempty ∧ C ⊆ A
hCA : ∀ x' ∈ A.powerset.erase ∅, ↑(C * B).card / ↑C.card ≤ ↑(x' * B).card / ↑x'.card
⊢ ↑((B ^ m / B ^ n).card * C.card) ≤ (↑(A * B).card / ↑A.card) ^ (m + n) * ↑A.card * ↑C.card
state_after: case intro.intro
α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A B✝ C✝ : Finset α
hA : A.Nonempty
B : Finset α
m n : ℕ
hA' : A ∈ A.powerset.erase ∅
C : Finset α
hC : C.Nonempty ∧ C ⊆ A
hCA : ∀ x' ∈ A.powerset.erase ∅, ↑(C * B).card / ↑C.card ≤ ↑(x' * B).card / ↑x'.card
⊢ ↑((B ^ m * C).card * (C * B ^ n).card) ≤ (↑(A * B).card / ↑A.card) ^ (m + n) * ↑A.card * ↑C.card
tactic: refine (Nat.cast_le.2 <| ruzsa_triangle_inequality_div_mul_mul _ _ _).trans ?_
state_before: case intro.intro
α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A B✝ C✝ : Finset α
hA : A.Nonempty
B : Finset α
m n : ℕ
hA' : A ∈ A.powerset.erase ∅
C : Finset α
hC : C.Nonempty ∧ C ⊆ A
hCA : ∀ x' ∈ A.powerset.erase ∅, ↑(C * B).card / ↑C.card ≤ ↑(x' * B).card / ↑x'.card
⊢ ↑((B ^ m * C).card * (C * B ^ n).card) ≤ (↑(A * B).card / ↑A.card) ^ (m + n) * ↑A.card * ↑C.card
state_after: case intro.intro
α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A B✝ C✝ : Finset α
hA : A.Nonempty
B : Finset α
m n : ℕ
hA' : A ∈ A.powerset.erase ∅
C : Finset α
hC : C.Nonempty ∧ C ⊆ A
hCA : ∀ x' ∈ A.powerset.erase ∅, ↑(C * B).card / ↑C.card ≤ ↑(x' * B).card / ↑x'.card
⊢ ↑(B ^ m * C).card * ↑(C * B ^ n).card ≤ (↑(A * B).card / ↑A.card) ^ (m + n) * ↑A.card * ↑C.card
tactic: push_cast
state_before: case intro.intro
α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A B✝ C✝ : Finset α
hA : A.Nonempty
B : Finset α
m n : ℕ
hA' : A ∈ A.powerset.erase ∅
C : Finset α
hC : C.Nonempty ∧ C ⊆ A
hCA : ∀ x' ∈ A.powerset.erase ∅, ↑(C * B).card / ↑C.card ≤ ↑(x' * B).card / ↑x'.card
⊢ ↑(B ^ m * C).card * ↑(C * B ^ n).card ≤ (↑(A * B).card / ↑A.card) ^ (m + n) * ↑A.card * ↑C.card
state_after: case intro.intro
α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A B✝ C✝ : Finset α
hA : A.Nonempty
B : Finset α
m n : ℕ
hA' : A ∈ A.powerset.erase ∅
C : Finset α
hC : C.Nonempty ∧ C ⊆ A
hCA : ∀ x' ∈ A.powerset.erase ∅, ↑(C * B).card / ↑C.card ≤ ↑(x' * B).card / ↑x'.card
⊢ ↑(C * B ^ m).card * ↑(C * B ^ n).card ≤ (↑(A * B).card / ↑A.card) ^ (m + n) * ↑A.card * ↑C.card
tactic: rw [mul_comm _ C]
state_before: case intro.intro
α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A B✝ C✝ : Finset α
hA : A.Nonempty
B : Finset α
m n : ℕ
hA' : A ∈ A.powerset.erase ∅
C : Finset α
hC : C.Nonempty ∧ C ⊆ A
hCA : ∀ x' ∈ A.powerset.erase ∅, ↑(C * B).card / ↑C.card ≤ ↑(x' * B).card / ↑x'.card
⊢ ↑(C * B ^ m).card * ↑(C * B ^ n).card ≤ (↑(A * B).card / ↑A.card) ^ (m + n) * ↑A.card * ↑C.card
state_after: case intro.intro
α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A B✝ C✝ : Finset α
hA : A.Nonempty
B : Finset α
m n : ℕ
hA' : A ∈ A.powerset.erase ∅
C : Finset α
hC : C.Nonempty ∧ C ⊆ A
hCA : ∀ x' ∈ A.powerset.erase ∅, ↑(C * B).card / ↑C.card ≤ ↑(x' * B).card / ↑x'.card
⊢ (↑(C * B).card / ↑C.card) ^ m * ↑C.card * ((↑(C * B).card / ↑C.card) ^ n * ↑C.card) ≤
    (↑(A * B).card / ↑A.card) ^ (m + n) * ↑A.card * ↑C.card
tactic: refine (mul_le_mul (card_mul_pow_le (mul_aux hC.1 hC.2 hCA) _)
    (card_mul_pow_le (mul_aux hC.1 hC.2 hCA) _) (zero_le _) (zero_le _)).trans ?_
state_before: case intro.intro
α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A B✝ C✝ : Finset α
hA : A.Nonempty
B : Finset α
m n : ℕ
hA' : A ∈ A.powerset.erase ∅
C : Finset α
hC : C.Nonempty ∧ C ⊆ A
hCA : ∀ x' ∈ A.powerset.erase ∅, ↑(C * B).card / ↑C.card ≤ ↑(x' * B).card / ↑x'.card
⊢ (↑(C * B).card / ↑C.card) ^ m * ↑C.card * ((↑(C * B).card / ↑C.card) ^ n * ↑C.card) ≤
    (↑(A * B).card / ↑A.card) ^ (m + n) * ↑A.card * ↑C.card
state_after: case intro.intro
α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A B✝ C✝ : Finset α
hA : A.Nonempty
B : Finset α
m n : ℕ
hA' : A ∈ A.powerset.erase ∅
C : Finset α
hC : C.Nonempty ∧ C ⊆ A
hCA : ∀ x' ∈ A.powerset.erase ∅, ↑(C * B).card / ↑C.card ≤ ↑(x' * B).card / ↑x'.card
⊢ (↑(C * B).card / ↑C.card) ^ (m + n) * ↑C.card * ↑C.card ≤ (↑(A * B).card / ↑A.card) ^ (m + n) * ↑A.card * ↑C.card
tactic: rw [mul_mul_mul_comm, ← pow_add, ← mul_assoc]
state_before: case intro.intro
α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A B✝ C✝ : Finset α
hA : A.Nonempty
B : Finset α
m n : ℕ
hA' : A ∈ A.powerset.erase ∅
C : Finset α
hC : C.Nonempty ∧ C ⊆ A
hCA : ∀ x' ∈ A.powerset.erase ∅, ↑(C * B).card / ↑C.card ≤ ↑(x' * B).card / ↑x'.card
⊢ (↑(C * B).card / ↑C.card) ^ (m + n) * ↑C.card * ↑C.card ≤ (↑(A * B).card / ↑A.card) ^ (m + n) * ↑A.card * ↑C.card
state_after: case intro.intro.bc.h₁.hab
α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A B✝ C✝ : Finset α
hA : A.Nonempty
B : Finset α
m n : ℕ
hA' : A ∈ A.powerset.erase ∅
C : Finset α
hC : C.Nonempty ∧ C ⊆ A
hCA : ∀ x' ∈ A.powerset.erase ∅, ↑(C * B).card / ↑C.card ≤ ↑(x' * B).card / ↑x'.card
⊢ ↑(C * B).card / ↑C.card ≤ ↑(A * B).card / ↑A.card

case intro.intro.bc.h₂.h
α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A B✝ C✝ : Finset α
hA : A.Nonempty
B : Finset α
m n : ℕ
hA' : A ∈ A.powerset.erase ∅
C : Finset α
hC : C.Nonempty ∧ C ⊆ A
hCA : ∀ x' ∈ A.powerset.erase ∅, ↑(C * B).card / ↑C.card ≤ ↑(x' * B).card / ↑x'.card
⊢ C.card ≤ A.card
tactic: gcongr ((?_ ^ _) * Nat.cast ?_) * _