/-
Copyright (c) 2022 Yaël Dillies, George Shakan. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Yaël Dillies, George Shakan

! This file was ported from Lean 3 source module combinatorics.additive.pluennecke_ruzsa
! leanprover-community/mathlib commit 3dadefa3f544b1db6214777fe47910739b54c66a
! Please do not edit these lines, except to modify the commit id
! if you have ported upstream changes.
-/
import Mathbin.Combinatorics.DoubleCounting
import Mathbin.Data.Finset.Pointwise
import Mathbin.Data.Rat.Nnrat

/-!
# The Plünnecke-Ruzsa inequality

> THIS FILE IS SYNCHRONIZED WITH MATHLIB4.
> Any changes to this file require a corresponding PR to mathlib4.

This file proves Ruzsa's triangle inequality, the Plünnecke-Petridis lemma, and the Plünnecke-Ruzsa
inequality.

## Main declarations

* `finset.card_sub_mul_le_card_sub_mul_card_sub`: Ruzsa's triangle inequality, difference version.
* `finset.card_add_mul_le_card_add_mul_card_add`: Ruzsa's triangle inequality, sum version.
* `finset.pluennecke_petridis`: The Plünnecke-Petridis lemma.
* `finset.card_smul_div_smul_le`: The Plünnecke-Ruzsa inequality.

## References

* [Giorgis Petridis, *The Plünnecke-Ruzsa inequality: an overview*][petridis2014]
* [Terrence Tao, Van Vu, *Additive Combinatorics][tao-vu]
-/

open Nat

open NNRat Pointwise

namespace Finset

variable {α : Type _} [CommGroup α] [DecidableEq α] {A B C : Finset α}

/- warning: finset.card_div_mul_le_card_div_mul_card_div -> Finset.card_div_mul_le_card_div_mul_card_div is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : CommGroup.{u1} α] [_inst_2 : DecidableEq.{succ u1} α] (A : Finset.{u1} α) (B : Finset.{u1} α) (C : Finset.{u1} α), LE.le.{0} Nat Nat.hasLe (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat Nat.hasMul) (Finset.card.{u1} α (HDiv.hDiv.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHDiv.{u1} (Finset.{u1} α) (Finset.div.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (DivInvMonoid.toHasDiv.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))) A C)) (Finset.card.{u1} α B)) (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat Nat.hasMul) (Finset.card.{u1} α (HDiv.hDiv.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHDiv.{u1} (Finset.{u1} α) (Finset.div.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (DivInvMonoid.toHasDiv.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))) A B)) (Finset.card.{u1} α (HDiv.hDiv.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHDiv.{u1} (Finset.{u1} α) (Finset.div.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (DivInvMonoid.toHasDiv.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))) B C)))
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : CommGroup.{u1} α] [_inst_2 : DecidableEq.{succ u1} α] (A : Finset.{u1} α) (B : Finset.{u1} α) (C : Finset.{u1} α), LE.le.{0} Nat instLENat (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat instMulNat) (Finset.card.{u1} α (HDiv.hDiv.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHDiv.{u1} (Finset.{u1} α) (Finset.div.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (DivInvMonoid.toDiv.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))) A C)) (Finset.card.{u1} α B)) (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat instMulNat) (Finset.card.{u1} α (HDiv.hDiv.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHDiv.{u1} (Finset.{u1} α) (Finset.div.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (DivInvMonoid.toDiv.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))) A B)) (Finset.card.{u1} α (HDiv.hDiv.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHDiv.{u1} (Finset.{u1} α) (Finset.div.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (DivInvMonoid.toDiv.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))) B C)))
Case conversion may be inaccurate. Consider using '#align finset.card_div_mul_le_card_div_mul_card_div Finset.card_div_mul_le_card_div_mul_card_divₓ'. -/
/-- **Ruzsa's triangle inequality**. Division version. -/
@[to_additive card_sub_mul_le_card_sub_mul_card_sub
      "**Ruzsa's triangle inequality**. Subtraction version."]
theorem card_div_mul_le_card_div_mul_card_div (A B C : Finset α) :
    (A / C).card * B.card ≤ (A / B).card * (B / C).card :=
  by
  rw [← card_product (A / B), ← mul_one (Finset.product _ _).card]
  refine'
    card_mul_le_card_mul (fun b ac => ac.1 * ac.2 = b) (fun x hx => _) fun x hx =>
      card_le_one_iff.2 fun u v hu hv =>
        ((mem_bipartite_below _).1 hu).2.symm.trans ((mem_bipartite_below _).1 hv).2
  obtain ⟨a, c, ha, hc, rfl⟩ := mem_div.1 hx
  refine' card_le_card_of_inj_on (fun b => (a / b, b / c)) (fun b hb => _) fun b₁ _ b₂ _ h => _
  · rw [mem_bipartite_above]
    exact ⟨mk_mem_product (div_mem_div ha hb) (div_mem_div hb hc), div_mul_div_cancel' _ _ _⟩
  · exact div_right_injective (Prod.ext_iff.1 h).1
#align finset.card_div_mul_le_card_div_mul_card_div Finset.card_div_mul_le_card_div_mul_card_div
#align finset.card_sub_mul_le_card_sub_mul_card_sub Finset.card_sub_mul_le_card_sub_mul_card_sub

/- warning: finset.card_div_mul_le_card_mul_mul_card_mul -> Finset.card_div_mul_le_card_mul_mul_card_mul is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : CommGroup.{u1} α] [_inst_2 : DecidableEq.{succ u1} α] (A : Finset.{u1} α) (B : Finset.{u1} α) (C : Finset.{u1} α), LE.le.{0} Nat Nat.hasLe (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat Nat.hasMul) (Finset.card.{u1} α (HDiv.hDiv.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHDiv.{u1} (Finset.{u1} α) (Finset.div.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (DivInvMonoid.toHasDiv.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))) A C)) (Finset.card.{u1} α B)) (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat Nat.hasMul) (Finset.card.{u1} α (HMul.hMul.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHMul.{u1} (Finset.{u1} α) (Finset.mul.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))))) A B)) (Finset.card.{u1} α (HMul.hMul.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHMul.{u1} (Finset.{u1} α) (Finset.mul.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))))) B C)))
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : CommGroup.{u1} α] [_inst_2 : DecidableEq.{succ u1} α] (A : Finset.{u1} α) (B : Finset.{u1} α) (C : Finset.{u1} α), LE.le.{0} Nat instLENat (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat instMulNat) (Finset.card.{u1} α (HDiv.hDiv.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHDiv.{u1} (Finset.{u1} α) (Finset.div.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (DivInvMonoid.toDiv.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))) A C)) (Finset.card.{u1} α B)) (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat instMulNat) (Finset.card.{u1} α (HMul.hMul.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHMul.{u1} (Finset.{u1} α) (Finset.mul.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))))) A B)) (Finset.card.{u1} α (HMul.hMul.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHMul.{u1} (Finset.{u1} α) (Finset.mul.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))))) B C)))
Case conversion may be inaccurate. Consider using '#align finset.card_div_mul_le_card_mul_mul_card_mul Finset.card_div_mul_le_card_mul_mul_card_mulₓ'. -/
/-- **Ruzsa's triangle inequality**. Div-mul-mul version. -/
@[to_additive card_sub_mul_le_card_add_mul_card_add
      "**Ruzsa's triangle inequality**. Sub-add-add version."]
theorem card_div_mul_le_card_mul_mul_card_mul (A B C : Finset α) :
    (A / C).card * B.card ≤ (A * B).card * (B * C).card :=
  by
  rw [← div_inv_eq_mul, ← card_inv B, ← card_inv (B * C), mul_inv, ← div_eq_mul_inv]
  exact card_div_mul_le_card_div_mul_card_div _ _ _
#align finset.card_div_mul_le_card_mul_mul_card_mul Finset.card_div_mul_le_card_mul_mul_card_mul
#align finset.card_sub_mul_le_card_add_mul_card_add Finset.card_sub_mul_le_card_add_mul_card_add

/- warning: finset.card_mul_mul_le_card_div_mul_card_mul -> Finset.card_mul_mul_le_card_div_mul_card_mul is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : CommGroup.{u1} α] [_inst_2 : DecidableEq.{succ u1} α] (A : Finset.{u1} α) (B : Finset.{u1} α) (C : Finset.{u1} α), LE.le.{0} Nat Nat.hasLe (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat Nat.hasMul) (Finset.card.{u1} α (HMul.hMul.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHMul.{u1} (Finset.{u1} α) (Finset.mul.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))))) A C)) (Finset.card.{u1} α B)) (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat Nat.hasMul) (Finset.card.{u1} α (HDiv.hDiv.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHDiv.{u1} (Finset.{u1} α) (Finset.div.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (DivInvMonoid.toHasDiv.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))) A B)) (Finset.card.{u1} α (HMul.hMul.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHMul.{u1} (Finset.{u1} α) (Finset.mul.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))))) B C)))
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : CommGroup.{u1} α] [_inst_2 : DecidableEq.{succ u1} α] (A : Finset.{u1} α) (B : Finset.{u1} α) (C : Finset.{u1} α), LE.le.{0} Nat instLENat (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat instMulNat) (Finset.card.{u1} α (HMul.hMul.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHMul.{u1} (Finset.{u1} α) (Finset.mul.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))))) A C)) (Finset.card.{u1} α B)) (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat instMulNat) (Finset.card.{u1} α (HDiv.hDiv.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHDiv.{u1} (Finset.{u1} α) (Finset.div.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (DivInvMonoid.toDiv.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))) A B)) (Finset.card.{u1} α (HMul.hMul.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHMul.{u1} (Finset.{u1} α) (Finset.mul.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))))) B C)))
Case conversion may be inaccurate. Consider using '#align finset.card_mul_mul_le_card_div_mul_card_mul Finset.card_mul_mul_le_card_div_mul_card_mulₓ'. -/
/-- **Ruzsa's triangle inequality**. Mul-div-div version. -/
@[to_additive card_add_mul_le_card_sub_mul_card_add
      "**Ruzsa's triangle inequality**. Add-sub-sub version."]
theorem card_mul_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_inv_eq_mul B]
  exact card_div_mul_le_card_div_mul_card_div _ _ _
#align finset.card_mul_mul_le_card_div_mul_card_mul Finset.card_mul_mul_le_card_div_mul_card_mul
#align finset.card_add_mul_le_card_sub_mul_card_add Finset.card_add_mul_le_card_sub_mul_card_add

/- warning: finset.card_mul_mul_le_card_mul_mul_card_div -> Finset.card_mul_mul_le_card_mul_mul_card_div is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : CommGroup.{u1} α] [_inst_2 : DecidableEq.{succ u1} α] (A : Finset.{u1} α) (B : Finset.{u1} α) (C : Finset.{u1} α), LE.le.{0} Nat Nat.hasLe (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat Nat.hasMul) (Finset.card.{u1} α (HMul.hMul.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHMul.{u1} (Finset.{u1} α) (Finset.mul.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))))) A C)) (Finset.card.{u1} α B)) (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat Nat.hasMul) (Finset.card.{u1} α (HMul.hMul.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHMul.{u1} (Finset.{u1} α) (Finset.mul.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))))) A B)) (Finset.card.{u1} α (HDiv.hDiv.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHDiv.{u1} (Finset.{u1} α) (Finset.div.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (DivInvMonoid.toHasDiv.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))) B C)))
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : CommGroup.{u1} α] [_inst_2 : DecidableEq.{succ u1} α] (A : Finset.{u1} α) (B : Finset.{u1} α) (C : Finset.{u1} α), LE.le.{0} Nat instLENat (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat instMulNat) (Finset.card.{u1} α (HMul.hMul.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHMul.{u1} (Finset.{u1} α) (Finset.mul.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))))) A C)) (Finset.card.{u1} α B)) (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat instMulNat) (Finset.card.{u1} α (HMul.hMul.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHMul.{u1} (Finset.{u1} α) (Finset.mul.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))))) A B)) (Finset.card.{u1} α (HDiv.hDiv.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHDiv.{u1} (Finset.{u1} α) (Finset.div.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (DivInvMonoid.toDiv.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))) B C)))
Case conversion may be inaccurate. Consider using '#align finset.card_mul_mul_le_card_mul_mul_card_div Finset.card_mul_mul_le_card_mul_mul_card_divₓ'. -/
/-- **Ruzsa's triangle inequality**. Mul-mul-div version. -/
@[to_additive card_add_mul_le_card_add_mul_card_sub
      "**Ruzsa's triangle inequality**. Add-add-sub version."]
theorem card_mul_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_inv_eq_mul, div_eq_mul_inv B]
  exact card_div_mul_le_card_mul_mul_card_mul _ _ _
#align finset.card_mul_mul_le_card_mul_mul_card_div Finset.card_mul_mul_le_card_mul_mul_card_div
#align finset.card_add_mul_le_card_add_mul_card_sub Finset.card_add_mul_le_card_add_mul_card_sub

