l3lab/ntp-mathlib huggingface dataset:
@[to_additive]
private theorem mul_aux (hA : A.Nonempty) (hAB : A ⊆ B)
    (h : ∀ A' ∈ B.powerset.erase ∅, ((A * C).card : ℚ≥0) / ↑A.card ≤ (A' * C).card / ↑A'.card) :
    ∀ (A') (_ : A' ⊆ A), (A * C).card * A'.card ≤ (A' * C).card * A.card := by
  rintro A' hAA'
  obtain rfl | hA' := A'.eq_empty_or_nonempty
  · simp
  

Proof state:
case inr
α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A B C : Finset α
hA : Finset.Nonempty A
hAB : A ⊆ B
h : ∀ A' ∈ erase (powerset B) ∅, ↑(card (A * C)) / ↑(card A) ≤ ↑(card (A' * C)) / ↑(card A')
A' : Finset α
hAA' : A' ⊆ A
hA' : Finset.Nonempty A'
⊢ card (A * C) * card A' ≤ card (A' * C) * card A

Next tactic:
have hA₀ : (0 : ℚ≥0) < A.card := cast_pos.2 hA.card_pos
@[to_additive]
private theorem mul_aux (hA : A.Nonempty) (hAB : A ⊆ B)
    (h : ∀ A' ∈ B.powerset.erase ∅, ((A * C).card : ℚ≥0) / ↑A.card ≤ (A' * C).card / ↑A'.card) :
    ∀ (A') (_ : A' ⊆ A), (A * C).card * A'.card ≤ (A' * C).card * A.card := by
  rintro A' hAA'
  obtain rfl | hA' := A'.eq_empty_or_nonempty
  · simp
  have hA₀ : (0 : ℚ≥0) < A.card := cast_pos.2 hA.card_pos
  

Proof state:
case inr
α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A B C : Finset α
hA : Finset.Nonempty A
hAB : A ⊆ B
h : ∀ A' ∈ erase (powerset B) ∅, ↑(card (A * C)) / ↑(card A) ≤ ↑(card (A' * C)) / ↑(card A')
A' : Finset α
hAA' : A' ⊆ A
hA' : Finset.Nonempty A'
hA₀ : 0 < ↑(card A)
⊢ card (A * C) * card A' ≤ card (A' * C) * card A

Next tactic:
have hA₀' : (0 : ℚ≥0) < A'.card := cast_pos.2 hA'.card_pos
@[to_additive]
private theorem mul_aux (hA : A.Nonempty) (hAB : A ⊆ B)
    (h : ∀ A' ∈ B.powerset.erase ∅, ((A * C).card : ℚ≥0) / ↑A.card ≤ (A' * C).card / ↑A'.card) :
    ∀ (A') (_ : A' ⊆ A), (A * C).card * A'.card ≤ (A' * C).card * A.card := by
  rintro A' hAA'
  obtain rfl | hA' := A'.eq_empty_or_nonempty
  · simp
  have hA₀ : (0 : ℚ≥0) < A.card := cast_pos.2 hA.card_pos
  have hA₀' : (0 : ℚ≥0) < A'.card := cast_pos.2 hA'.card_pos
  

Proof state:
case inr
α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A B C : Finset α
hA : Finset.Nonempty A
hAB : A ⊆ B
h : ∀ A' ∈ erase (powerset B) ∅, ↑(card (A * C)) / ↑(card A) ≤ ↑(card (A' * C)) / ↑(card A')
A' : Finset α
hAA' : A' ⊆ A
hA' : Finset.Nonempty A'
hA₀ : 0 < ↑(card A)
hA₀' : 0 < ↑(card A')
⊢ card (A * C) * card A' ≤ card (A' * C) * card A

