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

Proof steps:
state_before: α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A✝ B✝ C✝ A B C : Finset α
⊢ (A * C).card * B.card ≤ (A * B).card * (B * C).card
state_after: case inl
α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A✝ B C✝ A C : Finset α
⊢ (A * C).card * ∅.card ≤ (A * ∅).card * (∅ * C).card

case inr
α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A✝ B✝ C✝ A B C : Finset α
hB : B.Nonempty
⊢ (A * C).card * B.card ≤ (A * B).card * (B * C).card
tactic: obtain rfl | hB := B.eq_empty_or_nonempty
state_before: case inr
α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A✝ B✝ C✝ A B C : Finset α
hB : B.Nonempty
⊢ (A * C).card * B.card ≤ (A * B).card * (B * C).card
state_after: case inr
α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A✝ B✝ C✝ A B C : Finset α
hB : B.Nonempty
hB' : B ∈ B.powerset.erase ∅
⊢ (A * C).card * B.card ≤ (A * B).card * (B * C).card
tactic: have hB' : B ∈ B.powerset.erase ∅ := mem_erase_of_ne_of_mem hB.ne_empty (mem_powerset_self _)
state_before: case inr
α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A✝ B✝ C✝ A B C : Finset α
hB : B.Nonempty
hB' : B ∈ B.powerset.erase ∅
⊢ (A * C).card * B.card ≤ (A * B).card * (B * C).card
state_after: case inr.intro.intro
α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A✝ B✝ C✝ A B C : Finset α
hB : B.Nonempty
hB' : B ∈ B.powerset.erase ∅
U : Finset α
hU : U ∈ B.powerset.erase ∅
hUA : ∀ x' ∈ B.powerset.erase ∅, ↑(U * A).card / ↑U.card ≤ ↑(x' * A).card / ↑x'.card
⊢ (A * C).card * B.card ≤ (A * B).card * (B * C).card
tactic: obtain ⟨U, hU, hUA⟩ :=
    exists_min_image (B.powerset.erase ∅) (fun U ↦ (U * A).card / U.card : _ → ℚ≥0) ⟨B, hB'⟩