/- warning: finset.mul_pluennecke_petridis -> Finset.mul_pluennecke_petridis is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : CommGroup.{u1} α] [_inst_2 : DecidableEq.{succ u1} α] {A : Finset.{u1} α} {B : Finset.{u1} α} (C : Finset.{u1} α), (forall (A' : Finset.{u1} α), (HasSubset.Subset.{u1} (Finset.{u1} α) (Finset.hasSubset.{u1} α) A' A) -> (LE.le.{0} Nat Nat.hasLe (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat Nat.hasMul) (Finset.card.{u1} α (HMul.hMul.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHMul.{u1} (Finset.{u1} α) (Finset.mul.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))))) A B)) (Finset.card.{u1} α A')) (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat Nat.hasMul) (Finset.card.{u1} α (HMul.hMul.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHMul.{u1} (Finset.{u1} α) (Finset.mul.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))))) A' B)) (Finset.card.{u1} α A)))) -> (LE.le.{0} Nat Nat.hasLe (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat Nat.hasMul) (Finset.card.{u1} α (HMul.hMul.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHMul.{u1} (Finset.{u1} α) (Finset.mul.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))))) (HMul.hMul.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHMul.{u1} (Finset.{u1} α) (Finset.mul.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))))) A B) C)) (Finset.card.{u1} α A)) (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat Nat.hasMul) (Finset.card.{u1} α (HMul.hMul.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHMul.{u1} (Finset.{u1} α) (Finset.mul.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))))) A B)) (Finset.card.{u1} α (HMul.hMul.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHMul.{u1} (Finset.{u1} α) (Finset.mul.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))))) A C))))
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : CommGroup.{u1} α] [_inst_2 : DecidableEq.{succ u1} α] {A : Finset.{u1} α} {B : Finset.{u1} α} (C : Finset.{u1} α), (forall (A' : Finset.{u1} α), (HasSubset.Subset.{u1} (Finset.{u1} α) (Finset.instHasSubsetFinset.{u1} α) A' A) -> (LE.le.{0} Nat instLENat (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat instMulNat) (Finset.card.{u1} α (HMul.hMul.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHMul.{u1} (Finset.{u1} α) (Finset.mul.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))))) A B)) (Finset.card.{u1} α A')) (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat instMulNat) (Finset.card.{u1} α (HMul.hMul.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHMul.{u1} (Finset.{u1} α) (Finset.mul.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))))) A' B)) (Finset.card.{u1} α A)))) -> (LE.le.{0} Nat instLENat (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat instMulNat) (Finset.card.{u1} α (HMul.hMul.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHMul.{u1} (Finset.{u1} α) (Finset.mul.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))))) (HMul.hMul.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHMul.{u1} (Finset.{u1} α) (Finset.mul.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))))) A B) C)) (Finset.card.{u1} α A)) (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat instMulNat) (Finset.card.{u1} α (HMul.hMul.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHMul.{u1} (Finset.{u1} α) (Finset.mul.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))))) A B)) (Finset.card.{u1} α (HMul.hMul.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHMul.{u1} (Finset.{u1} α) (Finset.mul.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))))) A C))))
Case conversion may be inaccurate. Consider using '#align finset.mul_pluennecke_petridis Finset.mul_pluennecke_petridisₓ'. -/
/- ./././Mathport/Syntax/Translate/Basic.lean:635:2: warning: expanding binder collection (A' «expr ⊆ » A) -/
@[to_additive]
theorem mul_pluennecke_petridis (C : Finset α)
    (hA : ∀ (A') (_ : A' ⊆ A), (A * B).card * A'.card ≤ (A' * B).card * A.card) :
    (A * B * C).card * A.card ≤ (A * B).card * (A * C).card :=
  by
  induction' C using Finset.induction_on with x C hc ih
  · simp
  set A' := A ∩ (A * C / {x}) with hA'
  set C' := insert x C with hC'
  have h₀ : A' * {x} = A * {x} ∩ (A * C) := by
    rw [hA', inter_mul_singleton, (is_unit_singleton x).div_mul_cancelₓ]
  have h₁ : A * B * C' = A * B * C ∪ (A * B * {x}) \ (A' * B * {x}) :=
    by
    rw [hC', insert_eq, union_comm, mul_union]
    refine' (sup_sdiff_eq_sup _).symm
    rw [mul_right_comm, mul_right_comm A, h₀]
    exact mul_subset_mul_right (inter_subset_right _ _)
  have h₂ : A' * B * {x} ⊆ A * B * {x} :=
    mul_subset_mul_right (mul_subset_mul_right <| inter_subset_left _ _)
  have h₃ : (A * B * C').card ≤ (A * B * C).card + (A * B).card - (A' * B).card :=
    by
    rw [h₁]
    refine' (card_union_le _ _).trans_eq _
    rw [card_sdiff h₂, ← add_tsub_assoc_of_le (card_le_of_subset h₂), card_mul_singleton,
      card_mul_singleton]
  refine' (mul_le_mul_right' h₃ _).trans _
  rw [tsub_mul, add_mul]
  refine' (tsub_le_tsub (add_le_add_right ih _) <| hA _ <| inter_subset_left _ _).trans_eq _
  rw [← mul_add, ← mul_tsub, ← hA', insert_eq, mul_union, ← card_mul_singleton A x, ←
    card_mul_singleton A' x, add_comm (card _), h₀,
    eq_tsub_of_add_eq (card_union_add_card_inter _ _)]
#align finset.mul_pluennecke_petridis Finset.mul_pluennecke_petridis
#align finset.add_pluennecke_petridis Finset.add_pluennecke_petridis

/-! ### Sum triangle inequality -/

/- ./././Mathport/Syntax/Translate/Basic.lean:635:2: warning: expanding binder collection (A' «expr ⊆ » A) -/
-- Auxiliary lemma for Ruzsa's triangle sum inequality, and the Plünnecke-Ruzsa inequality.
@[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
  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)
#align finset.mul_aux finset.mul_aux

/- warning: finset.card_mul_mul_card_le_card_mul_mul_card_mul -> Finset.card_mul_mul_card_le_card_mul_mul_card_mul is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : CommGroup.{u1} α] [_inst_2 : DecidableEq.{succ u1} α] (A : Finset.{u1} α) (B : Finset.{u1} α) (C : Finset.{u1} α), LE.le.{0} Nat Nat.hasLe (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat Nat.hasMul) (Finset.card.{u1} α (HMul.hMul.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHMul.{u1} (Finset.{u1} α) (Finset.mul.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))))) A C)) (Finset.card.{u1} α B)) (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat Nat.hasMul) (Finset.card.{u1} α (HMul.hMul.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHMul.{u1} (Finset.{u1} α) (Finset.mul.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))))) A B)) (Finset.card.{u1} α (HMul.hMul.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHMul.{u1} (Finset.{u1} α) (Finset.mul.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))))) B C)))
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : CommGroup.{u1} α] [_inst_2 : DecidableEq.{succ u1} α] (A : Finset.{u1} α) (B : Finset.{u1} α) (C : Finset.{u1} α), LE.le.{0} Nat instLENat (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat instMulNat) (Finset.card.{u1} α (HMul.hMul.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHMul.{u1} (Finset.{u1} α) (Finset.mul.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))))) A C)) (Finset.card.{u1} α B)) (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat instMulNat) (Finset.card.{u1} α (HMul.hMul.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHMul.{u1} (Finset.{u1} α) (Finset.mul.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))))) A B)) (Finset.card.{u1} α (HMul.hMul.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHMul.{u1} (Finset.{u1} α) (Finset.mul.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))))) B C)))
Case conversion may be inaccurate. Consider using '#align finset.card_mul_mul_card_le_card_mul_mul_card_mul Finset.card_mul_mul_card_le_card_mul_mul_card_mulₓ'. -/
/-- **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 _
  exact_mod_cast mul_pluennecke_petridis C (mul_aux hU.1 hU.2 hUA)
#align finset.card_mul_mul_card_le_card_mul_mul_card_mul Finset.card_mul_mul_card_le_card_mul_mul_card_mul
#align finset.card_add_mul_card_le_card_add_mul_card_add Finset.card_add_mul_card_le_card_add_mul_card_add

/- warning: finset.card_mul_mul_le_card_div_mul_card_div -> Finset.card_mul_mul_le_card_div_mul_card_div is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : CommGroup.{u1} α] [_inst_2 : DecidableEq.{succ u1} α] (A : Finset.{u1} α) (B : Finset.{u1} α) (C : Finset.{u1} α), LE.le.{0} Nat Nat.hasLe (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat Nat.hasMul) (Finset.card.{u1} α (HMul.hMul.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHMul.{u1} (Finset.{u1} α) (Finset.mul.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))))) A C)) (Finset.card.{u1} α B)) (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat Nat.hasMul) (Finset.card.{u1} α (HDiv.hDiv.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHDiv.{u1} (Finset.{u1} α) (Finset.div.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (DivInvMonoid.toHasDiv.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))) A B)) (Finset.card.{u1} α (HDiv.hDiv.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHDiv.{u1} (Finset.{u1} α) (Finset.div.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (DivInvMonoid.toHasDiv.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))) B C)))
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : CommGroup.{u1} α] [_inst_2 : DecidableEq.{succ u1} α] (A : Finset.{u1} α) (B : Finset.{u1} α) (C : Finset.{u1} α), LE.le.{0} Nat instLENat (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat instMulNat) (Finset.card.{u1} α (HMul.hMul.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHMul.{u1} (Finset.{u1} α) (Finset.mul.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))))) A C)) (Finset.card.{u1} α B)) (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat instMulNat) (Finset.card.{u1} α (HDiv.hDiv.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHDiv.{u1} (Finset.{u1} α) (Finset.div.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (DivInvMonoid.toDiv.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))) A B)) (Finset.card.{u1} α (HDiv.hDiv.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHDiv.{u1} (Finset.{u1} α) (Finset.div.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (DivInvMonoid.toDiv.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))) B C)))
Case conversion may be inaccurate. Consider using '#align finset.card_mul_mul_le_card_div_mul_card_div Finset.card_mul_mul_le_card_div_mul_card_divₓ'. -/
/-- **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]
  exact card_mul_mul_card_le_card_mul_mul_card_mul _ _ _
#align finset.card_mul_mul_le_card_div_mul_card_div Finset.card_mul_mul_le_card_div_mul_card_div

/- warning: finset.card_div_mul_le_card_mul_mul_card_div -> Finset.card_div_mul_le_card_mul_mul_card_div is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : CommGroup.{u1} α] [_inst_2 : DecidableEq.{succ u1} α] (A : Finset.{u1} α) (B : Finset.{u1} α) (C : Finset.{u1} α), LE.le.{0} Nat Nat.hasLe (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat Nat.hasMul) (Finset.card.{u1} α (HDiv.hDiv.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHDiv.{u1} (Finset.{u1} α) (Finset.div.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (DivInvMonoid.toHasDiv.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))) A C)) (Finset.card.{u1} α B)) (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat Nat.hasMul) (Finset.card.{u1} α (HMul.hMul.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHMul.{u1} (Finset.{u1} α) (Finset.mul.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))))) A B)) (Finset.card.{u1} α (HDiv.hDiv.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHDiv.{u1} (Finset.{u1} α) (Finset.div.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (DivInvMonoid.toHasDiv.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))) B C)))
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : CommGroup.{u1} α] [_inst_2 : DecidableEq.{succ u1} α] (A : Finset.{u1} α) (B : Finset.{u1} α) (C : Finset.{u1} α), LE.le.{0} Nat instLENat (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat instMulNat) (Finset.card.{u1} α (HDiv.hDiv.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHDiv.{u1} (Finset.{u1} α) (Finset.div.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (DivInvMonoid.toDiv.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))) A C)) (Finset.card.{u1} α B)) (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat instMulNat) (Finset.card.{u1} α (HMul.hMul.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHMul.{u1} (Finset.{u1} α) (Finset.mul.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))))) A B)) (Finset.card.{u1} α (HDiv.hDiv.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHDiv.{u1} (Finset.{u1} α) (Finset.div.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (DivInvMonoid.toDiv.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))) B C)))
Case conversion may be inaccurate. Consider using '#align finset.card_div_mul_le_card_mul_mul_card_div Finset.card_div_mul_le_card_mul_mul_card_divₓ'. -/
/-- **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]
  exact card_mul_mul_card_le_card_mul_mul_card_mul _ _ _
#align finset.card_div_mul_le_card_mul_mul_card_div Finset.card_div_mul_le_card_mul_mul_card_div

/- warning: finset.card_div_mul_le_card_div_mul_card_mul -> Finset.card_div_mul_le_card_div_mul_card_mul is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : CommGroup.{u1} α] [_inst_2 : DecidableEq.{succ u1} α] (A : Finset.{u1} α) (B : Finset.{u1} α) (C : Finset.{u1} α), LE.le.{0} Nat Nat.hasLe (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat Nat.hasMul) (Finset.card.{u1} α (HDiv.hDiv.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHDiv.{u1} (Finset.{u1} α) (Finset.div.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (DivInvMonoid.toHasDiv.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))) A C)) (Finset.card.{u1} α B)) (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat Nat.hasMul) (Finset.card.{u1} α (HDiv.hDiv.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHDiv.{u1} (Finset.{u1} α) (Finset.div.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (DivInvMonoid.toHasDiv.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))) A B)) (Finset.card.{u1} α (HMul.hMul.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHMul.{u1} (Finset.{u1} α) (Finset.mul.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))))) B C)))
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : CommGroup.{u1} α] [_inst_2 : DecidableEq.{succ u1} α] (A : Finset.{u1} α) (B : Finset.{u1} α) (C : Finset.{u1} α), LE.le.{0} Nat instLENat (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat instMulNat) (Finset.card.{u1} α (HDiv.hDiv.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHDiv.{u1} (Finset.{u1} α) (Finset.div.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (DivInvMonoid.toDiv.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))) A C)) (Finset.card.{u1} α B)) (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat instMulNat) (Finset.card.{u1} α (HDiv.hDiv.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHDiv.{u1} (Finset.{u1} α) (Finset.div.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (DivInvMonoid.toDiv.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))) A B)) (Finset.card.{u1} α (HMul.hMul.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHMul.{u1} (Finset.{u1} α) (Finset.mul.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))))) B C)))
Case conversion may be inaccurate. Consider using '#align finset.card_div_mul_le_card_div_mul_card_mul Finset.card_div_mul_le_card_div_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
  rw [← div_inv_eq_mul, div_eq_mul_inv]
  exact card_mul_mul_le_card_div_mul_card_div _ _ _