Next tactic:
exact mod_cast
    (div_le_div_iff hA₀ hA₀').1
      (h _ <| mem_erase_of_ne_of_mem hA'.ne_empty <| mem_powerset.2 <| hAA'.trans hAB)
/-- **Ruzsa's triangle inequality**. Multiplication version. -/
@[to_additive card_add_mul_card_le_card_add_mul_card_add
      "**Ruzsa's triangle inequality**. Addition version."]
theorem card_mul_mul_card_le_card_mul_mul_card_mul (A B C : Finset α) :
    (A * C).card * B.card ≤ (A * B).card * (B * C).card := by
  

Proof state:
α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A✝ B✝ C✝ A B C : Finset α
⊢ card (A * C) * card B ≤ card (A * B) * card (B * C)

Next tactic:
obtain rfl | hB := B.eq_empty_or_nonempty
/-- **Ruzsa's triangle inequality**. Multiplication version. -/
@[to_additive card_add_mul_card_le_card_add_mul_card_add
      "**Ruzsa's triangle inequality**. Addition version."]
theorem card_mul_mul_card_le_card_mul_mul_card_mul (A B C : Finset α) :
    (A * C).card * B.card ≤ (A * B).card * (B * C).card := by
  obtain rfl | hB := B.eq_empty_or_nonempty
  · 

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

Next tactic:
simp
/-- **Ruzsa's triangle inequality**. Multiplication version. -/
@[to_additive card_add_mul_card_le_card_add_mul_card_add
      "**Ruzsa's triangle inequality**. Addition version."]
theorem card_mul_mul_card_le_card_mul_mul_card_mul (A B C : Finset α) :
    (A * C).card * B.card ≤ (A * B).card * (B * C).card := by
  obtain rfl | hB := B.eq_empty_or_nonempty
  · simp
  

Proof state:
case inr
α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A✝ B✝ C✝ A B C : Finset α
hB : Finset.Nonempty B
⊢ card (A * C) * card B ≤ card (A * B) * card (B * C)

Next tactic:
have hB' : B ∈ B.powerset.erase ∅ := mem_erase_of_ne_of_mem hB.ne_empty (mem_powerset_self _)
/-- **Ruzsa's triangle inequality**. Multiplication version. -/
@[to_additive card_add_mul_card_le_card_add_mul_card_add
      "**Ruzsa's triangle inequality**. Addition version."]
theorem card_mul_mul_card_le_card_mul_mul_card_mul (A B C : Finset α) :
    (A * C).card * B.card ≤ (A * B).card * (B * C).card := by
  obtain rfl | hB := B.eq_empty_or_nonempty
  · simp
  have hB' : B ∈ B.powerset.erase ∅ := mem_erase_of_ne_of_mem hB.ne_empty (mem_powerset_self _)
  

Proof state:
case inr
α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A✝ B✝ C✝ A B C : Finset α
hB : Finset.Nonempty B
hB' : B ∈ erase (powerset B) ∅
⊢ card (A * C) * card B ≤ card (A * B) * card (B * C)

Next tactic:
obtain ⟨U, hU, hUA⟩ :=
    exists_min_image (B.powerset.erase ∅) (fun U ↦ (U * A).card / U.card : _ → ℚ≥0) ⟨B, hB'⟩
/-- **Ruzsa's triangle inequality**. Multiplication version. -/
@[to_additive card_add_mul_card_le_card_add_mul_card_add
      "**Ruzsa's triangle inequality**. Addition version."]
theorem card_mul_mul_card_le_card_mul_mul_card_mul (A B C : Finset α) :
    (A * C).card * B.card ≤ (A * B).card * (B * C).card := by
  obtain rfl | hB := B.eq_empty_or_nonempty
  · simp
  have hB' : B ∈ B.powerset.erase ∅ := mem_erase_of_ne_of_mem hB.ne_empty (mem_powerset_self _)
  obtain ⟨U, hU, hUA⟩ :=
    exists_min_image (B.powerset.erase ∅) (fun U ↦ (U * A).card / U.card : _ → ℚ≥0) ⟨B, hB'⟩
  

Proof state:
case inr.intro.intro
α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A✝ B✝ C✝ A B C : Finset α
hB : Finset.Nonempty B
hB' : B ∈ erase (powerset B) ∅
U : Finset α
hU : U ∈ erase (powerset B) ∅
hUA : ∀ x' ∈ erase (powerset B) ∅, ↑(card (U * A)) / ↑(card U) ≤ ↑(card (x' * A)) / ↑(card x')
⊢ card (A * C) * card B ≤ card (A * B) * card (B * C)

Next tactic:
rw [mem_erase, mem_powerset, ← nonempty_iff_ne_empty] at hU
/-- **Ruzsa's triangle inequality**. Multiplication version. -/
@[to_additive card_add_mul_card_le_card_add_mul_card_add
      "**Ruzsa's triangle inequality**. Addition version."]
theorem card_mul_mul_card_le_card_mul_mul_card_mul (A B C : Finset α) :
    (A * C).card * B.card ≤ (A * B).card * (B * C).card := by
  obtain rfl | hB := B.eq_empty_or_nonempty
  · simp
  have hB' : B ∈ B.powerset.erase ∅ := mem_erase_of_ne_of_mem hB.ne_empty (mem_powerset_self _)
  obtain ⟨U, hU, hUA⟩ :=
    exists_min_image (B.powerset.erase ∅) (fun U ↦ (U * A).card / U.card : _ → ℚ≥0) ⟨B, hB'⟩
  rw [mem_erase, mem_powerset, ← nonempty_iff_ne_empty] at hU
  

Proof state:
case inr.intro.intro
α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A✝ B✝ C✝ A B C : Finset α
hB : Finset.Nonempty B
hB' : B ∈ erase (powerset B) ∅
U : Finset α
hU : Finset.Nonempty U ∧ U ⊆ B
hUA : ∀ x' ∈ erase (powerset B) ∅, ↑(card (U * A)) / ↑(card U) ≤ ↑(card (x' * A)) / ↑(card x')
⊢ card (A * C) * card B ≤ card (A * B) * card (B * C)

Next tactic:
refine' cast_le.1 (_ : (_ : ℚ≥0) ≤ _)
/-- **Ruzsa's triangle inequality**. Multiplication version. -/
@[to_additive card_add_mul_card_le_card_add_mul_card_add
      "**Ruzsa's triangle inequality**. Addition version."]
theorem card_mul_mul_card_le_card_mul_mul_card_mul (A B C : Finset α) :
    (A * C).card * B.card ≤ (A * B).card * (B * C).card := by
  obtain rfl | hB := B.eq_empty_or_nonempty
  · simp
  have hB' : B ∈ B.powerset.erase ∅ := mem_erase_of_ne_of_mem hB.ne_empty (mem_powerset_self _)
  obtain ⟨U, hU, hUA⟩ :=
    exists_min_image (B.powerset.erase ∅) (fun U ↦ (U * A).card / U.card : _ → ℚ≥0) ⟨B, hB'⟩
  rw [mem_erase, mem_powerset, ← nonempty_iff_ne_empty] at hU
  refine' cast_le.1 (_ : (_ : ℚ≥0) ≤ _)
  

Proof state:
case inr.intro.intro
α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A✝ B✝ C✝ A B C : Finset α
hB : Finset.Nonempty B
hB' : B ∈ erase (powerset B) ∅
U : Finset α
hU : Finset.Nonempty U ∧ U ⊆ B
hUA : ∀ x' ∈ erase (powerset B) ∅, ↑(card (U * A)) / ↑(card U) ≤ ↑(card (x' * A)) / ↑(card x')
⊢ ↑(card (A * C) * card B) ≤ ↑(card (A * B) * card (B * C))

Next tactic:
push_cast
/-- **Ruzsa's triangle inequality**. Multiplication version. -/
@[to_additive card_add_mul_card_le_card_add_mul_card_add
      "**Ruzsa's triangle inequality**. Addition version."]
theorem card_mul_mul_card_le_card_mul_mul_card_mul (A B C : Finset α) :
    (A * C).card * B.card ≤ (A * B).card * (B * C).card := by
  obtain rfl | hB := B.eq_empty_or_nonempty
  · simp
  have hB' : B ∈ B.powerset.erase ∅ := mem_erase_of_ne_of_mem hB.ne_empty (mem_powerset_self _)
  obtain ⟨U, hU, hUA⟩ :=
    exists_min_image (B.powerset.erase ∅) (fun U ↦ (U * A).card / U.card : _ → ℚ≥0) ⟨B, hB'⟩
  rw [mem_erase, mem_powerset, ← nonempty_iff_ne_empty] at hU
  refine' cast_le.1 (_ : (_ : ℚ≥0) ≤ _)
  push_cast
  

Proof state:
case inr.intro.intro
α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A✝ B✝ C✝ A B C : Finset α
hB : Finset.Nonempty B
hB' : B ∈ erase (powerset B) ∅
U : Finset α
hU : Finset.Nonempty U ∧ U ⊆ B
hUA : ∀ x' ∈ erase (powerset B) ∅, ↑(card (U * A)) / ↑(card U) ≤ ↑(card (x' * A)) / ↑(card x')
⊢ ↑(card (A * C)) * ↑(card B) ≤ ↑(card (A * B)) * ↑(card (B * C))

Next tactic:
refine' (le_div_iff <| cast_pos.2 hB.card_pos).1 _
/-- **Ruzsa's triangle inequality**. Multiplication version. -/
@[to_additive card_add_mul_card_le_card_add_mul_card_add
      "**Ruzsa's triangle inequality**. Addition version."]
theorem card_mul_mul_card_le_card_mul_mul_card_mul (A B C : Finset α) :
    (A * C).card * B.card ≤ (A * B).card * (B * C).card := by
  obtain rfl | hB := B.eq_empty_or_nonempty
  · simp
  have hB' : B ∈ B.powerset.erase ∅ := mem_erase_of_ne_of_mem hB.ne_empty (mem_powerset_self _)
  obtain ⟨U, hU, hUA⟩ :=
    exists_min_image (B.powerset.erase ∅) (fun U ↦ (U * A).card / U.card : _ → ℚ≥0) ⟨B, hB'⟩
  rw [mem_erase, mem_powerset, ← nonempty_iff_ne_empty] at hU
  refine' cast_le.1 (_ : (_ : ℚ≥0) ≤ _)
  push_cast
  refine' (le_div_iff <| cast_pos.2 hB.card_pos).1 _
  

Proof state:
case inr.intro.intro
α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A✝ B✝ C✝ A B C : Finset α
hB : Finset.Nonempty B
hB' : B ∈ erase (powerset B) ∅
U : Finset α
hU : Finset.Nonempty U ∧ U ⊆ B
hUA : ∀ x' ∈ erase (powerset B) ∅, ↑(card (U * A)) / ↑(card U) ≤ ↑(card (x' * A)) / ↑(card x')
⊢ ↑(card (A * C)) ≤ ↑(card (A * B)) * ↑(card (B * C)) / ↑(card B)

Next tactic:
rw [mul_div_right_comm, mul_comm _ B]
/-- **Ruzsa's triangle inequality**. Multiplication version. -/
@[to_additive card_add_mul_card_le_card_add_mul_card_add
      "**Ruzsa's triangle inequality**. Addition version."]
theorem card_mul_mul_card_le_card_mul_mul_card_mul (A B C : Finset α) :
    (A * C).card * B.card ≤ (A * B).card * (B * C).card := by
  obtain rfl | hB := B.eq_empty_or_nonempty
  · simp
  have hB' : B ∈ B.powerset.erase ∅ := mem_erase_of_ne_of_mem hB.ne_empty (mem_powerset_self _)
  obtain ⟨U, hU, hUA⟩ :=
    exists_min_image (B.powerset.erase ∅) (fun U ↦ (U * A).card / U.card : _ → ℚ≥0) ⟨B, hB'⟩
  rw [mem_erase, mem_powerset, ← nonempty_iff_ne_empty] at hU
  refine' cast_le.1 (_ : (_ : ℚ≥0) ≤ _)
  push_cast
  refine' (le_div_iff <| cast_pos.2 hB.card_pos).1 _
  rw [mul_div_right_comm, mul_comm _ B]
  

Proof state:
case inr.intro.intro
α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A✝ B✝ C✝ A B C : Finset α
hB : Finset.Nonempty B
hB' : B ∈ erase (powerset B) ∅
U : Finset α
hU : Finset.Nonempty U ∧ U ⊆ B
hUA : ∀ x' ∈ erase (powerset B) ∅, ↑(card (U * A)) / ↑(card U) ≤ ↑(card (x' * A)) / ↑(card x')
⊢ ↑(card (A * C)) ≤ ↑(card (B * A)) / ↑(card B) * ↑(card (B * C))

Next tactic:
refine' (cast_le.2 <| card_le_card_mul_left _ hU.1).trans _
/-- **Ruzsa's triangle inequality**. Multiplication version. -/
@[to_additive card_add_mul_card_le_card_add_mul_card_add
      "**Ruzsa's triangle inequality**. Addition version."]
theorem card_mul_mul_card_le_card_mul_mul_card_mul (A B C : Finset α) :
    (A * C).card * B.card ≤ (A * B).card * (B * C).card := by
  obtain rfl | hB := B.eq_empty_or_nonempty
  · simp
  have hB' : B ∈ B.powerset.erase ∅ := mem_erase_of_ne_of_mem hB.ne_empty (mem_powerset_self _)
  obtain ⟨U, hU, hUA⟩ :=
    exists_min_image (B.powerset.erase ∅) (fun U ↦ (U * A).card / U.card : _ → ℚ≥0) ⟨B, hB'⟩
  rw [mem_erase, mem_powerset, ← nonempty_iff_ne_empty] at hU
  refine' cast_le.1 (_ : (_ : ℚ≥0) ≤ _)
  push_cast
  refine' (le_div_iff <| cast_pos.2 hB.card_pos).1 _
  rw [mul_div_right_comm, mul_comm _ B]
  refine' (cast_le.2 <| card_le_card_mul_left _ hU.1).trans _
  

Proof state:
case inr.intro.intro
α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A✝ B✝ C✝ A B C : Finset α
hB : Finset.Nonempty B
hB' : B ∈ erase (powerset B) ∅
U : Finset α
hU : Finset.Nonempty U ∧ U ⊆ B
hUA : ∀ x' ∈ erase (powerset B) ∅, ↑(card (U * A)) / ↑(card U) ≤ ↑(card (x' * A)) / ↑(card x')
⊢ ↑(card (U * (A * C))) ≤ ↑(card (B * A)) / ↑(card B) * ↑(card (B * C))

Next tactic:
refine' le_trans _
    (mul_le_mul (hUA _ hB') (cast_le.2 <| card_le_of_subset <| mul_subset_mul_right hU.2)
      (zero_le _) (zero_le _))
/-- **Ruzsa's triangle inequality**. Multiplication version. -/
@[to_additive card_add_mul_card_le_card_add_mul_card_add
      "**Ruzsa's triangle inequality**. Addition version."]
theorem card_mul_mul_card_le_card_mul_mul_card_mul (A B C : Finset α) :
    (A * C).card * B.card ≤ (A * B).card * (B * C).card := by
  obtain rfl | hB := B.eq_empty_or_nonempty
  · simp
  have hB' : B ∈ B.powerset.erase ∅ := mem_erase_of_ne_of_mem hB.ne_empty (mem_powerset_self _)
  obtain ⟨U, hU, hUA⟩ :=
    exists_min_image (B.powerset.erase ∅) (fun U ↦ (U * A).card / U.card : _ → ℚ≥0) ⟨B, hB'⟩
  rw [mem_erase, mem_powerset, ← nonempty_iff_ne_empty] at hU
  refine' cast_le.1 (_ : (_ : ℚ≥0) ≤ _)
  push_cast
  refine' (le_div_iff <| cast_pos.2 hB.card_pos).1 _
  rw [mul_div_right_comm, mul_comm _ B]
  refine' (cast_le.2 <| card_le_card_mul_left _ hU.1).trans _
  refine' le_trans _
    (mul_le_mul (hUA _ hB') (cast_le.2 <| card_le_of_subset <| mul_subset_mul_right hU.2)
      (zero_le _) (zero_le _))
  

Proof state:
case inr.intro.intro
α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A✝ B✝ C✝ A B C : Finset α
hB : Finset.Nonempty B
hB' : B ∈ erase (powerset B) ∅
U : Finset α
hU : Finset.Nonempty U ∧ U ⊆ B
hUA : ∀ x' ∈ erase (powerset B) ∅, ↑(card (U * A)) / ↑(card U) ≤ ↑(card (x' * A)) / ↑(card x')
⊢ ↑(card (U * (A * C))) ≤ ↑(card (U * A)) / ↑(card U) * ↑(card (U * C))

Next tactic:
rw [← mul_div_right_comm, ← mul_assoc]
/-- **Ruzsa's triangle inequality**. Multiplication version. -/
@[to_additive card_add_mul_card_le_card_add_mul_card_add
      "**Ruzsa's triangle inequality**. Addition version."]
theorem card_mul_mul_card_le_card_mul_mul_card_mul (A B C : Finset α) :
    (A * C).card * B.card ≤ (A * B).card * (B * C).card := by
  obtain rfl | hB := B.eq_empty_or_nonempty
  · simp
  have hB' : B ∈ B.powerset.erase ∅ := mem_erase_of_ne_of_mem hB.ne_empty (mem_powerset_self _)
  obtain ⟨U, hU, hUA⟩ :=
    exists_min_image (B.powerset.erase ∅) (fun U ↦ (U * A).card / U.card : _ → ℚ≥0) ⟨B, hB'⟩
  rw [mem_erase, mem_powerset, ← nonempty_iff_ne_empty] at hU
  refine' cast_le.1 (_ : (_ : ℚ≥0) ≤ _)
  push_cast
  refine' (le_div_iff <| cast_pos.2 hB.card_pos).1 _
  rw [mul_div_right_comm, mul_comm _ B]
  refine' (cast_le.2 <| card_le_card_mul_left _ hU.1).trans _
  refine' le_trans _
    (mul_le_mul (hUA _ hB') (cast_le.2 <| card_le_of_subset <| mul_subset_mul_right hU.2)
      (zero_le _) (zero_le _))
  rw [← mul_div_right_comm, ← mul_assoc]
  

Proof state:
case inr.intro.intro
α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A✝ B✝ C✝ A B C : Finset α
hB : Finset.Nonempty B
hB' : B ∈ erase (powerset B) ∅
U : Finset α
hU : Finset.Nonempty U ∧ U ⊆ B
hUA : ∀ x' ∈ erase (powerset B) ∅, ↑(card (U * A)) / ↑(card U) ≤ ↑(card (x' * A)) / ↑(card x')
⊢ ↑(card (U * A * C)) ≤ ↑(card (U * A)) * ↑(card (U * C)) / ↑(card U)

Next tactic:
refine' (le_div_iff <| cast_pos.2 hU.1.card_pos).2 _
/-- **Ruzsa's triangle inequality**. Multiplication version. -/
@[to_additive card_add_mul_card_le_card_add_mul_card_add
      "**Ruzsa's triangle inequality**. Addition version."]
theorem card_mul_mul_card_le_card_mul_mul_card_mul (A B C : Finset α) :
    (A * C).card * B.card ≤ (A * B).card * (B * C).card := by
  obtain rfl | hB := B.eq_empty_or_nonempty
  · simp
  have hB' : B ∈ B.powerset.erase ∅ := mem_erase_of_ne_of_mem hB.ne_empty (mem_powerset_self _)
  obtain ⟨U, hU, hUA⟩ :=
    exists_min_image (B.powerset.erase ∅) (fun U ↦ (U * A).card / U.card : _ → ℚ≥0) ⟨B, hB'⟩
  rw [mem_erase, mem_powerset, ← nonempty_iff_ne_empty] at hU
  refine' cast_le.1 (_ : (_ : ℚ≥0) ≤ _)
  push_cast
  refine' (le_div_iff <| cast_pos.2 hB.card_pos).1 _
  rw [mul_div_right_comm, mul_comm _ B]
  refine' (cast_le.2 <| card_le_card_mul_left _ hU.1).trans _
  refine' le_trans _
    (mul_le_mul (hUA _ hB') (cast_le.2 <| card_le_of_subset <| mul_subset_mul_right hU.2)
      (zero_le _) (zero_le _))
  rw [← mul_div_right_comm, ← mul_assoc]
  refine' (le_div_iff <| cast_pos.2 hU.1.card_pos).2 _
  

Proof state:
case inr.intro.intro
α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A✝ B✝ C✝ A B C : Finset α
hB : Finset.Nonempty B
hB' : B ∈ erase (powerset B) ∅
U : Finset α
hU : Finset.Nonempty U ∧ U ⊆ B
hUA : ∀ x' ∈ erase (powerset B) ∅, ↑(card (U * A)) / ↑(card U) ≤ ↑(card (x' * A)) / ↑(card x')
⊢ ↑(card (U * A * C)) * ↑(card U) ≤ ↑(card (U * A)) * ↑(card (U * C))

Next tactic:
exact mod_cast mul_pluennecke_petridis C (mul_aux hU.1 hU.2 hUA)
/-- **Ruzsa's triangle inequality**. Add-sub-sub version. -/
theorem card_mul_mul_le_card_div_mul_card_div (A B C : Finset α) :
    (A * C).card * B.card ≤ (A / B).card * (B / C).card := by
  

Proof state:
α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A✝ B✝ C✝ A B C : Finset α
⊢ card (A * C) * card B ≤ card (A / B) * card (B / C)

Next tactic:
rw [div_eq_mul_inv, ← card_inv B, ← card_inv (B / C), inv_div', div_inv_eq_mul]
/-- **Ruzsa's triangle inequality**. Add-sub-sub version. -/
theorem card_mul_mul_le_card_div_mul_card_div (A B C : Finset α) :
    (A * C).card * B.card ≤ (A / B).card * (B / C).card := by
  rw [div_eq_mul_inv, ← card_inv B, ← card_inv (B / C), inv_div', div_inv_eq_mul]
  

Proof state:
α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A✝ B✝ C✝ A B C : Finset α
⊢ card (A * C) * card B⁻¹ ≤ card (A * B⁻¹) * card (B⁻¹ * C)

Next tactic:
exact card_mul_mul_card_le_card_mul_mul_card_mul _ _ _
/-- **Ruzsa's triangle inequality**. Sub-add-sub version. -/
theorem card_div_mul_le_card_mul_mul_card_div (A B C : Finset α) :
    (A / C).card * B.card ≤ (A * B).card * (B / C).card := by
  

Proof state:
α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A✝ B✝ C✝ A B C : Finset α
⊢ card (A / C) * card B ≤ card (A * B) * card (B / C)

Next tactic:
rw [div_eq_mul_inv, div_eq_mul_inv]
/-- **Ruzsa's triangle inequality**. Sub-add-sub version. -/
theorem card_div_mul_le_card_mul_mul_card_div (A B C : Finset α) :
    (A / C).card * B.card ≤ (A * B).card * (B / C).card := by
  rw [div_eq_mul_inv, div_eq_mul_inv]
  

Proof state:
α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A✝ B✝ C✝ A B C : Finset α
⊢ card (A * C⁻¹) * card B ≤ card (A * B) * card (B * C⁻¹)

Next tactic:
exact card_mul_mul_card_le_card_mul_mul_card_mul _ _ _
/-- **Ruzsa's triangle inequality**. Sub-sub-add version. -/
theorem card_div_mul_le_card_div_mul_card_mul (A B C : Finset α) :
    (A / C).card * B.card ≤ (A / B).card * (B * C).card := by
  

Proof state:
α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A✝ B✝ C✝ A B C : Finset α
⊢ card (A / C) * card B ≤ card (A / B) * card (B * C)

Next tactic:
rw [← div_inv_eq_mul, div_eq_mul_inv]
/-- **Ruzsa's triangle inequality**. Sub-sub-add version. -/
theorem card_div_mul_le_card_div_mul_card_mul (A B C : Finset α) :
    (A / C).card * B.card ≤ (A / B).card * (B * C).card := by
  rw [← div_inv_eq_mul, div_eq_mul_inv]
  

Proof state:
α : Type u_1
inst✝¹ : CommGroup α
inst✝ : DecidableEq α
A✝ B✝ C✝ A B C : Finset α
⊢ card (A * C⁻¹) * card B ≤ card (A / B) * card (B / C⁻¹)

Next tactic:
exact card_mul_mul_le_card_div_mul_card_div _ _ _
theorem card_add_nsmul_le {α : Type*} [AddCommGroup α] [DecidableEq α] {A B : Finset α}
    (hAB : ∀ (A') (_ : A' ⊆ A), (A + B).card * A'.card ≤ (A' + B).card * A.card) (n : ℕ) :
    (A + n • B).card ≤ ((A + B).card / A.card : ℚ≥0) ^ n * A.card := by
  

Proof state:
α✝ : Type u_1
inst✝³ : CommGroup α✝
inst✝² : DecidableEq α✝
A✝ B✝ C : Finset α✝
α : Type u_2
inst✝¹ : AddCommGroup α
inst✝ : DecidableEq α
A B : Finset α
hAB : ∀ A' ⊆ A, card (A + B) * card A' ≤ card (A' + B) * card A
n : ℕ
⊢ ↑(card (A + n • B)) ≤ (↑(card (A + B)) / ↑(card A)) ^ n * ↑(card A)

Next tactic:
obtain rfl | hA := A.eq_empty_or_nonempty
theorem card_add_nsmul_le {α : Type*} [AddCommGroup α] [DecidableEq α] {A B : Finset α}
    (hAB : ∀ (A') (_ : A' ⊆ A), (A + B).card * A'.card ≤ (A' + B).card * A.card) (n : ℕ) :
    (A + n • B).card ≤ ((A + B).card / A.card : ℚ≥0) ^ n * A.card := by
  obtain rfl | hA := A.eq_empty_or_nonempty
  · 

Proof state:
case inl
α✝ : Type u_1
inst✝³ : CommGroup α✝
inst✝² : DecidableEq α✝
A B✝ C : Finset α✝
α : Type u_2
inst✝¹ : AddCommGroup α
inst✝ : DecidableEq α
B : Finset α
n : ℕ
hAB : ∀ A' ⊆ ∅, card (∅ + B) * card A' ≤ card (A' + B) * card ∅
⊢ ↑(card (∅ + n • B)) ≤ (↑(card (∅ + B)) / ↑(card ∅)) ^ n * ↑(card ∅)

Next tactic:
simp
theorem card_add_nsmul_le {α : Type*} [AddCommGroup α] [DecidableEq α] {A B : Finset α}
    (hAB : ∀ (A') (_ : A' ⊆ A), (A + B).card * A'.card ≤ (A' + B).card * A.card) (n : ℕ) :
    (A + n • B).card ≤ ((A + B).card / A.card : ℚ≥0) ^ n * A.card := by
  obtain rfl | hA := A.eq_empty_or_nonempty
  · simp
  

Proof state:
case inr
α✝ : Type u_1
inst✝³ : CommGroup α✝
inst✝² : DecidableEq α✝
A✝ B✝ C : Finset α✝
α : Type u_2
inst✝¹ : AddCommGroup α
inst✝ : DecidableEq α
A B : Finset α
hAB : ∀ A' ⊆ A, card (A + B) * card A' ≤ card (A' + B) * card A
n : ℕ
hA : Finset.Nonempty A
⊢ ↑(card (A + n • B)) ≤ (↑(card (A + B)) / ↑(card A)) ^ n * ↑(card A)

Next tactic:
induction' n with n ih
theorem card_add_nsmul_le {α : Type*} [AddCommGroup α] [DecidableEq α] {A B : Finset α}
    (hAB : ∀ (A') (_ : A' ⊆ A), (A + B).card * A'.card ≤ (A' + B).card * A.card) (n : ℕ) :
    (A + n • B).card ≤ ((A + B).card / A.card : ℚ≥0) ^ n * A.card := by
  obtain rfl | hA := A.eq_empty_or_nonempty
  · simp
  induction' n with n ih
  · 

Proof state:
case inr.zero
α✝ : Type u_1
inst✝³ : CommGroup α✝
inst✝² : DecidableEq α✝
A✝ B✝ C : Finset α✝
α : Type u_2
inst✝¹ : AddCommGroup α
inst✝ : DecidableEq α
A B : Finset α
hAB : ∀ A' ⊆ A, card (A + B) * card A' ≤ card (A' + B) * card A
hA : Finset.Nonempty A
⊢ ↑(card (A + zero • B)) ≤ (↑(card (A + B)) / ↑(card A)) ^ zero * ↑(card A)

Next tactic:
simp
theorem card_add_nsmul_le {α : Type*} [AddCommGroup α] [DecidableEq α] {A B : Finset α}
    (hAB : ∀ (A') (_ : A' ⊆ A), (A + B).card * A'.card ≤ (A' + B).card * A.card) (n : ℕ) :
    (A + n • B).card ≤ ((A + B).card / A.card : ℚ≥0) ^ n * A.card := by
  obtain rfl | hA := A.eq_empty_or_nonempty
  · simp
  induction' n with n ih
  · simp
  

Proof state:
case inr.succ
α✝ : Type u_1
inst✝³ : CommGroup α✝
inst✝² : DecidableEq α✝
A✝ B✝ C : Finset α✝
α : Type u_2
inst✝¹ : AddCommGroup α
inst✝ : DecidableEq α
A B : Finset α
hAB : ∀ A' ⊆ A, card (A + B) * card A' ≤ card (A' + B) * card A
hA : Finset.Nonempty A
n : ℕ
ih : ↑(card (A + n • B)) ≤ (↑(card (A + B)) / ↑(card A)) ^ n * ↑(card A)
⊢ ↑(card (A + succ n • B)) ≤ (↑(card (A + B)) / ↑(card A)) ^ succ n * ↑(card A)

Next tactic:
rw [succ_nsmul, ← add_assoc, _root_.pow_succ, mul_assoc, ← mul_div_right_comm, le_div_iff,
    ← cast_mul]