-- Mathlib/Combinatorics/Additive/CauchyDavenport.lean
/-- A generalisation of the **Cauchy-Davenport theorem** to arbitrary groups. The size of `s * t` is
lower-bounded by `|s| + |t| - 1` unless this quantity is greater than the size of the smallest
subgroup. -/
@[to_additive "A generalisation of the **Cauchy-Davenport theorem** to arbitrary groups. The size of
`s + t` is lower-bounded by `|s| + |t| - 1` unless this quantity is greater than the size of the
smallest subgroup."]
lemma cauchy_davenport_minOrder_mul (hs : s.Nonempty) (ht : t.Nonempty) :
    min (minOrder α) ↑(#s + #t - 1) ≤ #(s * t)

Proof state:
case intro.mk.intro.inr.inr.intro.intro.intro.intro
α : Type u_1
inst✝¹ : Group α
inst✝ : DecidableEq α
s t : Finset α
hs : s.Nonempty
ht : t.Nonempty
ih :
  ∀ (a b : Finset α),
    a.Nonempty → b.Nonempty → DevosMulRel (a, b) (s, t) → minOrder α ≤ ↑(#(a * b)) ∨ #a + #b ≤ #(a * b) + 1
hst : #s ≤ #t
a : α
ha : a ∈ ↑s
b : α
hb : b ∈ ↑s
hab : a ≠ b
⊢ minOrder α ≤ ↑(#(s * t)) ∨ #s + #t ≤ #(s * t) + 1

Tactic:
obtain ⟨g, hg, hgs⟩ : ∃ g : α, g ≠ 1 ∧ (s ∩ op g • s).Nonempty :=
  ⟨b⁻¹ * a, inv_mul_eq_one.not.2 hab.symm, _,
    mem_inter.2 ⟨ha, mem_smul_finset.2 ⟨_, hb, by simp⟩⟩⟩

Result:
case intro.mk.intro.inr.inr.intro.intro.intro.intro.intro.intro
α : Type u_1
inst✝¹ : Group α
inst✝ : DecidableEq α
s t : Finset α
hs : s.Nonempty
ht : t.Nonempty
ih :
  ∀ (a b : Finset α),
    a.Nonempty → b.Nonempty → DevosMulRel (a, b) (s, t) → minOrder α ≤ ↑(#(a * b)) ∨ #a + #b ≤ #(a * b) + 1
hst : #s ≤ #t
a : α
ha : a ∈ ↑s
b : α
hb : b ∈ ↑s
hab : a ≠ b
g : α
hg : g ≠ 1
hgs : (s ∩ op g • s).Nonempty
⊢ minOrder α ≤ ↑(#(s * t)) ∨ #s + #t ≤ #(s * t) + 1

Proof state:
α : Type u_1
inst✝¹ : Group α
inst✝ : DecidableEq α
s t : Finset α
hs : s.Nonempty
ht : t.Nonempty
x : Finset α × Finset α
hx : x = (s, t)
⊢ minOrder α ⊓ ↑(#s + #t - 1) ≤ ↑(#(s * t))

Tactic:
simp only [Prod.ext_iff] at hx

Result:
α : Type u_1
inst✝¹ : Group α
inst✝ : DecidableEq α
s t : Finset α
hs : s.Nonempty
ht : t.Nonempty
x : Finset α × Finset α
hx : x.1 = s ∧ x.2 = t
⊢ minOrder α ⊓ ↑(#s + #t - 1) ≤ ↑(#(s * t))

Proof state:
α : Type u_1
inst✝¹ : Group α
inst✝ : DecidableEq α
s t : Finset α
hs : s.Nonempty
ht : t.Nonempty
x : Finset α × Finset α
hx : x.1 = s ∧ x.2 = t
⊢ minOrder α ⊓ ↑(#s + #t - 1) ≤ ↑(#(s * t))

Tactic:
obtain ⟨rfl, rfl⟩ := hx

Result:
case intro
α : Type u_1
inst✝¹ : Group α
inst✝ : DecidableEq α
x : Finset α × Finset α
hs : x.1.Nonempty
ht : x.2.Nonempty
⊢ minOrder α ⊓ ↑(#x.1 + #x.2 - 1) ≤ ↑(#(x.1 * x.2))

Proof state:
α : Type u_1
inst✝¹ : Group α
inst✝ : DecidableEq α
s t : Finset α
hs : s.Nonempty
ht : t.Nonempty
ih :
  ∀ (a b : Finset α),
    a.Nonempty → b.Nonempty → DevosMulRel (a, b) (s, t) → minOrder α ≤ ↑(#(a * b)) ∨ #a + #b ≤ #(a * b) + 1
hts : #t < #s
⊢ #((t⁻¹, s⁻¹).1 * (t⁻¹, s⁻¹).2) = #((s, t).1 * (s, t).2) ∧
    #(t⁻¹, s⁻¹).1 + #(t⁻¹, s⁻¹).2 = #(s, t).1 + #(s, t).2 ∧ #(t⁻¹, s⁻¹).1 < #(s, t).1

Tactic:
simpa only [← mul_inv_rev, add_comm, card_inv, true_and]

Result:
no goals

Proof state:
case intro.mk.intro.inr.inr.intro.intro.intro.intro.intro.intro.inr.inl
α : Type u_1
inst✝¹ : Group α
inst✝ : DecidableEq α
s t : Finset α
hs : s.Nonempty
ht : t.Nonempty
ih :
  ∀ (a b : Finset α),
    a.Nonempty → b.Nonempty → DevosMulRel (a, b) (s, t) → minOrder α ≤ ↑(#(a * b)) ∨ #a + #b ≤ #(a * b) + 1
hst : #s ≤ #t
a : α
ha : a ∈ ↑s
b : α
hb : b ∈ ↑s
hab : a ≠ b
g : α
hg : g ≠ 1
hgs : (s ∩ op g • s).Nonempty
hsg : #(s ∩ op g • s) < #s
aux1 : #((mulETransformLeft g (s, t)).1 * (mulETransformLeft g (s, t)).2) ≤ #((s, t).1 * (s, t).2)
aux2 : #((mulETransformRight g (s, t)).1 * (mulETransformRight g (s, t)).2) ≤ #((s, t).1 * (s, t).2)
hgt : Disjoint t (g⁻¹ • t)
⊢ #(t ∪ g⁻¹ • t) ≤ #(s * t) + 1

Tactic:
exact (card_le_card_mul_left hgs).trans (le_add_of_le_left aux1)

Result:
no goals

Proof state:
case intro.mk.intro
α : Type u_1
inst✝¹ : Group α
inst✝ : DecidableEq α
s t : Finset α
hs : (s, t).1.Nonempty
ht : (s, t).2.Nonempty
ih :
  ∀ z ∈ {x | x.1.Nonempty ∧ x.2.Nonempty},
    DevosMulRel z (s, t) → (fun x => minOrder α ⊓ ↑(#x.1 + #x.2 - 1) ≤ ↑(#(x.1 * x.2))) z
⊢ minOrder α ⊓ ↑(#(s, t).1 + #(s, t).2 - 1) ≤ ↑(#((s, t).1 * (s, t).2))

Tactic:
simp only [min_le_iff, tsub_le_iff_right, Prod.forall, Set.mem_setOf_eq, and_imp,
  Nat.cast_le] at *

Result:
case intro.mk.intro
α : Type u_1
inst✝¹ : Group α
inst✝ : DecidableEq α
s t : Finset α
hs : s.Nonempty
ht : t.Nonempty
ih :
  ∀ (a b : Finset α),
    a.Nonempty → b.Nonempty → DevosMulRel (a, b) (s, t) → minOrder α ≤ ↑(#(a * b)) ∨ #a + #b ≤ #(a * b) + 1
⊢ minOrder α ≤ ↑(#(s * t)) ∨ #s + #t ≤ #(s * t) + 1

Proof state:
case intro.mk.intro.inr.inr.intro.intro.intro.intro.intro.intro.inr.inl
α : Type u_1
inst✝¹ : Group α
inst✝ : DecidableEq α
s t : Finset α
hs : s.Nonempty
ht : t.Nonempty
ih :
  ∀ (a b : Finset α),
    a.Nonempty → b.Nonempty → DevosMulRel (a, b) (s, t) → minOrder α ≤ ↑(#(a * b)) ∨ #a + #b ≤ #(a * b) + 1
hst : #s ≤ #t
a : α
ha : a ∈ ↑s
b : α
hb : b ∈ ↑s
hab : a ≠ b
g : α
hg : g ≠ 1
hgs : (s ∩ op g • s).Nonempty
hsg : #(s ∩ op g • s) < #s
aux1 : #((mulETransformLeft g (s, t)).1 * (mulETransformLeft g (s, t)).2) ≤ #((s, t).1 * (s, t).2)
aux2 : #((mulETransformRight g (s, t)).1 * (mulETransformRight g (s, t)).2) ≤ #((s, t).1 * (s, t).2)
hgt : Disjoint t (g⁻¹ • t)
⊢ minOrder α ≤ ↑(#(s * t)) ∨ #s + #(g⁻¹ • t) ≤ #(s * t) + 1

Tactic:
refine Or.inr ((add_le_add_right hst _).trans ?_)

Result:
case intro.mk.intro.inr.inr.intro.intro.intro.intro.intro.intro.inr.inl
α : Type u_1
inst✝¹ : Group α
inst✝ : DecidableEq α
s t : Finset α
hs : s.Nonempty
ht : t.Nonempty
ih :
  ∀ (a b : Finset α),
    a.Nonempty → b.Nonempty → DevosMulRel (a, b) (s, t) → minOrder α ≤ ↑(#(a * b)) ∨ #a + #b ≤ #(a * b) + 1
hst : #s ≤ #t
a : α
ha : a ∈ ↑s
b : α
hb : b ∈ ↑s
hab : a ≠ b
g : α
hg : g ≠ 1
hgs : (s ∩ op g • s).Nonempty
hsg : #(s ∩ op g • s) < #s
aux1 : #((mulETransformLeft g (s, t)).1 * (mulETransformLeft g (s, t)).2) ≤ #((s, t).1 * (s, t).2)
aux2 : #((mulETransformRight g (s, t)).1 * (mulETransformRight g (s, t)).2) ≤ #((s, t).1 * (s, t).2)
hgt : Disjoint t (g⁻¹ • t)
⊢ #t + #(g⁻¹ • t) ≤ #(s * t) + 1

Proof state:
case intro.mk.intro.inr.inr.intro.intro.intro.intro.intro.intro
α : Type u_1
inst✝¹ : Group α
inst✝ : DecidableEq α
s t : Finset α
hs : s.Nonempty
ht : t.Nonempty
ih :
  ∀ (a b : Finset α),
    a.Nonempty → b.Nonempty → DevosMulRel (a, b) (s, t) → minOrder α ≤ ↑(#(a * b)) ∨ #a + #b ≤ #(a * b) + 1
hst : #s ≤ #t
a : α
ha : a ∈ ↑s
b : α
hb : b ∈ ↑s
hab : a ≠ b
g : α
hg : g ≠ 1
hgs : (s ∩ op g • s).Nonempty
⊢ minOrder α ≤ ↑(#(s * t)) ∨ #s + #t ≤ #(s * t) + 1

Tactic:
obtain hsg | hsg := eq_or_ne (op g • s) s

Result:
case intro.mk.intro.inr.inr.intro.intro.intro.intro.intro.intro.inl
α : Type u_1
inst✝¹ : Group α
inst✝ : DecidableEq α
s t : Finset α
hs : s.Nonempty
ht : t.Nonempty
ih :
  ∀ (a b : Finset α),
    a.Nonempty → b.Nonempty → DevosMulRel (a, b) (s, t) → minOrder α ≤ ↑(#(a * b)) ∨ #a + #b ≤ #(a * b) + 1
hst : #s ≤ #t
a : α
ha : a ∈ ↑s
b : α
hb : b ∈ ↑s
hab : a ≠ b
g : α
hg : g ≠ 1
hgs : (s ∩ op g • s).Nonempty
hsg : op g • s = s
⊢ minOrder α ≤ ↑(#(s * t)) ∨ #s + #t ≤ #(s * t) + 1

case intro.mk.intro.inr.inr.intro.intro.intro.intro.intro.intro.inr
α : Type u_1
inst✝¹ : Group α
inst✝ : DecidableEq α
s t : Finset α
hs : s.Nonempty
ht : t.Nonempty
ih :
  ∀ (a b : Finset α),
    a.Nonempty → b.Nonempty → DevosMulRel (a, b) (s, t) → minOrder α ≤ ↑(#(a * b)) ∨ #a + #b ≤ #(a * b) + 1
hst : #s ≤ #t
a : α
ha : a ∈ ↑s
b : α
hb : b ∈ ↑s
hab : a ≠ b
g : α
hg : g ≠ 1
hgs : (s ∩ op g • s).Nonempty
hsg : op g • s ≠ s
⊢ minOrder α ≤ ↑(#(s * t)) ∨ #s + #t ≤ #(s * t) + 1