#align finset.card_div_mul_le_card_div_mul_card_mul Finset.card_div_mul_le_card_div_mul_card_mul

/- warning: finset.card_add_nsmul_le -> Finset.card_add_nsmul_le is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_3 : AddCommGroup.{u1} α] [_inst_4 : DecidableEq.{succ u1} α] {A : Finset.{u1} α} {B : Finset.{u1} α}, (forall (A' : Finset.{u1} α), (HasSubset.Subset.{u1} (Finset.{u1} α) (Finset.hasSubset.{u1} α) A' A) -> (LE.le.{0} Nat Nat.hasLe (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat Nat.hasMul) (Finset.card.{u1} α (HAdd.hAdd.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHAdd.{u1} (Finset.{u1} α) (Finset.add.{u1} α (fun (a : α) (b : α) => _inst_4 a b) (AddZeroClass.toHasAdd.{u1} α (AddMonoid.toAddZeroClass.{u1} α (SubNegMonoid.toAddMonoid.{u1} α (AddGroup.toSubNegMonoid.{u1} α (AddCommGroup.toAddGroup.{u1} α _inst_3))))))) A B)) (Finset.card.{u1} α A')) (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat Nat.hasMul) (Finset.card.{u1} α (HAdd.hAdd.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHAdd.{u1} (Finset.{u1} α) (Finset.add.{u1} α (fun (a : α) (b : α) => _inst_4 a b) (AddZeroClass.toHasAdd.{u1} α (AddMonoid.toAddZeroClass.{u1} α (SubNegMonoid.toAddMonoid.{u1} α (AddGroup.toSubNegMonoid.{u1} α (AddCommGroup.toAddGroup.{u1} α _inst_3))))))) A' B)) (Finset.card.{u1} α A)))) -> (forall (n : Nat), LE.le.{0} NNRat (Preorder.toLE.{0} NNRat (PartialOrder.toPreorder.{0} NNRat (OrderedCancelAddCommMonoid.toPartialOrder.{0} NNRat (StrictOrderedSemiring.toOrderedCancelAddCommMonoid.{0} NNRat (LinearOrderedSemiring.toStrictOrderedSemiring.{0} NNRat (LinearOrderedCommSemiring.toLinearOrderedSemiring.{0} NNRat (LinearOrderedSemifield.toLinearOrderedCommSemiring.{0} NNRat (CanonicallyLinearOrderedSemifield.toLinearOrderedSemifield.{0} NNRat NNRat.canonicallyLinearOrderedSemifield)))))))) ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat NNRat (HasLiftT.mk.{1, 1} Nat NNRat (CoeTCₓ.coe.{1, 1} Nat NNRat (Nat.castCoe.{0} NNRat (AddMonoidWithOne.toNatCast.{0} NNRat (AddCommMonoidWithOne.toAddMonoidWithOne.{0} NNRat (NonAssocSemiring.toAddCommMonoidWithOne.{0} NNRat (Semiring.toNonAssocSemiring.{0} NNRat (StrictOrderedSemiring.toSemiring.{0} NNRat (LinearOrderedSemiring.toStrictOrderedSemiring.{0} NNRat (LinearOrderedCommSemiring.toLinearOrderedSemiring.{0} NNRat (LinearOrderedSemifield.toLinearOrderedCommSemiring.{0} NNRat (CanonicallyLinearOrderedSemifield.toLinearOrderedSemifield.{0} NNRat NNRat.canonicallyLinearOrderedSemifield)))))))))))) (Finset.card.{u1} α (HAdd.hAdd.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHAdd.{u1} (Finset.{u1} α) (Finset.add.{u1} α (fun (a : α) (b : α) => _inst_4 a b) (AddZeroClass.toHasAdd.{u1} α (AddMonoid.toAddZeroClass.{u1} α (SubNegMonoid.toAddMonoid.{u1} α (AddGroup.toSubNegMonoid.{u1} α (AddCommGroup.toAddGroup.{u1} α _inst_3))))))) A (SMul.smul.{0, u1} Nat (Finset.{u1} α) (Finset.nsmul.{u1} α (fun (a : α) (b : α) => _inst_4 a b) (AddZeroClass.toHasZero.{u1} α (AddMonoid.toAddZeroClass.{u1} α (SubNegMonoid.toAddMonoid.{u1} α (AddGroup.toSubNegMonoid.{u1} α (AddCommGroup.toAddGroup.{u1} α _inst_3))))) (AddZeroClass.toHasAdd.{u1} α (AddMonoid.toAddZeroClass.{u1} α (SubNegMonoid.toAddMonoid.{u1} α (AddGroup.toSubNegMonoid.{u1} α (AddCommGroup.toAddGroup.{u1} α _inst_3)))))) n B)))) (HMul.hMul.{0, 0, 0} NNRat NNRat NNRat (instHMul.{0} NNRat (Distrib.toHasMul.{0} NNRat (NonUnitalNonAssocSemiring.toDistrib.{0} NNRat (NonAssocSemiring.toNonUnitalNonAssocSemiring.{0} NNRat (Semiring.toNonAssocSemiring.{0} NNRat (StrictOrderedSemiring.toSemiring.{0} NNRat (LinearOrderedSemiring.toStrictOrderedSemiring.{0} NNRat (LinearOrderedCommSemiring.toLinearOrderedSemiring.{0} NNRat (LinearOrderedSemifield.toLinearOrderedCommSemiring.{0} NNRat (CanonicallyLinearOrderedSemifield.toLinearOrderedSemifield.{0} NNRat NNRat.canonicallyLinearOrderedSemifield)))))))))) (HPow.hPow.{0, 0, 0} NNRat Nat NNRat (instHPow.{0, 0} NNRat Nat (Monoid.Pow.{0} NNRat (MonoidWithZero.toMonoid.{0} NNRat (Semiring.toMonoidWithZero.{0} NNRat (StrictOrderedSemiring.toSemiring.{0} NNRat (LinearOrderedSemiring.toStrictOrderedSemiring.{0} NNRat (LinearOrderedCommSemiring.toLinearOrderedSemiring.{0} NNRat (LinearOrderedSemifield.toLinearOrderedCommSemiring.{0} NNRat (CanonicallyLinearOrderedSemifield.toLinearOrderedSemifield.{0} NNRat NNRat.canonicallyLinearOrderedSemifield))))))))) (HDiv.hDiv.{0, 0, 0} NNRat NNRat NNRat (instHDiv.{0} NNRat (DivInvMonoid.toHasDiv.{0} NNRat (GroupWithZero.toDivInvMonoid.{0} NNRat (DivisionSemiring.toGroupWithZero.{0} NNRat (Semifield.toDivisionSemiring.{0} NNRat (LinearOrderedSemifield.toSemifield.{0} NNRat (CanonicallyLinearOrderedSemifield.toLinearOrderedSemifield.{0} NNRat NNRat.canonicallyLinearOrderedSemifield))))))) ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat NNRat (HasLiftT.mk.{1, 1} Nat NNRat (CoeTCₓ.coe.{1, 1} Nat NNRat (Nat.castCoe.{0} NNRat (AddMonoidWithOne.toNatCast.{0} NNRat (AddCommMonoidWithOne.toAddMonoidWithOne.{0} NNRat (NonAssocSemiring.toAddCommMonoidWithOne.{0} NNRat (Semiring.toNonAssocSemiring.{0} NNRat (StrictOrderedSemiring.toSemiring.{0} NNRat (LinearOrderedSemiring.toStrictOrderedSemiring.{0} NNRat (LinearOrderedCommSemiring.toLinearOrderedSemiring.{0} NNRat (LinearOrderedSemifield.toLinearOrderedCommSemiring.{0} NNRat (CanonicallyLinearOrderedSemifield.toLinearOrderedSemifield.{0} NNRat NNRat.canonicallyLinearOrderedSemifield)))))))))))) (Finset.card.{u1} α (HAdd.hAdd.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHAdd.{u1} (Finset.{u1} α) (Finset.add.{u1} α (fun (a : α) (b : α) => _inst_4 a b) (AddZeroClass.toHasAdd.{u1} α (AddMonoid.toAddZeroClass.{u1} α (SubNegMonoid.toAddMonoid.{u1} α (AddGroup.toSubNegMonoid.{u1} α (AddCommGroup.toAddGroup.{u1} α _inst_3))))))) A B))) ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat NNRat (HasLiftT.mk.{1, 1} Nat NNRat (CoeTCₓ.coe.{1, 1} Nat NNRat (Nat.castCoe.{0} NNRat (AddMonoidWithOne.toNatCast.{0} NNRat (AddCommMonoidWithOne.toAddMonoidWithOne.{0} NNRat (NonAssocSemiring.toAddCommMonoidWithOne.{0} NNRat (Semiring.toNonAssocSemiring.{0} NNRat (StrictOrderedSemiring.toSemiring.{0} NNRat (LinearOrderedSemiring.toStrictOrderedSemiring.{0} NNRat (LinearOrderedCommSemiring.toLinearOrderedSemiring.{0} NNRat (LinearOrderedSemifield.toLinearOrderedCommSemiring.{0} NNRat (CanonicallyLinearOrderedSemifield.toLinearOrderedSemifield.{0} NNRat NNRat.canonicallyLinearOrderedSemifield)))))))))))) (Finset.card.{u1} α A))) n) ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat NNRat (HasLiftT.mk.{1, 1} Nat NNRat (CoeTCₓ.coe.{1, 1} Nat NNRat (Nat.castCoe.{0} NNRat (AddMonoidWithOne.toNatCast.{0} NNRat (AddCommMonoidWithOne.toAddMonoidWithOne.{0} NNRat (NonAssocSemiring.toAddCommMonoidWithOne.{0} NNRat (Semiring.toNonAssocSemiring.{0} NNRat (StrictOrderedSemiring.toSemiring.{0} NNRat (LinearOrderedSemiring.toStrictOrderedSemiring.{0} NNRat (LinearOrderedCommSemiring.toLinearOrderedSemiring.{0} NNRat (LinearOrderedSemifield.toLinearOrderedCommSemiring.{0} NNRat (CanonicallyLinearOrderedSemifield.toLinearOrderedSemifield.{0} NNRat NNRat.canonicallyLinearOrderedSemifield)))))))))))) (Finset.card.{u1} α A))))
but is expected to have type
  forall {α : Type.{u1}} [_inst_3 : AddCommGroup.{u1} α] [_inst_4 : DecidableEq.{succ u1} α] {A : Finset.{u1} α} {B : Finset.{u1} α}, (forall (A' : Finset.{u1} α), (HasSubset.Subset.{u1} (Finset.{u1} α) (Finset.instHasSubsetFinset.{u1} α) A' A) -> (LE.le.{0} Nat instLENat (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat instMulNat) (Finset.card.{u1} α (HAdd.hAdd.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHAdd.{u1} (Finset.{u1} α) (Finset.add.{u1} α (fun (a : α) (b : α) => _inst_4 a b) (AddZeroClass.toAdd.{u1} α (AddMonoid.toAddZeroClass.{u1} α (SubNegMonoid.toAddMonoid.{u1} α (AddGroup.toSubNegMonoid.{u1} α (AddCommGroup.toAddGroup.{u1} α _inst_3))))))) A B)) (Finset.card.{u1} α A')) (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat instMulNat) (Finset.card.{u1} α (HAdd.hAdd.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHAdd.{u1} (Finset.{u1} α) (Finset.add.{u1} α (fun (a : α) (b : α) => _inst_4 a b) (AddZeroClass.toAdd.{u1} α (AddMonoid.toAddZeroClass.{u1} α (SubNegMonoid.toAddMonoid.{u1} α (AddGroup.toSubNegMonoid.{u1} α (AddCommGroup.toAddGroup.{u1} α _inst_3))))))) A' B)) (Finset.card.{u1} α A)))) -> (forall (n : Nat), LE.le.{0} NNRat (Preorder.toLE.{0} NNRat (PartialOrder.toPreorder.{0} NNRat (StrictOrderedSemiring.toPartialOrder.{0} NNRat (LinearOrderedSemiring.toStrictOrderedSemiring.{0} NNRat (LinearOrderedCommSemiring.toLinearOrderedSemiring.{0} NNRat (LinearOrderedSemifield.toLinearOrderedCommSemiring.{0} NNRat (CanonicallyLinearOrderedSemifield.toLinearOrderedSemifield.{0} NNRat instNNRatCanonicallyLinearOrderedSemifield))))))) (Nat.cast.{0} NNRat (CanonicallyOrderedCommSemiring.toNatCast.{0} NNRat instNNRatCanonicallyOrderedCommSemiring) (Finset.card.{u1} α (HAdd.hAdd.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHAdd.{u1} (Finset.{u1} α) (Finset.add.{u1} α (fun (a : α) (b : α) => _inst_4 a b) (AddZeroClass.toAdd.{u1} α (AddMonoid.toAddZeroClass.{u1} α (SubNegMonoid.toAddMonoid.{u1} α (AddGroup.toSubNegMonoid.{u1} α (AddCommGroup.toAddGroup.{u1} α _inst_3))))))) A (HSMul.hSMul.{0, u1, u1} Nat (Finset.{u1} α) (Finset.{u1} α) (instHSMul.{0, u1} Nat (Finset.{u1} α) (Finset.nsmul.{u1} α (fun (a : α) (b : α) => _inst_4 a b) (NegZeroClass.toZero.{u1} α (SubNegZeroMonoid.toNegZeroClass.{u1} α (SubtractionMonoid.toSubNegZeroMonoid.{u1} α (SubtractionCommMonoid.toSubtractionMonoid.{u1} α (AddCommGroup.toDivisionAddCommMonoid.{u1} α _inst_3))))) (AddZeroClass.toAdd.{u1} α (AddMonoid.toAddZeroClass.{u1} α (SubNegMonoid.toAddMonoid.{u1} α (AddGroup.toSubNegMonoid.{u1} α (AddCommGroup.toAddGroup.{u1} α _inst_3))))))) n B)))) (HMul.hMul.{0, 0, 0} NNRat NNRat NNRat (instHMul.{0} NNRat (CanonicallyOrderedCommSemiring.toMul.{0} NNRat instNNRatCanonicallyOrderedCommSemiring)) (HPow.hPow.{0, 0, 0} NNRat Nat NNRat (instHPow.{0, 0} NNRat Nat (Monoid.Pow.{0} NNRat (MonoidWithZero.toMonoid.{0} NNRat (Semiring.toMonoidWithZero.{0} NNRat (StrictOrderedSemiring.toSemiring.{0} NNRat (LinearOrderedSemiring.toStrictOrderedSemiring.{0} NNRat (LinearOrderedCommSemiring.toLinearOrderedSemiring.{0} NNRat (LinearOrderedSemifield.toLinearOrderedCommSemiring.{0} NNRat (CanonicallyLinearOrderedSemifield.toLinearOrderedSemifield.{0} NNRat instNNRatCanonicallyLinearOrderedSemifield))))))))) (HDiv.hDiv.{0, 0, 0} NNRat NNRat NNRat (instHDiv.{0} NNRat (CanonicallyLinearOrderedSemifield.toDiv.{0} NNRat instNNRatCanonicallyLinearOrderedSemifield)) (Nat.cast.{0} NNRat (CanonicallyOrderedCommSemiring.toNatCast.{0} NNRat instNNRatCanonicallyOrderedCommSemiring) (Finset.card.{u1} α (HAdd.hAdd.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHAdd.{u1} (Finset.{u1} α) (Finset.add.{u1} α (fun (a : α) (b : α) => _inst_4 a b) (AddZeroClass.toAdd.{u1} α (AddMonoid.toAddZeroClass.{u1} α (SubNegMonoid.toAddMonoid.{u1} α (AddGroup.toSubNegMonoid.{u1} α (AddCommGroup.toAddGroup.{u1} α _inst_3))))))) A B))) (Nat.cast.{0} NNRat (CanonicallyOrderedCommSemiring.toNatCast.{0} NNRat instNNRatCanonicallyOrderedCommSemiring) (Finset.card.{u1} α A))) n) (Nat.cast.{0} NNRat (CanonicallyOrderedCommSemiring.toNatCast.{0} NNRat instNNRatCanonicallyOrderedCommSemiring) (Finset.card.{u1} α A))))