state_before: case inr.intro.intro
α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A✝ B✝ C✝ A B C : Finset α
hB : B.Nonempty
hB' : B ∈ B.powerset.erase ∅
U : Finset α
hU : U ∈ B.powerset.erase ∅
hUA : ∀ x' ∈ B.powerset.erase ∅, ↑(U * A).card / ↑U.card ≤ ↑(x' * A).card / ↑x'.card
⊢ (A * C).card * B.card ≤ (A * B).card * (B * C).card
state_after: case inr.intro.intro
α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A✝ B✝ C✝ A B C : Finset α
hB : B.Nonempty
hB' : B ∈ B.powerset.erase ∅
U : Finset α
hU : U.Nonempty ∧ U ⊆ B
hUA : ∀ x' ∈ B.powerset.erase ∅, ↑(U * A).card / ↑U.card ≤ ↑(x' * A).card / ↑x'.card
⊢ (A * C).card * B.card ≤ (A * B).card * (B * C).card
tactic: rw [mem_erase, mem_powerset, ← nonempty_iff_ne_empty] at hU
state_before: case inr.intro.intro
α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A✝ B✝ C✝ A B C : Finset α
hB : B.Nonempty
hB' : B ∈ B.powerset.erase ∅
U : Finset α
hU : U.Nonempty ∧ U ⊆ B
hUA : ∀ x' ∈ B.powerset.erase ∅, ↑(U * A).card / ↑U.card ≤ ↑(x' * A).card / ↑x'.card
⊢ (A * C).card * B.card ≤ (A * B).card * (B * C).card
state_after: case inr.intro.intro
α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A✝ B✝ C✝ A B C : Finset α
hB : B.Nonempty
hB' : B ∈ B.powerset.erase ∅
U : Finset α
hU : U.Nonempty ∧ U ⊆ B
hUA : ∀ x' ∈ B.powerset.erase ∅, ↑(U * A).card / ↑U.card ≤ ↑(x' * A).card / ↑x'.card
⊢ ↑((A * C).card * B.card) ≤ ↑((A * B).card * (B * C).card)
tactic: refine cast_le.1 (?_ : (_ : ℚ≥0) ≤ _)
state_before: case inr.intro.intro
α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A✝ B✝ C✝ A B C : Finset α
hB : B.Nonempty
hB' : B ∈ B.powerset.erase ∅
U : Finset α
hU : U.Nonempty ∧ U ⊆ B
hUA : ∀ x' ∈ B.powerset.erase ∅, ↑(U * A).card / ↑U.card ≤ ↑(x' * A).card / ↑x'.card
⊢ ↑((A * C).card * B.card) ≤ ↑((A * B).card * (B * C).card)
state_after: case inr.intro.intro
α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A✝ B✝ C✝ A B C : Finset α
hB : B.Nonempty
hB' : B ∈ B.powerset.erase ∅
U : Finset α
hU : U.Nonempty ∧ U ⊆ B
hUA : ∀ x' ∈ B.powerset.erase ∅, ↑(U * A).card / ↑U.card ≤ ↑(x' * A).card / ↑x'.card
⊢ ↑(A * C).card * ↑B.card ≤ ↑(A * B).card * ↑(B * C).card
tactic: push_cast
state_before: case inr.intro.intro
α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A✝ B✝ C✝ A B C : Finset α
hB : B.Nonempty
hB' : B ∈ B.powerset.erase ∅
U : Finset α
hU : U.Nonempty ∧ U ⊆ B
hUA : ∀ x' ∈ B.powerset.erase ∅, ↑(U * A).card / ↑U.card ≤ ↑(x' * A).card / ↑x'.card
⊢ ↑(A * C).card * ↑B.card ≤ ↑(A * B).card * ↑(B * C).card
state_after: case inr.intro.intro
α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A✝ B✝ C✝ A B C : Finset α
hB : B.Nonempty
hB' : B ∈ B.powerset.erase ∅
U : Finset α
hU : U.Nonempty ∧ U ⊆ B
hUA : ∀ x' ∈ B.powerset.erase ∅, ↑(U * A).card / ↑U.card ≤ ↑(x' * A).card / ↑x'.card
⊢ ↑(A * C).card ≤ ↑(A * B).card * ↑(B * C).card / ↑B.card
tactic: refine (le_div_iff <| cast_pos.2 hB.card_pos).1 ?_
state_before: case inr.intro.intro
α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A✝ B✝ C✝ A B C : Finset α
hB : B.Nonempty
hB' : B ∈ B.powerset.erase ∅
U : Finset α
hU : U.Nonempty ∧ U ⊆ B
hUA : ∀ x' ∈ B.powerset.erase ∅, ↑(U * A).card / ↑U.card ≤ ↑(x' * A).card / ↑x'.card
⊢ ↑(A * C).card ≤ ↑(A * B).card * ↑(B * C).card / ↑B.card
state_after: case inr.intro.intro
α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A✝ B✝ C✝ A B C : Finset α
hB : B.Nonempty
hB' : B ∈ B.powerset.erase ∅
U : Finset α
hU : U.Nonempty ∧ U ⊆ B
hUA : ∀ x' ∈ B.powerset.erase ∅, ↑(U * A).card / ↑U.card ≤ ↑(x' * A).card / ↑x'.card
⊢ ↑(A * C).card ≤ ↑(B * A).card / ↑B.card * ↑(B * C).card
tactic: rw [mul_div_right_comm, mul_comm _ B]
state_before: case inr.intro.intro
α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A✝ B✝ C✝ A B C : Finset α
hB : B.Nonempty
hB' : B ∈ B.powerset.erase ∅
U : Finset α
hU : U.Nonempty ∧ U ⊆ B
hUA : ∀ x' ∈ B.powerset.erase ∅, ↑(U * A).card / ↑U.card ≤ ↑(x' * A).card / ↑x'.card
⊢ ↑(A * C).card ≤ ↑(B * A).card / ↑B.card * ↑(B * C).card
state_after: case inr.intro.intro
α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A✝ B✝ C✝ A B C : Finset α
hB : B.Nonempty
hB' : B ∈ B.powerset.erase ∅
U : Finset α
hU : U.Nonempty ∧ U ⊆ B
hUA : ∀ x' ∈ B.powerset.erase ∅, ↑(U * A).card / ↑U.card ≤ ↑(x' * A).card / ↑x'.card
⊢ ↑(U * (A * C)).card ≤ ↑(B * A).card / ↑B.card * ↑(B * C).card
tactic: refine (Nat.cast_le.2 <| card_le_card_mul_left _ hU.1).trans ?_
state_before: case inr.intro.intro
α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A✝ B✝ C✝ A B C : Finset α
hB : B.Nonempty
hB' : B ∈ B.powerset.erase ∅
U : Finset α
hU : U.Nonempty ∧ U ⊆ B
hUA : ∀ x' ∈ B.powerset.erase ∅, ↑(U * A).card / ↑U.card ≤ ↑(x' * A).card / ↑x'.card
⊢ ↑(U * (A * C)).card ≤ ↑(B * A).card / ↑B.card * ↑(B * C).card
state_after: case inr.intro.intro
α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A✝ B✝ C✝ A B C : Finset α
hB : B.Nonempty
hB' : B ∈ B.powerset.erase ∅
U : Finset α
hU : U.Nonempty ∧ U ⊆ B
hUA : ∀ x' ∈ B.powerset.erase ∅, ↑(U * A).card / ↑U.card ≤ ↑(x' * A).card / ↑x'.card
⊢ ↑(U * (A * C)).card ≤ ↑(U * A).card / ↑U.card * ↑(U * C).card
tactic: refine le_trans ?_
    (mul_le_mul (hUA _ hB') (cast_le.2 <| card_le_card <| mul_subset_mul_right hU.2)
      (zero_le _) (zero_le _))
state_before: case inr.intro.intro
α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A✝ B✝ C✝ A B C : Finset α
hB : B.Nonempty
hB' : B ∈ B.powerset.erase ∅
U : Finset α
hU : U.Nonempty ∧ U ⊆ B
hUA : ∀ x' ∈ B.powerset.erase ∅, ↑(U * A).card / ↑U.card ≤ ↑(x' * A).card / ↑x'.card
⊢ ↑(U * (A * C)).card ≤ ↑(U * A).card / ↑U.card * ↑(U * C).card
state_after: case inr.intro.intro
α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A✝ B✝ C✝ A B C : Finset α
hB : B.Nonempty
hB' : B ∈ B.powerset.erase ∅
U : Finset α
hU : U.Nonempty ∧ U ⊆ B
hUA : ∀ x' ∈ B.powerset.erase ∅, ↑(U * A).card / ↑U.card ≤ ↑(x' * A).card / ↑x'.card
⊢ ↑(U * A * C).card ≤ ↑(U * A).card * ↑(U * C).card / ↑U.card
tactic: rw [← mul_div_right_comm, ← mul_assoc]
state_before: case inr.intro.intro
α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A✝ B✝ C✝ A B C : Finset α
hB : B.Nonempty
hB' : B ∈ B.powerset.erase ∅
U : Finset α
hU : U.Nonempty ∧ U ⊆ B
hUA : ∀ x' ∈ B.powerset.erase ∅, ↑(U * A).card / ↑U.card ≤ ↑(x' * A).card / ↑x'.card
⊢ ↑(U * A * C).card ≤ ↑(U * A).card * ↑(U * C).card / ↑U.card
state_after: case inr.intro.intro
α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A✝ B✝ C✝ A B C : Finset α
hB : B.Nonempty
hB' : B ∈ B.powerset.erase ∅
U : Finset α
hU : U.Nonempty ∧ U ⊆ B
hUA : ∀ x' ∈ B.powerset.erase ∅, ↑(U * A).card / ↑U.card ≤ ↑(x' * A).card / ↑x'.card
⊢ ↑(U * A * C).card * ↑U.card ≤ ↑(U * A).card * ↑(U * C).card
tactic: refine (le_div_iff <| cast_pos.2 hU.1.card_pos).2 ?_
state_before: case inr.intro.intro
α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A✝ B✝ C✝ A B C : Finset α
hB : B.Nonempty
hB' : B ∈ B.powerset.erase ∅
U : Finset α
hU : U.Nonempty ∧ U ⊆ B
hUA : ∀ x' ∈ B.powerset.erase ∅, ↑(U * A).card / ↑U.card ≤ ↑(x' * A).card / ↑x'.card
⊢ ↑(U * A * C).card * ↑U.card ≤ ↑(U * A).card * ↑(U * C).card
state_after: no goals
tactic: exact mod_cast pluennecke_petridis_inequality_mul C (mul_aux hU.1 hU.2 hUA)