Case conversion may be inaccurate. Consider using '#align finset.card_add_nsmul_le Finset.card_add_nsmul_leₓ'. -/
/- ./././Mathport/Syntax/Translate/Basic.lean:635:2: warning: expanding binder collection (A' «expr ⊆ » A) -/
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 : ℚ≥0) ≤ ((A + B).card / A.card) ^ n * A.card :=
  by
  obtain rfl | hA := A.eq_empty_or_nonempty
  · simp
  induction' n with n ih
  · simp
  rw [succ_nsmul, ← add_assoc, pow_succ, mul_assoc, ← mul_div_right_comm, le_div_iff, ← cast_mul]
  swap; exact cast_pos.2 hA.card_pos
  refine' (cast_le.2 <| add_pluennecke_petridis _ hAB).trans _
  rw [cast_mul]
  exact mul_le_mul_of_nonneg_left ih (zero_le _)
#align finset.card_add_nsmul_le Finset.card_add_nsmul_le

/- warning: finset.card_mul_pow_le -> Finset.card_mul_pow_le is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : CommGroup.{u1} α] [_inst_2 : DecidableEq.{succ u1} α] {A : Finset.{u1} α} {B : Finset.{u1} α}, (forall (A' : Finset.{u1} α), (HasSubset.Subset.{u1} (Finset.{u1} α) (Finset.hasSubset.{u1} α) A' A) -> (LE.le.{0} Nat Nat.hasLe (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat Nat.hasMul) (Finset.card.{u1} α (HMul.hMul.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHMul.{u1} (Finset.{u1} α) (Finset.mul.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))))) A B)) (Finset.card.{u1} α A')) (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat Nat.hasMul) (Finset.card.{u1} α (HMul.hMul.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHMul.{u1} (Finset.{u1} α) (Finset.mul.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))))) A' B)) (Finset.card.{u1} α A)))) -> (forall (n : Nat), LE.le.{0} NNRat (Preorder.toLE.{0} NNRat (PartialOrder.toPreorder.{0} NNRat (OrderedCancelAddCommMonoid.toPartialOrder.{0} NNRat (StrictOrderedSemiring.toOrderedCancelAddCommMonoid.{0} NNRat (LinearOrderedSemiring.toStrictOrderedSemiring.{0} NNRat (LinearOrderedCommSemiring.toLinearOrderedSemiring.{0} NNRat (LinearOrderedSemifield.toLinearOrderedCommSemiring.{0} NNRat (CanonicallyLinearOrderedSemifield.toLinearOrderedSemifield.{0} NNRat NNRat.canonicallyLinearOrderedSemifield)))))))) ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat NNRat (HasLiftT.mk.{1, 1} Nat NNRat (CoeTCₓ.coe.{1, 1} Nat NNRat (Nat.castCoe.{0} NNRat (AddMonoidWithOne.toNatCast.{0} NNRat (AddCommMonoidWithOne.toAddMonoidWithOne.{0} NNRat (NonAssocSemiring.toAddCommMonoidWithOne.{0} NNRat (Semiring.toNonAssocSemiring.{0} NNRat (StrictOrderedSemiring.toSemiring.{0} NNRat (LinearOrderedSemiring.toStrictOrderedSemiring.{0} NNRat (LinearOrderedCommSemiring.toLinearOrderedSemiring.{0} NNRat (LinearOrderedSemifield.toLinearOrderedCommSemiring.{0} NNRat (CanonicallyLinearOrderedSemifield.toLinearOrderedSemifield.{0} NNRat NNRat.canonicallyLinearOrderedSemifield)))))))))))) (Finset.card.{u1} α (HMul.hMul.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHMul.{u1} (Finset.{u1} α) (Finset.mul.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))))) A (HPow.hPow.{u1, 0, u1} (Finset.{u1} α) Nat (Finset.{u1} α) (instHPow.{u1, 0} (Finset.{u1} α) Nat (Finset.npow.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (MulOneClass.toHasOne.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))) (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))))) B n)))) (HMul.hMul.{0, 0, 0} NNRat NNRat NNRat (instHMul.{0} NNRat (Distrib.toHasMul.{0} NNRat (NonUnitalNonAssocSemiring.toDistrib.{0} NNRat (NonAssocSemiring.toNonUnitalNonAssocSemiring.{0} NNRat (Semiring.toNonAssocSemiring.{0} NNRat (StrictOrderedSemiring.toSemiring.{0} NNRat (LinearOrderedSemiring.toStrictOrderedSemiring.{0} NNRat (LinearOrderedCommSemiring.toLinearOrderedSemiring.{0} NNRat (LinearOrderedSemifield.toLinearOrderedCommSemiring.{0} NNRat (CanonicallyLinearOrderedSemifield.toLinearOrderedSemifield.{0} NNRat NNRat.canonicallyLinearOrderedSemifield)))))))))) (HPow.hPow.{0, 0, 0} NNRat Nat NNRat (instHPow.{0, 0} NNRat Nat (Monoid.Pow.{0} NNRat (MonoidWithZero.toMonoid.{0} NNRat (Semiring.toMonoidWithZero.{0} NNRat (StrictOrderedSemiring.toSemiring.{0} NNRat (LinearOrderedSemiring.toStrictOrderedSemiring.{0} NNRat (LinearOrderedCommSemiring.toLinearOrderedSemiring.{0} NNRat (LinearOrderedSemifield.toLinearOrderedCommSemiring.{0} NNRat (CanonicallyLinearOrderedSemifield.toLinearOrderedSemifield.{0} NNRat NNRat.canonicallyLinearOrderedSemifield))))))))) (HDiv.hDiv.{0, 0, 0} NNRat NNRat NNRat (instHDiv.{0} NNRat (DivInvMonoid.toHasDiv.{0} NNRat (GroupWithZero.toDivInvMonoid.{0} NNRat (DivisionSemiring.toGroupWithZero.{0} NNRat (Semifield.toDivisionSemiring.{0} NNRat (LinearOrderedSemifield.toSemifield.{0} NNRat (CanonicallyLinearOrderedSemifield.toLinearOrderedSemifield.{0} NNRat NNRat.canonicallyLinearOrderedSemifield))))))) ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat NNRat (HasLiftT.mk.{1, 1} Nat NNRat (CoeTCₓ.coe.{1, 1} Nat NNRat (Nat.castCoe.{0} NNRat (AddMonoidWithOne.toNatCast.{0} NNRat (AddCommMonoidWithOne.toAddMonoidWithOne.{0} NNRat (NonAssocSemiring.toAddCommMonoidWithOne.{0} NNRat (Semiring.toNonAssocSemiring.{0} NNRat (StrictOrderedSemiring.toSemiring.{0} NNRat (LinearOrderedSemiring.toStrictOrderedSemiring.{0} NNRat (LinearOrderedCommSemiring.toLinearOrderedSemiring.{0} NNRat (LinearOrderedSemifield.toLinearOrderedCommSemiring.{0} NNRat (CanonicallyLinearOrderedSemifield.toLinearOrderedSemifield.{0} NNRat NNRat.canonicallyLinearOrderedSemifield)))))))))))) (Finset.card.{u1} α (HMul.hMul.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHMul.{u1} (Finset.{u1} α) (Finset.mul.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))))) A B))) ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat NNRat (HasLiftT.mk.{1, 1} Nat NNRat (CoeTCₓ.coe.{1, 1} Nat NNRat (Nat.castCoe.{0} NNRat (AddMonoidWithOne.toNatCast.{0} NNRat (AddCommMonoidWithOne.toAddMonoidWithOne.{0} NNRat (NonAssocSemiring.toAddCommMonoidWithOne.{0} NNRat (Semiring.toNonAssocSemiring.{0} NNRat (StrictOrderedSemiring.toSemiring.{0} NNRat (LinearOrderedSemiring.toStrictOrderedSemiring.{0} NNRat (LinearOrderedCommSemiring.toLinearOrderedSemiring.{0} NNRat (LinearOrderedSemifield.toLinearOrderedCommSemiring.{0} NNRat (CanonicallyLinearOrderedSemifield.toLinearOrderedSemifield.{0} NNRat NNRat.canonicallyLinearOrderedSemifield)))))))))))) (Finset.card.{u1} α A))) n) ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat NNRat (HasLiftT.mk.{1, 1} Nat NNRat (CoeTCₓ.coe.{1, 1} Nat NNRat (Nat.castCoe.{0} NNRat (AddMonoidWithOne.toNatCast.{0} NNRat (AddCommMonoidWithOne.toAddMonoidWithOne.{0} NNRat (NonAssocSemiring.toAddCommMonoidWithOne.{0} NNRat (Semiring.toNonAssocSemiring.{0} NNRat (StrictOrderedSemiring.toSemiring.{0} NNRat (LinearOrderedSemiring.toStrictOrderedSemiring.{0} NNRat (LinearOrderedCommSemiring.toLinearOrderedSemiring.{0} NNRat (LinearOrderedSemifield.toLinearOrderedCommSemiring.{0} NNRat (CanonicallyLinearOrderedSemifield.toLinearOrderedSemifield.{0} NNRat NNRat.canonicallyLinearOrderedSemifield)))))))))))) (Finset.card.{u1} α A))))
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : CommGroup.{u1} α] [_inst_2 : DecidableEq.{succ u1} α] {A : Finset.{u1} α} {B : Finset.{u1} α}, (forall (A' : Finset.{u1} α), (HasSubset.Subset.{u1} (Finset.{u1} α) (Finset.instHasSubsetFinset.{u1} α) A' A) -> (LE.le.{0} Nat instLENat (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat instMulNat) (Finset.card.{u1} α (HMul.hMul.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHMul.{u1} (Finset.{u1} α) (Finset.mul.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))))) A B)) (Finset.card.{u1} α A')) (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat instMulNat) (Finset.card.{u1} α (HMul.hMul.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHMul.{u1} (Finset.{u1} α) (Finset.mul.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))))) A' B)) (Finset.card.{u1} α A)))) -> (forall (n : Nat), LE.le.{0} NNRat (Preorder.toLE.{0} NNRat (PartialOrder.toPreorder.{0} NNRat (StrictOrderedSemiring.toPartialOrder.{0} NNRat (LinearOrderedSemiring.toStrictOrderedSemiring.{0} NNRat (LinearOrderedCommSemiring.toLinearOrderedSemiring.{0} NNRat (LinearOrderedSemifield.toLinearOrderedCommSemiring.{0} NNRat (CanonicallyLinearOrderedSemifield.toLinearOrderedSemifield.{0} NNRat instNNRatCanonicallyLinearOrderedSemifield))))))) (Nat.cast.{0} NNRat (CanonicallyOrderedCommSemiring.toNatCast.{0} NNRat instNNRatCanonicallyOrderedCommSemiring) (Finset.card.{u1} α (HMul.hMul.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHMul.{u1} (Finset.{u1} α) (Finset.mul.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))))) A (HPow.hPow.{u1, 0, u1} (Finset.{u1} α) Nat (Finset.{u1} α) (instHPow.{u1, 0} (Finset.{u1} α) Nat (Finset.npow.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (InvOneClass.toOne.{u1} α (DivInvOneMonoid.toInvOneClass.{u1} α (DivisionMonoid.toDivInvOneMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α (CommGroup.toDivisionCommMonoid.{u1} α _inst_1))))) (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))))) B n)))) (HMul.hMul.{0, 0, 0} NNRat NNRat NNRat (instHMul.{0} NNRat (CanonicallyOrderedCommSemiring.toMul.{0} NNRat instNNRatCanonicallyOrderedCommSemiring)) (HPow.hPow.{0, 0, 0} NNRat Nat NNRat (instHPow.{0, 0} NNRat Nat (Monoid.Pow.{0} NNRat (MonoidWithZero.toMonoid.{0} NNRat (Semiring.toMonoidWithZero.{0} NNRat (StrictOrderedSemiring.toSemiring.{0} NNRat (LinearOrderedSemiring.toStrictOrderedSemiring.{0} NNRat (LinearOrderedCommSemiring.toLinearOrderedSemiring.{0} NNRat (LinearOrderedSemifield.toLinearOrderedCommSemiring.{0} NNRat (CanonicallyLinearOrderedSemifield.toLinearOrderedSemifield.{0} NNRat instNNRatCanonicallyLinearOrderedSemifield))))))))) (HDiv.hDiv.{0, 0, 0} NNRat NNRat NNRat (instHDiv.{0} NNRat (CanonicallyLinearOrderedSemifield.toDiv.{0} NNRat instNNRatCanonicallyLinearOrderedSemifield)) (Nat.cast.{0} NNRat (CanonicallyOrderedCommSemiring.toNatCast.{0} NNRat instNNRatCanonicallyOrderedCommSemiring) (Finset.card.{u1} α (HMul.hMul.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHMul.{u1} (Finset.{u1} α) (Finset.mul.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))))) A B))) (Nat.cast.{0} NNRat (CanonicallyOrderedCommSemiring.toNatCast.{0} NNRat instNNRatCanonicallyOrderedCommSemiring) (Finset.card.{u1} α A))) n) (Nat.cast.{0} NNRat (CanonicallyOrderedCommSemiring.toNatCast.{0} NNRat instNNRatCanonicallyOrderedCommSemiring) (Finset.card.{u1} α A))))
Case conversion may be inaccurate. Consider using '#align finset.card_mul_pow_le Finset.card_mul_pow_leₓ'. -/
/- ./././Mathport/Syntax/Translate/Basic.lean:635:2: warning: expanding binder collection (A' «expr ⊆ » A) -/
@[to_additive]
theorem card_mul_pow_le (hAB : ∀ (A') (_ : A' ⊆ A), (A * B).card * A'.card ≤ (A' * B).card * A.card)
    (n : ℕ) : ((A * B ^ n).card : ℚ≥0) ≤ ((A * B).card / A.card) ^ n * A.card :=
  by
  obtain rfl | hA := A.eq_empty_or_nonempty
  · simp
  induction' n with n ih
  · simp
  rw [pow_succ, ← mul_assoc, pow_succ, @mul_assoc ℚ≥0, ← mul_div_right_comm, le_div_iff, ← cast_mul]
  swap; exact cast_pos.2 hA.card_pos
  refine' (cast_le.2 <| mul_pluennecke_petridis _ hAB).trans _
  rw [cast_mul]
  exact mul_le_mul_of_nonneg_left ih (zero_le _)
#align finset.card_mul_pow_le Finset.card_mul_pow_le
#align finset.card_add_nsmul_le Finset.card_add_nsmul_le

/- warning: finset.card_pow_div_pow_le -> Finset.card_pow_div_pow_le is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : CommGroup.{u1} α] [_inst_2 : DecidableEq.{succ u1} α] {A : Finset.{u1} α}, (Finset.Nonempty.{u1} α A) -> (forall (B : Finset.{u1} α) (m : Nat) (n : Nat), LE.le.{0} NNRat (Preorder.toLE.{0} NNRat (PartialOrder.toPreorder.{0} NNRat (OrderedCancelAddCommMonoid.toPartialOrder.{0} NNRat (StrictOrderedSemiring.toOrderedCancelAddCommMonoid.{0} NNRat (LinearOrderedSemiring.toStrictOrderedSemiring.{0} NNRat (LinearOrderedCommSemiring.toLinearOrderedSemiring.{0} NNRat (LinearOrderedSemifield.toLinearOrderedCommSemiring.{0} NNRat (CanonicallyLinearOrderedSemifield.toLinearOrderedSemifield.{0} NNRat NNRat.canonicallyLinearOrderedSemifield)))))))) ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat NNRat (HasLiftT.mk.{1, 1} Nat NNRat (CoeTCₓ.coe.{1, 1} Nat NNRat (Nat.castCoe.{0} NNRat (AddMonoidWithOne.toNatCast.{0} NNRat (AddCommMonoidWithOne.toAddMonoidWithOne.{0} NNRat (NonAssocSemiring.toAddCommMonoidWithOne.{0} NNRat (Semiring.toNonAssocSemiring.{0} NNRat (StrictOrderedSemiring.toSemiring.{0} NNRat (LinearOrderedSemiring.toStrictOrderedSemiring.{0} NNRat (LinearOrderedCommSemiring.toLinearOrderedSemiring.{0} NNRat (LinearOrderedSemifield.toLinearOrderedCommSemiring.{0} NNRat (CanonicallyLinearOrderedSemifield.toLinearOrderedSemifield.{0} NNRat NNRat.canonicallyLinearOrderedSemifield)))))))))))) (Finset.card.{u1} α (HDiv.hDiv.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHDiv.{u1} (Finset.{u1} α) (Finset.div.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (DivInvMonoid.toHasDiv.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))) (HPow.hPow.{u1, 0, u1} (Finset.{u1} α) Nat (Finset.{u1} α) (instHPow.{u1, 0} (Finset.{u1} α) Nat (Finset.npow.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (MulOneClass.toHasOne.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))) (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))))) B m) (HPow.hPow.{u1, 0, u1} (Finset.{u1} α) Nat (Finset.{u1} α) (instHPow.{u1, 0} (Finset.{u1} α) Nat (Finset.npow.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (MulOneClass.toHasOne.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))) (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))))) B n)))) (HMul.hMul.{0, 0, 0} NNRat NNRat NNRat (instHMul.{0} NNRat (Distrib.toHasMul.{0} NNRat (NonUnitalNonAssocSemiring.toDistrib.{0} NNRat (NonAssocSemiring.toNonUnitalNonAssocSemiring.{0} NNRat (Semiring.toNonAssocSemiring.{0} NNRat (StrictOrderedSemiring.toSemiring.{0} NNRat (LinearOrderedSemiring.toStrictOrderedSemiring.{0} NNRat (LinearOrderedCommSemiring.toLinearOrderedSemiring.{0} NNRat (LinearOrderedSemifield.toLinearOrderedCommSemiring.{0} NNRat (CanonicallyLinearOrderedSemifield.toLinearOrderedSemifield.{0} NNRat NNRat.canonicallyLinearOrderedSemifield)))))))))) (HPow.hPow.{0, 0, 0} NNRat Nat NNRat (instHPow.{0, 0} NNRat Nat (Monoid.Pow.{0} NNRat (MonoidWithZero.toMonoid.{0} NNRat (Semiring.toMonoidWithZero.{0} NNRat (StrictOrderedSemiring.toSemiring.{0} NNRat (LinearOrderedSemiring.toStrictOrderedSemiring.{0} NNRat (LinearOrderedCommSemiring.toLinearOrderedSemiring.{0} NNRat (LinearOrderedSemifield.toLinearOrderedCommSemiring.{0} NNRat (CanonicallyLinearOrderedSemifield.toLinearOrderedSemifield.{0} NNRat NNRat.canonicallyLinearOrderedSemifield))))))))) (HDiv.hDiv.{0, 0, 0} NNRat NNRat NNRat (instHDiv.{0} NNRat (DivInvMonoid.toHasDiv.{0} NNRat (GroupWithZero.toDivInvMonoid.{0} NNRat (DivisionSemiring.toGroupWithZero.{0} NNRat (Semifield.toDivisionSemiring.{0} NNRat (LinearOrderedSemifield.toSemifield.{0} NNRat (CanonicallyLinearOrderedSemifield.toLinearOrderedSemifield.{0} NNRat NNRat.canonicallyLinearOrderedSemifield))))))) ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat NNRat (HasLiftT.mk.{1, 1} Nat NNRat (CoeTCₓ.coe.{1, 1} Nat NNRat (Nat.castCoe.{0} NNRat (AddMonoidWithOne.toNatCast.{0} NNRat (AddCommMonoidWithOne.toAddMonoidWithOne.{0} NNRat (NonAssocSemiring.toAddCommMonoidWithOne.{0} NNRat (Semiring.toNonAssocSemiring.{0} NNRat (StrictOrderedSemiring.toSemiring.{0} NNRat (LinearOrderedSemiring.toStrictOrderedSemiring.{0} NNRat (LinearOrderedCommSemiring.toLinearOrderedSemiring.{0} NNRat (LinearOrderedSemifield.toLinearOrderedCommSemiring.{0} NNRat (CanonicallyLinearOrderedSemifield.toLinearOrderedSemifield.{0} NNRat NNRat.canonicallyLinearOrderedSemifield)))))))))))) (Finset.card.{u1} α (HMul.hMul.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHMul.{u1} (Finset.{u1} α) (Finset.mul.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))))) A B))) ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat NNRat (HasLiftT.mk.{1, 1} Nat NNRat (CoeTCₓ.coe.{1, 1} Nat NNRat (Nat.castCoe.{0} NNRat (AddMonoidWithOne.toNatCast.{0} NNRat (AddCommMonoidWithOne.toAddMonoidWithOne.{0} NNRat (NonAssocSemiring.toAddCommMonoidWithOne.{0} NNRat (Semiring.toNonAssocSemiring.{0} NNRat (StrictOrderedSemiring.toSemiring.{0} NNRat (LinearOrderedSemiring.toStrictOrderedSemiring.{0} NNRat (LinearOrderedCommSemiring.toLinearOrderedSemiring.{0} NNRat (LinearOrderedSemifield.toLinearOrderedCommSemiring.{0} NNRat (CanonicallyLinearOrderedSemifield.toLinearOrderedSemifield.{0} NNRat NNRat.canonicallyLinearOrderedSemifield)))))))))))) (Finset.card.{u1} α A))) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) m n)) ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat NNRat (HasLiftT.mk.{1, 1} Nat NNRat (CoeTCₓ.coe.{1, 1} Nat NNRat (Nat.castCoe.{0} NNRat (AddMonoidWithOne.toNatCast.{0} NNRat (AddCommMonoidWithOne.toAddMonoidWithOne.{0} NNRat (NonAssocSemiring.toAddCommMonoidWithOne.{0} NNRat (Semiring.toNonAssocSemiring.{0} NNRat (StrictOrderedSemiring.toSemiring.{0} NNRat (LinearOrderedSemiring.toStrictOrderedSemiring.{0} NNRat (LinearOrderedCommSemiring.toLinearOrderedSemiring.{0} NNRat (LinearOrderedSemifield.toLinearOrderedCommSemiring.{0} NNRat (CanonicallyLinearOrderedSemifield.toLinearOrderedSemifield.{0} NNRat NNRat.canonicallyLinearOrderedSemifield)))))))))))) (Finset.card.{u1} α A))))
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : CommGroup.{u1} α] [_inst_2 : DecidableEq.{succ u1} α] {A : Finset.{u1} α}, (Finset.Nonempty.{u1} α A) -> (forall (B : Finset.{u1} α) (m : Nat) (n : Nat), LE.le.{0} NNRat (Preorder.toLE.{0} NNRat (PartialOrder.toPreorder.{0} NNRat (StrictOrderedSemiring.toPartialOrder.{0} NNRat (LinearOrderedSemiring.toStrictOrderedSemiring.{0} NNRat (LinearOrderedCommSemiring.toLinearOrderedSemiring.{0} NNRat (LinearOrderedSemifield.toLinearOrderedCommSemiring.{0} NNRat (CanonicallyLinearOrderedSemifield.toLinearOrderedSemifield.{0} NNRat instNNRatCanonicallyLinearOrderedSemifield))))))) (Nat.cast.{0} NNRat (CanonicallyOrderedCommSemiring.toNatCast.{0} NNRat instNNRatCanonicallyOrderedCommSemiring) (Finset.card.{u1} α (HDiv.hDiv.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHDiv.{u1} (Finset.{u1} α) (Finset.div.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (DivInvMonoid.toDiv.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))) (HPow.hPow.{u1, 0, u1} (Finset.{u1} α) Nat (Finset.{u1} α) (instHPow.{u1, 0} (Finset.{u1} α) Nat (Finset.npow.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (InvOneClass.toOne.{u1} α (DivInvOneMonoid.toInvOneClass.{u1} α (DivisionMonoid.toDivInvOneMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α (CommGroup.toDivisionCommMonoid.{u1} α _inst_1))))) (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))))) B m) (HPow.hPow.{u1, 0, u1} (Finset.{u1} α) Nat (Finset.{u1} α) (instHPow.{u1, 0} (Finset.{u1} α) Nat (Finset.npow.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (InvOneClass.toOne.{u1} α (DivInvOneMonoid.toInvOneClass.{u1} α (DivisionMonoid.toDivInvOneMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α (CommGroup.toDivisionCommMonoid.{u1} α _inst_1))))) (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))))) B n)))) (HMul.hMul.{0, 0, 0} NNRat NNRat NNRat (instHMul.{0} NNRat (CanonicallyOrderedCommSemiring.toMul.{0} NNRat instNNRatCanonicallyOrderedCommSemiring)) (HPow.hPow.{0, 0, 0} NNRat Nat NNRat (instHPow.{0, 0} NNRat Nat (Monoid.Pow.{0} NNRat (MonoidWithZero.toMonoid.{0} NNRat (Semiring.toMonoidWithZero.{0} NNRat (StrictOrderedSemiring.toSemiring.{0} NNRat (LinearOrderedSemiring.toStrictOrderedSemiring.{0} NNRat (LinearOrderedCommSemiring.toLinearOrderedSemiring.{0} NNRat (LinearOrderedSemifield.toLinearOrderedCommSemiring.{0} NNRat (CanonicallyLinearOrderedSemifield.toLinearOrderedSemifield.{0} NNRat instNNRatCanonicallyLinearOrderedSemifield))))))))) (HDiv.hDiv.{0, 0, 0} NNRat NNRat NNRat (instHDiv.{0} NNRat (CanonicallyLinearOrderedSemifield.toDiv.{0} NNRat instNNRatCanonicallyLinearOrderedSemifield)) (Nat.cast.{0} NNRat (CanonicallyOrderedCommSemiring.toNatCast.{0} NNRat instNNRatCanonicallyOrderedCommSemiring) (Finset.card.{u1} α (HMul.hMul.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHMul.{u1} (Finset.{u1} α) (Finset.mul.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))))) A B))) (Nat.cast.{0} NNRat (CanonicallyOrderedCommSemiring.toNatCast.{0} NNRat instNNRatCanonicallyOrderedCommSemiring) (Finset.card.{u1} α A))) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) m n)) (Nat.cast.{0} NNRat (CanonicallyOrderedCommSemiring.toNatCast.{0} NNRat instNNRatCanonicallyOrderedCommSemiring) (Finset.card.{u1} α A))))
Case conversion may be inaccurate. Consider using '#align finset.card_pow_div_pow_le Finset.card_pow_div_pow_leₓ'. -/
/-- The **Plünnecke-Ruzsa inequality**. Multiplication version. Note that this is genuinely harder
than the division version because we cannot use a double counting argument. -/
@[to_additive
      "The **Plünnecke-Ruzsa inequality**. Addition version. Note that this is genuinely\nharder than the subtraction version because we cannot use a double counting argument."]
theorem card_pow_div_pow_le (hA : A.Nonempty) (B : Finset α) (m n : ℕ) :
    ((B ^ m / B ^ n).card : ℚ≥0) ≤ ((A * B).card / A.card) ^ (m + n) * A.card :=
  by
  have hA' : A ∈ A.powerset.erase ∅ := mem_erase_of_ne_of_mem hA.ne_empty (mem_powerset_self _)
  obtain ⟨C, hC, hCA⟩ :=
    exists_min_image (A.powerset.erase ∅) (fun C => (C * B).card / C.card : _ → ℚ≥0) ⟨A, hA'⟩
  rw [mem_erase, mem_powerset, ← nonempty_iff_ne_empty] at hC
  refine' (mul_le_mul_right <| cast_pos.2 hC.1.card_pos).1 _
  norm_cast
  refine' (cast_le.2 <| card_div_mul_le_card_mul_mul_card_mul _ _ _).trans _
  push_cast
  rw [mul_comm _ C]
  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
      _
  rw [mul_mul_mul_comm, ← pow_add, ← mul_assoc]
  exact
    mul_le_mul_of_nonneg_right
      (mul_le_mul (pow_le_pow_of_le_left (zero_le _) (hCA _ hA') _)
          (cast_le.2 <| card_le_of_subset hC.2) (zero_le _) <|
        zero_le _)
      (zero_le _)
#align finset.card_pow_div_pow_le Finset.card_pow_div_pow_le
#align finset.card_nsmul_sub_nsmul_le Finset.card_nsmul_sub_nsmul_le

/- warning: finset.card_pow_div_pow_le' -> Finset.card_pow_div_pow_le' is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : CommGroup.{u1} α] [_inst_2 : DecidableEq.{succ u1} α] {A : Finset.{u1} α}, (Finset.Nonempty.{u1} α A) -> (forall (B : Finset.{u1} α) (m : Nat) (n : Nat), LE.le.{0} NNRat (Preorder.toLE.{0} NNRat (PartialOrder.toPreorder.{0} NNRat (OrderedCancelAddCommMonoid.toPartialOrder.{0} NNRat (StrictOrderedSemiring.toOrderedCancelAddCommMonoid.{0} NNRat (LinearOrderedSemiring.toStrictOrderedSemiring.{0} NNRat (LinearOrderedCommSemiring.toLinearOrderedSemiring.{0} NNRat (LinearOrderedSemifield.toLinearOrderedCommSemiring.{0} NNRat (CanonicallyLinearOrderedSemifield.toLinearOrderedSemifield.{0} NNRat NNRat.canonicallyLinearOrderedSemifield)))))))) ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat NNRat (HasLiftT.mk.{1, 1} Nat NNRat (CoeTCₓ.coe.{1, 1} Nat NNRat (Nat.castCoe.{0} NNRat (AddMonoidWithOne.toNatCast.{0} NNRat (AddCommMonoidWithOne.toAddMonoidWithOne.{0} NNRat (NonAssocSemiring.toAddCommMonoidWithOne.{0} NNRat (Semiring.toNonAssocSemiring.{0} NNRat (StrictOrderedSemiring.toSemiring.{0} NNRat (LinearOrderedSemiring.toStrictOrderedSemiring.{0} NNRat (LinearOrderedCommSemiring.toLinearOrderedSemiring.{0} NNRat (LinearOrderedSemifield.toLinearOrderedCommSemiring.{0} NNRat (CanonicallyLinearOrderedSemifield.toLinearOrderedSemifield.{0} NNRat NNRat.canonicallyLinearOrderedSemifield)))))))))))) (Finset.card.{u1} α (HDiv.hDiv.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHDiv.{u1} (Finset.{u1} α) (Finset.div.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (DivInvMonoid.toHasDiv.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))) (HPow.hPow.{u1, 0, u1} (Finset.{u1} α) Nat (Finset.{u1} α) (instHPow.{u1, 0} (Finset.{u1} α) Nat (Finset.npow.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (MulOneClass.toHasOne.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))) (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))))) B m) (HPow.hPow.{u1, 0, u1} (Finset.{u1} α) Nat (Finset.{u1} α) (instHPow.{u1, 0} (Finset.{u1} α) Nat (Finset.npow.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (MulOneClass.toHasOne.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))) (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))))) B n)))) (HMul.hMul.{0, 0, 0} NNRat NNRat NNRat (instHMul.{0} NNRat (Distrib.toHasMul.{0} NNRat (NonUnitalNonAssocSemiring.toDistrib.{0} NNRat (NonAssocSemiring.toNonUnitalNonAssocSemiring.{0} NNRat (Semiring.toNonAssocSemiring.{0} NNRat (StrictOrderedSemiring.toSemiring.{0} NNRat (LinearOrderedSemiring.toStrictOrderedSemiring.{0} NNRat (LinearOrderedCommSemiring.toLinearOrderedSemiring.{0} NNRat (LinearOrderedSemifield.toLinearOrderedCommSemiring.{0} NNRat (CanonicallyLinearOrderedSemifield.toLinearOrderedSemifield.{0} NNRat NNRat.canonicallyLinearOrderedSemifield)))))))))) (HPow.hPow.{0, 0, 0} NNRat Nat NNRat (instHPow.{0, 0} NNRat Nat (Monoid.Pow.{0} NNRat (MonoidWithZero.toMonoid.{0} NNRat (Semiring.toMonoidWithZero.{0} NNRat (StrictOrderedSemiring.toSemiring.{0} NNRat (LinearOrderedSemiring.toStrictOrderedSemiring.{0} NNRat (LinearOrderedCommSemiring.toLinearOrderedSemiring.{0} NNRat (LinearOrderedSemifield.toLinearOrderedCommSemiring.{0} NNRat (CanonicallyLinearOrderedSemifield.toLinearOrderedSemifield.{0} NNRat NNRat.canonicallyLinearOrderedSemifield))))))))) (HDiv.hDiv.{0, 0, 0} NNRat NNRat NNRat (instHDiv.{0} NNRat (DivInvMonoid.toHasDiv.{0} NNRat (GroupWithZero.toDivInvMonoid.{0} NNRat (DivisionSemiring.toGroupWithZero.{0} NNRat (Semifield.toDivisionSemiring.{0} NNRat (LinearOrderedSemifield.toSemifield.{0} NNRat (CanonicallyLinearOrderedSemifield.toLinearOrderedSemifield.{0} NNRat NNRat.canonicallyLinearOrderedSemifield))))))) ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat NNRat (HasLiftT.mk.{1, 1} Nat NNRat (CoeTCₓ.coe.{1, 1} Nat NNRat (Nat.castCoe.{0} NNRat (AddMonoidWithOne.toNatCast.{0} NNRat (AddCommMonoidWithOne.toAddMonoidWithOne.{0} NNRat (NonAssocSemiring.toAddCommMonoidWithOne.{0} NNRat (Semiring.toNonAssocSemiring.{0} NNRat (StrictOrderedSemiring.toSemiring.{0} NNRat (LinearOrderedSemiring.toStrictOrderedSemiring.{0} NNRat (LinearOrderedCommSemiring.toLinearOrderedSemiring.{0} NNRat (LinearOrderedSemifield.toLinearOrderedCommSemiring.{0} NNRat (CanonicallyLinearOrderedSemifield.toLinearOrderedSemifield.{0} NNRat NNRat.canonicallyLinearOrderedSemifield)))))))))))) (Finset.card.{u1} α (HDiv.hDiv.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHDiv.{u1} (Finset.{u1} α) (Finset.div.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (DivInvMonoid.toHasDiv.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))) A B))) ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat NNRat (HasLiftT.mk.{1, 1} Nat NNRat (CoeTCₓ.coe.{1, 1} Nat NNRat (Nat.castCoe.{0} NNRat (AddMonoidWithOne.toNatCast.{0} NNRat (AddCommMonoidWithOne.toAddMonoidWithOne.{0} NNRat (NonAssocSemiring.toAddCommMonoidWithOne.{0} NNRat (Semiring.toNonAssocSemiring.{0} NNRat (StrictOrderedSemiring.toSemiring.{0} NNRat (LinearOrderedSemiring.toStrictOrderedSemiring.{0} NNRat (LinearOrderedCommSemiring.toLinearOrderedSemiring.{0} NNRat (LinearOrderedSemifield.toLinearOrderedCommSemiring.{0} NNRat (CanonicallyLinearOrderedSemifield.toLinearOrderedSemifield.{0} NNRat NNRat.canonicallyLinearOrderedSemifield)))))))))))) (Finset.card.{u1} α A))) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) m n)) ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat NNRat (HasLiftT.mk.{1, 1} Nat NNRat (CoeTCₓ.coe.{1, 1} Nat NNRat (Nat.castCoe.{0} NNRat (AddMonoidWithOne.toNatCast.{0} NNRat (AddCommMonoidWithOne.toAddMonoidWithOne.{0} NNRat (NonAssocSemiring.toAddCommMonoidWithOne.{0} NNRat (Semiring.toNonAssocSemiring.{0} NNRat (StrictOrderedSemiring.toSemiring.{0} NNRat (LinearOrderedSemiring.toStrictOrderedSemiring.{0} NNRat (LinearOrderedCommSemiring.toLinearOrderedSemiring.{0} NNRat (LinearOrderedSemifield.toLinearOrderedCommSemiring.{0} NNRat (CanonicallyLinearOrderedSemifield.toLinearOrderedSemifield.{0} NNRat NNRat.canonicallyLinearOrderedSemifield)))))))))))) (Finset.card.{u1} α A))))
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : CommGroup.{u1} α] [_inst_2 : DecidableEq.{succ u1} α] {A : Finset.{u1} α}, (Finset.Nonempty.{u1} α A) -> (forall (B : Finset.{u1} α) (m : Nat) (n : Nat), LE.le.{0} NNRat (Preorder.toLE.{0} NNRat (PartialOrder.toPreorder.{0} NNRat (StrictOrderedSemiring.toPartialOrder.{0} NNRat (LinearOrderedSemiring.toStrictOrderedSemiring.{0} NNRat (LinearOrderedCommSemiring.toLinearOrderedSemiring.{0} NNRat (LinearOrderedSemifield.toLinearOrderedCommSemiring.{0} NNRat (CanonicallyLinearOrderedSemifield.toLinearOrderedSemifield.{0} NNRat instNNRatCanonicallyLinearOrderedSemifield))))))) (Nat.cast.{0} NNRat (CanonicallyOrderedCommSemiring.toNatCast.{0} NNRat instNNRatCanonicallyOrderedCommSemiring) (Finset.card.{u1} α (HDiv.hDiv.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHDiv.{u1} (Finset.{u1} α) (Finset.div.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (DivInvMonoid.toDiv.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))) (HPow.hPow.{u1, 0, u1} (Finset.{u1} α) Nat (Finset.{u1} α) (instHPow.{u1, 0} (Finset.{u1} α) Nat (Finset.npow.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (InvOneClass.toOne.{u1} α (DivInvOneMonoid.toInvOneClass.{u1} α (DivisionMonoid.toDivInvOneMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α (CommGroup.toDivisionCommMonoid.{u1} α _inst_1))))) (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))))) B m) (HPow.hPow.{u1, 0, u1} (Finset.{u1} α) Nat (Finset.{u1} α) (instHPow.{u1, 0} (Finset.{u1} α) Nat (Finset.npow.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (InvOneClass.toOne.{u1} α (DivInvOneMonoid.toInvOneClass.{u1} α (DivisionMonoid.toDivInvOneMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α (CommGroup.toDivisionCommMonoid.{u1} α _inst_1))))) (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))))) B n)))) (HMul.hMul.{0, 0, 0} NNRat NNRat NNRat (instHMul.{0} NNRat (CanonicallyOrderedCommSemiring.toMul.{0} NNRat instNNRatCanonicallyOrderedCommSemiring)) (HPow.hPow.{0, 0, 0} NNRat Nat NNRat (instHPow.{0, 0} NNRat Nat (Monoid.Pow.{0} NNRat (MonoidWithZero.toMonoid.{0} NNRat (Semiring.toMonoidWithZero.{0} NNRat (StrictOrderedSemiring.toSemiring.{0} NNRat (LinearOrderedSemiring.toStrictOrderedSemiring.{0} NNRat (LinearOrderedCommSemiring.toLinearOrderedSemiring.{0} NNRat (LinearOrderedSemifield.toLinearOrderedCommSemiring.{0} NNRat (CanonicallyLinearOrderedSemifield.toLinearOrderedSemifield.{0} NNRat instNNRatCanonicallyLinearOrderedSemifield))))))))) (HDiv.hDiv.{0, 0, 0} NNRat NNRat NNRat (instHDiv.{0} NNRat (CanonicallyLinearOrderedSemifield.toDiv.{0} NNRat instNNRatCanonicallyLinearOrderedSemifield)) (Nat.cast.{0} NNRat (CanonicallyOrderedCommSemiring.toNatCast.{0} NNRat instNNRatCanonicallyOrderedCommSemiring) (Finset.card.{u1} α (HDiv.hDiv.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHDiv.{u1} (Finset.{u1} α) (Finset.div.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (DivInvMonoid.toDiv.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))) A B))) (Nat.cast.{0} NNRat (CanonicallyOrderedCommSemiring.toNatCast.{0} NNRat instNNRatCanonicallyOrderedCommSemiring) (Finset.card.{u1} α A))) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) m n)) (Nat.cast.{0} NNRat (CanonicallyOrderedCommSemiring.toNatCast.{0} NNRat instNNRatCanonicallyOrderedCommSemiring) (Finset.card.{u1} α A))))
Case conversion may be inaccurate. Consider using '#align finset.card_pow_div_pow_le' Finset.card_pow_div_pow_le'ₓ'. -/
/-- The **Plünnecke-Ruzsa inequality**. Subtraction version. -/
@[to_additive "The **Plünnecke-Ruzsa inequality**. Subtraction version."]
theorem card_pow_div_pow_le' (hA : A.Nonempty) (B : Finset α) (m n : ℕ) :
    ((B ^ m / B ^ n).card : ℚ≥0) ≤ ((A / B).card / A.card) ^ (m + n) * A.card :=
  by
  rw [← card_inv, inv_div', ← inv_pow, ← inv_pow, div_eq_mul_inv A]
  exact card_pow_div_pow_le hA _ _ _
#align finset.card_pow_div_pow_le' Finset.card_pow_div_pow_le'
#align finset.card_nsmul_sub_nsmul_le' Finset.card_nsmul_sub_nsmul_le'

/- warning: finset.card_pow_le -> Finset.card_pow_le is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : CommGroup.{u1} α] [_inst_2 : DecidableEq.{succ u1} α] {A : Finset.{u1} α}, (Finset.Nonempty.{u1} α A) -> (forall (B : Finset.{u1} α) (n : Nat), LE.le.{0} NNRat (Preorder.toLE.{0} NNRat (PartialOrder.toPreorder.{0} NNRat (OrderedCancelAddCommMonoid.toPartialOrder.{0} NNRat (StrictOrderedSemiring.toOrderedCancelAddCommMonoid.{0} NNRat (LinearOrderedSemiring.toStrictOrderedSemiring.{0} NNRat (LinearOrderedCommSemiring.toLinearOrderedSemiring.{0} NNRat (LinearOrderedSemifield.toLinearOrderedCommSemiring.{0} NNRat (CanonicallyLinearOrderedSemifield.toLinearOrderedSemifield.{0} NNRat NNRat.canonicallyLinearOrderedSemifield)))))))) ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat NNRat (HasLiftT.mk.{1, 1} Nat NNRat (CoeTCₓ.coe.{1, 1} Nat NNRat (Nat.castCoe.{0} NNRat (AddMonoidWithOne.toNatCast.{0} NNRat (AddCommMonoidWithOne.toAddMonoidWithOne.{0} NNRat (NonAssocSemiring.toAddCommMonoidWithOne.{0} NNRat (Semiring.toNonAssocSemiring.{0} NNRat (StrictOrderedSemiring.toSemiring.{0} NNRat (LinearOrderedSemiring.toStrictOrderedSemiring.{0} NNRat (LinearOrderedCommSemiring.toLinearOrderedSemiring.{0} NNRat (LinearOrderedSemifield.toLinearOrderedCommSemiring.{0} NNRat (CanonicallyLinearOrderedSemifield.toLinearOrderedSemifield.{0} NNRat NNRat.canonicallyLinearOrderedSemifield)))))))))))) (Finset.card.{u1} α (HPow.hPow.{u1, 0, u1} (Finset.{u1} α) Nat (Finset.{u1} α) (instHPow.{u1, 0} (Finset.{u1} α) Nat (Finset.npow.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (MulOneClass.toHasOne.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))) (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))))) B n))) (HMul.hMul.{0, 0, 0} NNRat NNRat NNRat (instHMul.{0} NNRat (Distrib.toHasMul.{0} NNRat (NonUnitalNonAssocSemiring.toDistrib.{0} NNRat (NonAssocSemiring.toNonUnitalNonAssocSemiring.{0} NNRat (Semiring.toNonAssocSemiring.{0} NNRat (StrictOrderedSemiring.toSemiring.{0} NNRat (LinearOrderedSemiring.toStrictOrderedSemiring.{0} NNRat (LinearOrderedCommSemiring.toLinearOrderedSemiring.{0} NNRat (LinearOrderedSemifield.toLinearOrderedCommSemiring.{0} NNRat (CanonicallyLinearOrderedSemifield.toLinearOrderedSemifield.{0} NNRat NNRat.canonicallyLinearOrderedSemifield)))))))))) (HPow.hPow.{0, 0, 0} NNRat Nat NNRat (instHPow.{0, 0} NNRat Nat (Monoid.Pow.{0} NNRat (MonoidWithZero.toMonoid.{0} NNRat (Semiring.toMonoidWithZero.{0} NNRat (StrictOrderedSemiring.toSemiring.{0} NNRat (LinearOrderedSemiring.toStrictOrderedSemiring.{0} NNRat (LinearOrderedCommSemiring.toLinearOrderedSemiring.{0} NNRat (LinearOrderedSemifield.toLinearOrderedCommSemiring.{0} NNRat (CanonicallyLinearOrderedSemifield.toLinearOrderedSemifield.{0} NNRat NNRat.canonicallyLinearOrderedSemifield))))))))) (HDiv.hDiv.{0, 0, 0} NNRat NNRat NNRat (instHDiv.{0} NNRat (DivInvMonoid.toHasDiv.{0} NNRat (GroupWithZero.toDivInvMonoid.{0} NNRat (DivisionSemiring.toGroupWithZero.{0} NNRat (Semifield.toDivisionSemiring.{0} NNRat (LinearOrderedSemifield.toSemifield.{0} NNRat (CanonicallyLinearOrderedSemifield.toLinearOrderedSemifield.{0} NNRat NNRat.canonicallyLinearOrderedSemifield))))))) ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat NNRat (HasLiftT.mk.{1, 1} Nat NNRat (CoeTCₓ.coe.{1, 1} Nat NNRat (Nat.castCoe.{0} NNRat (AddMonoidWithOne.toNatCast.{0} NNRat (AddCommMonoidWithOne.toAddMonoidWithOne.{0} NNRat (NonAssocSemiring.toAddCommMonoidWithOne.{0} NNRat (Semiring.toNonAssocSemiring.{0} NNRat (StrictOrderedSemiring.toSemiring.{0} NNRat (LinearOrderedSemiring.toStrictOrderedSemiring.{0} NNRat (LinearOrderedCommSemiring.toLinearOrderedSemiring.{0} NNRat (LinearOrderedSemifield.toLinearOrderedCommSemiring.{0} NNRat (CanonicallyLinearOrderedSemifield.toLinearOrderedSemifield.{0} NNRat NNRat.canonicallyLinearOrderedSemifield)))))))))))) (Finset.card.{u1} α (HMul.hMul.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHMul.{u1} (Finset.{u1} α) (Finset.mul.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))))) A B))) ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat NNRat (HasLiftT.mk.{1, 1} Nat NNRat (CoeTCₓ.coe.{1, 1} Nat NNRat (Nat.castCoe.{0} NNRat (AddMonoidWithOne.toNatCast.{0} NNRat (AddCommMonoidWithOne.toAddMonoidWithOne.{0} NNRat (NonAssocSemiring.toAddCommMonoidWithOne.{0} NNRat (Semiring.toNonAssocSemiring.{0} NNRat (StrictOrderedSemiring.toSemiring.{0} NNRat (LinearOrderedSemiring.toStrictOrderedSemiring.{0} NNRat (LinearOrderedCommSemiring.toLinearOrderedSemiring.{0} NNRat (LinearOrderedSemifield.toLinearOrderedCommSemiring.{0} NNRat (CanonicallyLinearOrderedSemifield.toLinearOrderedSemifield.{0} NNRat NNRat.canonicallyLinearOrderedSemifield)))))))))))) (Finset.card.{u1} α A))) n) ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat NNRat (HasLiftT.mk.{1, 1} Nat NNRat (CoeTCₓ.coe.{1, 1} Nat NNRat (Nat.castCoe.{0} NNRat (AddMonoidWithOne.toNatCast.{0} NNRat (AddCommMonoidWithOne.toAddMonoidWithOne.{0} NNRat (NonAssocSemiring.toAddCommMonoidWithOne.{0} NNRat (Semiring.toNonAssocSemiring.{0} NNRat (StrictOrderedSemiring.toSemiring.{0} NNRat (LinearOrderedSemiring.toStrictOrderedSemiring.{0} NNRat (LinearOrderedCommSemiring.toLinearOrderedSemiring.{0} NNRat (LinearOrderedSemifield.toLinearOrderedCommSemiring.{0} NNRat (CanonicallyLinearOrderedSemifield.toLinearOrderedSemifield.{0} NNRat NNRat.canonicallyLinearOrderedSemifield)))))))))))) (Finset.card.{u1} α A))))
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : CommGroup.{u1} α] [_inst_2 : DecidableEq.{succ u1} α] {A : Finset.{u1} α}, (Finset.Nonempty.{u1} α A) -> (forall (B : Finset.{u1} α) (n : Nat), LE.le.{0} NNRat (Preorder.toLE.{0} NNRat (PartialOrder.toPreorder.{0} NNRat (StrictOrderedSemiring.toPartialOrder.{0} NNRat (LinearOrderedSemiring.toStrictOrderedSemiring.{0} NNRat (LinearOrderedCommSemiring.toLinearOrderedSemiring.{0} NNRat (LinearOrderedSemifield.toLinearOrderedCommSemiring.{0} NNRat (CanonicallyLinearOrderedSemifield.toLinearOrderedSemifield.{0} NNRat instNNRatCanonicallyLinearOrderedSemifield))))))) (Nat.cast.{0} NNRat (CanonicallyOrderedCommSemiring.toNatCast.{0} NNRat instNNRatCanonicallyOrderedCommSemiring) (Finset.card.{u1} α (HPow.hPow.{u1, 0, u1} (Finset.{u1} α) Nat (Finset.{u1} α) (instHPow.{u1, 0} (Finset.{u1} α) Nat (Finset.npow.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (InvOneClass.toOne.{u1} α (DivInvOneMonoid.toInvOneClass.{u1} α (DivisionMonoid.toDivInvOneMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α (CommGroup.toDivisionCommMonoid.{u1} α _inst_1))))) (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))))) B n))) (HMul.hMul.{0, 0, 0} NNRat NNRat NNRat (instHMul.{0} NNRat (CanonicallyOrderedCommSemiring.toMul.{0} NNRat instNNRatCanonicallyOrderedCommSemiring)) (HPow.hPow.{0, 0, 0} NNRat Nat NNRat (instHPow.{0, 0} NNRat Nat (Monoid.Pow.{0} NNRat (MonoidWithZero.toMonoid.{0} NNRat (Semiring.toMonoidWithZero.{0} NNRat (StrictOrderedSemiring.toSemiring.{0} NNRat (LinearOrderedSemiring.toStrictOrderedSemiring.{0} NNRat (LinearOrderedCommSemiring.toLinearOrderedSemiring.{0} NNRat (LinearOrderedSemifield.toLinearOrderedCommSemiring.{0} NNRat (CanonicallyLinearOrderedSemifield.toLinearOrderedSemifield.{0} NNRat instNNRatCanonicallyLinearOrderedSemifield))))))))) (HDiv.hDiv.{0, 0, 0} NNRat NNRat NNRat (instHDiv.{0} NNRat (CanonicallyLinearOrderedSemifield.toDiv.{0} NNRat instNNRatCanonicallyLinearOrderedSemifield)) (Nat.cast.{0} NNRat (CanonicallyOrderedCommSemiring.toNatCast.{0} NNRat instNNRatCanonicallyOrderedCommSemiring) (Finset.card.{u1} α (HMul.hMul.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHMul.{u1} (Finset.{u1} α) (Finset.mul.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))))) A B))) (Nat.cast.{0} NNRat (CanonicallyOrderedCommSemiring.toNatCast.{0} NNRat instNNRatCanonicallyOrderedCommSemiring) (Finset.card.{u1} α A))) n) (Nat.cast.{0} NNRat (CanonicallyOrderedCommSemiring.toNatCast.{0} NNRat instNNRatCanonicallyOrderedCommSemiring) (Finset.card.{u1} α A))))
Case conversion may be inaccurate. Consider using '#align finset.card_pow_le Finset.card_pow_leₓ'. -/
/-- Special case of the **Plünnecke-Ruzsa inequality**. Multiplication version. -/
@[to_additive "Special case of the **Plünnecke-Ruzsa inequality**. Addition version."]
theorem card_pow_le (hA : A.Nonempty) (B : Finset α) (n : ℕ) :
    ((B ^ n).card : ℚ≥0) ≤ ((A * B).card / A.card) ^ n * A.card := by
  simpa only [pow_zero, div_one] using card_pow_div_pow_le hA _ _ 0
#align finset.card_pow_le Finset.card_pow_le
#align finset.card_nsmul_le Finset.card_nsmul_le

/- warning: finset.card_pow_le' -> Finset.card_pow_le' is a dubious translation:
lean 3 declaration is
  forall {α : Type.{u1}} [_inst_1 : CommGroup.{u1} α] [_inst_2 : DecidableEq.{succ u1} α] {A : Finset.{u1} α}, (Finset.Nonempty.{u1} α A) -> (forall (B : Finset.{u1} α) (n : Nat), LE.le.{0} NNRat (Preorder.toLE.{0} NNRat (PartialOrder.toPreorder.{0} NNRat (OrderedCancelAddCommMonoid.toPartialOrder.{0} NNRat (StrictOrderedSemiring.toOrderedCancelAddCommMonoid.{0} NNRat (LinearOrderedSemiring.toStrictOrderedSemiring.{0} NNRat (LinearOrderedCommSemiring.toLinearOrderedSemiring.{0} NNRat (LinearOrderedSemifield.toLinearOrderedCommSemiring.{0} NNRat (CanonicallyLinearOrderedSemifield.toLinearOrderedSemifield.{0} NNRat NNRat.canonicallyLinearOrderedSemifield)))))))) ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat NNRat (HasLiftT.mk.{1, 1} Nat NNRat (CoeTCₓ.coe.{1, 1} Nat NNRat (Nat.castCoe.{0} NNRat (AddMonoidWithOne.toNatCast.{0} NNRat (AddCommMonoidWithOne.toAddMonoidWithOne.{0} NNRat (NonAssocSemiring.toAddCommMonoidWithOne.{0} NNRat (Semiring.toNonAssocSemiring.{0} NNRat (StrictOrderedSemiring.toSemiring.{0} NNRat (LinearOrderedSemiring.toStrictOrderedSemiring.{0} NNRat (LinearOrderedCommSemiring.toLinearOrderedSemiring.{0} NNRat (LinearOrderedSemifield.toLinearOrderedCommSemiring.{0} NNRat (CanonicallyLinearOrderedSemifield.toLinearOrderedSemifield.{0} NNRat NNRat.canonicallyLinearOrderedSemifield)))))))))))) (Finset.card.{u1} α (HPow.hPow.{u1, 0, u1} (Finset.{u1} α) Nat (Finset.{u1} α) (instHPow.{u1, 0} (Finset.{u1} α) Nat (Finset.npow.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (MulOneClass.toHasOne.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))) (MulOneClass.toHasMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))))) B n))) (HMul.hMul.{0, 0, 0} NNRat NNRat NNRat (instHMul.{0} NNRat (Distrib.toHasMul.{0} NNRat (NonUnitalNonAssocSemiring.toDistrib.{0} NNRat (NonAssocSemiring.toNonUnitalNonAssocSemiring.{0} NNRat (Semiring.toNonAssocSemiring.{0} NNRat (StrictOrderedSemiring.toSemiring.{0} NNRat (LinearOrderedSemiring.toStrictOrderedSemiring.{0} NNRat (LinearOrderedCommSemiring.toLinearOrderedSemiring.{0} NNRat (LinearOrderedSemifield.toLinearOrderedCommSemiring.{0} NNRat (CanonicallyLinearOrderedSemifield.toLinearOrderedSemifield.{0} NNRat NNRat.canonicallyLinearOrderedSemifield)))))))))) (HPow.hPow.{0, 0, 0} NNRat Nat NNRat (instHPow.{0, 0} NNRat Nat (Monoid.Pow.{0} NNRat (MonoidWithZero.toMonoid.{0} NNRat (Semiring.toMonoidWithZero.{0} NNRat (StrictOrderedSemiring.toSemiring.{0} NNRat (LinearOrderedSemiring.toStrictOrderedSemiring.{0} NNRat (LinearOrderedCommSemiring.toLinearOrderedSemiring.{0} NNRat (LinearOrderedSemifield.toLinearOrderedCommSemiring.{0} NNRat (CanonicallyLinearOrderedSemifield.toLinearOrderedSemifield.{0} NNRat NNRat.canonicallyLinearOrderedSemifield))))))))) (HDiv.hDiv.{0, 0, 0} NNRat NNRat NNRat (instHDiv.{0} NNRat (DivInvMonoid.toHasDiv.{0} NNRat (GroupWithZero.toDivInvMonoid.{0} NNRat (DivisionSemiring.toGroupWithZero.{0} NNRat (Semifield.toDivisionSemiring.{0} NNRat (LinearOrderedSemifield.toSemifield.{0} NNRat (CanonicallyLinearOrderedSemifield.toLinearOrderedSemifield.{0} NNRat NNRat.canonicallyLinearOrderedSemifield))))))) ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat NNRat (HasLiftT.mk.{1, 1} Nat NNRat (CoeTCₓ.coe.{1, 1} Nat NNRat (Nat.castCoe.{0} NNRat (AddMonoidWithOne.toNatCast.{0} NNRat (AddCommMonoidWithOne.toAddMonoidWithOne.{0} NNRat (NonAssocSemiring.toAddCommMonoidWithOne.{0} NNRat (Semiring.toNonAssocSemiring.{0} NNRat (StrictOrderedSemiring.toSemiring.{0} NNRat (LinearOrderedSemiring.toStrictOrderedSemiring.{0} NNRat (LinearOrderedCommSemiring.toLinearOrderedSemiring.{0} NNRat (LinearOrderedSemifield.toLinearOrderedCommSemiring.{0} NNRat (CanonicallyLinearOrderedSemifield.toLinearOrderedSemifield.{0} NNRat NNRat.canonicallyLinearOrderedSemifield)))))))))))) (Finset.card.{u1} α (HDiv.hDiv.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHDiv.{u1} (Finset.{u1} α) (Finset.div.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (DivInvMonoid.toHasDiv.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))) A B))) ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat NNRat (HasLiftT.mk.{1, 1} Nat NNRat (CoeTCₓ.coe.{1, 1} Nat NNRat (Nat.castCoe.{0} NNRat (AddMonoidWithOne.toNatCast.{0} NNRat (AddCommMonoidWithOne.toAddMonoidWithOne.{0} NNRat (NonAssocSemiring.toAddCommMonoidWithOne.{0} NNRat (Semiring.toNonAssocSemiring.{0} NNRat (StrictOrderedSemiring.toSemiring.{0} NNRat (LinearOrderedSemiring.toStrictOrderedSemiring.{0} NNRat (LinearOrderedCommSemiring.toLinearOrderedSemiring.{0} NNRat (LinearOrderedSemifield.toLinearOrderedCommSemiring.{0} NNRat (CanonicallyLinearOrderedSemifield.toLinearOrderedSemifield.{0} NNRat NNRat.canonicallyLinearOrderedSemifield)))))))))))) (Finset.card.{u1} α A))) n) ((fun (a : Type) (b : Type) [self : HasLiftT.{1, 1} a b] => self.0) Nat NNRat (HasLiftT.mk.{1, 1} Nat NNRat (CoeTCₓ.coe.{1, 1} Nat NNRat (Nat.castCoe.{0} NNRat (AddMonoidWithOne.toNatCast.{0} NNRat (AddCommMonoidWithOne.toAddMonoidWithOne.{0} NNRat (NonAssocSemiring.toAddCommMonoidWithOne.{0} NNRat (Semiring.toNonAssocSemiring.{0} NNRat (StrictOrderedSemiring.toSemiring.{0} NNRat (LinearOrderedSemiring.toStrictOrderedSemiring.{0} NNRat (LinearOrderedCommSemiring.toLinearOrderedSemiring.{0} NNRat (LinearOrderedSemifield.toLinearOrderedCommSemiring.{0} NNRat (CanonicallyLinearOrderedSemifield.toLinearOrderedSemifield.{0} NNRat NNRat.canonicallyLinearOrderedSemifield)))))))))))) (Finset.card.{u1} α A))))
but is expected to have type
  forall {α : Type.{u1}} [_inst_1 : CommGroup.{u1} α] [_inst_2 : DecidableEq.{succ u1} α] {A : Finset.{u1} α}, (Finset.Nonempty.{u1} α A) -> (forall (B : Finset.{u1} α) (n : Nat), LE.le.{0} NNRat (Preorder.toLE.{0} NNRat (PartialOrder.toPreorder.{0} NNRat (StrictOrderedSemiring.toPartialOrder.{0} NNRat (LinearOrderedSemiring.toStrictOrderedSemiring.{0} NNRat (LinearOrderedCommSemiring.toLinearOrderedSemiring.{0} NNRat (LinearOrderedSemifield.toLinearOrderedCommSemiring.{0} NNRat (CanonicallyLinearOrderedSemifield.toLinearOrderedSemifield.{0} NNRat instNNRatCanonicallyLinearOrderedSemifield))))))) (Nat.cast.{0} NNRat (CanonicallyOrderedCommSemiring.toNatCast.{0} NNRat instNNRatCanonicallyOrderedCommSemiring) (Finset.card.{u1} α (HPow.hPow.{u1, 0, u1} (Finset.{u1} α) Nat (Finset.{u1} α) (instHPow.{u1, 0} (Finset.{u1} α) Nat (Finset.npow.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (InvOneClass.toOne.{u1} α (DivInvOneMonoid.toInvOneClass.{u1} α (DivisionMonoid.toDivInvOneMonoid.{u1} α (DivisionCommMonoid.toDivisionMonoid.{u1} α (CommGroup.toDivisionCommMonoid.{u1} α _inst_1))))) (MulOneClass.toMul.{u1} α (Monoid.toMulOneClass.{u1} α (DivInvMonoid.toMonoid.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))))) B n))) (HMul.hMul.{0, 0, 0} NNRat NNRat NNRat (instHMul.{0} NNRat (CanonicallyOrderedCommSemiring.toMul.{0} NNRat instNNRatCanonicallyOrderedCommSemiring)) (HPow.hPow.{0, 0, 0} NNRat Nat NNRat (instHPow.{0, 0} NNRat Nat (Monoid.Pow.{0} NNRat (MonoidWithZero.toMonoid.{0} NNRat (Semiring.toMonoidWithZero.{0} NNRat (StrictOrderedSemiring.toSemiring.{0} NNRat (LinearOrderedSemiring.toStrictOrderedSemiring.{0} NNRat (LinearOrderedCommSemiring.toLinearOrderedSemiring.{0} NNRat (LinearOrderedSemifield.toLinearOrderedCommSemiring.{0} NNRat (CanonicallyLinearOrderedSemifield.toLinearOrderedSemifield.{0} NNRat instNNRatCanonicallyLinearOrderedSemifield))))))))) (HDiv.hDiv.{0, 0, 0} NNRat NNRat NNRat (instHDiv.{0} NNRat (CanonicallyLinearOrderedSemifield.toDiv.{0} NNRat instNNRatCanonicallyLinearOrderedSemifield)) (Nat.cast.{0} NNRat (CanonicallyOrderedCommSemiring.toNatCast.{0} NNRat instNNRatCanonicallyOrderedCommSemiring) (Finset.card.{u1} α (HDiv.hDiv.{u1, u1, u1} (Finset.{u1} α) (Finset.{u1} α) (Finset.{u1} α) (instHDiv.{u1} (Finset.{u1} α) (Finset.div.{u1} α (fun (a : α) (b : α) => _inst_2 a b) (DivInvMonoid.toDiv.{u1} α (Group.toDivInvMonoid.{u1} α (CommGroup.toGroup.{u1} α _inst_1))))) A B))) (Nat.cast.{0} NNRat (CanonicallyOrderedCommSemiring.toNatCast.{0} NNRat instNNRatCanonicallyOrderedCommSemiring) (Finset.card.{u1} α A))) n) (Nat.cast.{0} NNRat (CanonicallyOrderedCommSemiring.toNatCast.{0} NNRat instNNRatCanonicallyOrderedCommSemiring) (Finset.card.{u1} α A))))
Case conversion may be inaccurate. Consider using '#align finset.card_pow_le' Finset.card_pow_le'ₓ'. -/
/-- Special case of the **Plünnecke-Ruzsa inequality**. Division version. -/
@[to_additive "Special case of the **Plünnecke-Ruzsa inequality**. Subtraction version."]
theorem card_pow_le' (hA : A.Nonempty) (B : Finset α) (n : ℕ) :
    ((B ^ n).card : ℚ≥0) ≤ ((A / B).card / A.card) ^ n * A.card := by
  simpa only [pow_zero, div_one] using card_pow_div_pow_le' hA _ _ 0
#align finset.card_pow_le' Finset.card_pow_le'
#align finset.card_nsmul_le' Finset.card_nsmul_le'

end Finset