Skip to content

Commit fe7877b

Browse files
committed
feat(Data/Finset/Empty): add @[push] tags for pushing negation (leanprover-community#32195)
This PR tags `Finset.nonempty_iff_ne_empty` and `Finset.not_nonempty_iff_eq_empty` with `@[push]`, so that they can be used in `push_neg`, `by_cases!`, etc. A bunch of proofs have been golfed using this.
1 parent 0749ef1 commit fe7877b

39 files changed

Lines changed: 82 additions & 98 deletions

File tree

Mathlib/Algebra/Group/Pointwise/Finset/Basic.lean

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -858,12 +858,8 @@ lemma Nonempty.pow (hs : s.Nonempty) : ∀ {n}, (s ^ n).Nonempty
858858
constructor
859859
· contrapose! +distrib
860860
rintro (hs | rfl)
861-
-- TODO: The `nonempty_iff_ne_empty` would be unnecessary if `push_neg` knew how to simplify
862-
-- `s ≠ ∅` to `s.Nonempty` when `s : Finset α`.
863-
-- See https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/push_neg.20extensibility
864-
· exact nonempty_iff_ne_empty.1 (nonempty_iff_ne_empty.2 hs).pow
865-
· rw [← nonempty_iff_ne_empty]
866-
simp
861+
· exact hs.pow
862+
· simp
867863
· rintro ⟨rfl, hn⟩
868864
exact empty_pow hn
869865

@@ -1010,9 +1006,8 @@ lemma Nonempty.zpow (hs : s.Nonempty) : ∀ {n : ℤ}, (s ^ n).Nonempty
10101006
constructor
10111007
· contrapose! +distrib
10121008
rintro (hs | rfl)
1013-
· exact nonempty_iff_ne_empty.1 (nonempty_iff_ne_empty.2 hs).zpow
1014-
· rw [← nonempty_iff_ne_empty]
1015-
simp
1009+
· exact hs.zpow
1010+
· simp
10161011
· rintro ⟨rfl, hn⟩
10171012
exact empty_zpow hn
10181013

Mathlib/Algebra/Module/ZLattice/Basic.lean

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -562,12 +562,10 @@ theorem ZLattice.rank [hs : IsZLattice K L] : finrank ℤ L = finrank K E := by
562562
-- Since `finrank ℤ L > finrank K E`, there exists a vector `v ∈ b` with `v ∉ e`
563563
obtain ⟨v, hv⟩ : (Set.range b \ Set.range e).Nonempty := by
564564
rw [Basis.coe_mk, Subtype.range_coe_subtype, Set.setOf_mem_eq, ← Set.toFinset_nonempty]
565-
contrapose h
566-
rw [Finset.not_nonempty_iff_eq_empty, Set.toFinset_diff,
567-
Finset.sdiff_eq_empty_iff_subset] at h
565+
contrapose! h
566+
rw [Set.toFinset_diff, Finset.sdiff_eq_empty_iff_subset] at h
568567
replace h := Finset.card_le_card h
569-
rwa [not_lt, h_card, ← topEquiv.finrank_eq, ← h_spanE, ← ht_span,
570-
finrank_span_set_eq_card ht_lin]
568+
rwa [h_card, ← topEquiv.finrank_eq, ← h_spanE, ← ht_span, finrank_span_set_eq_card ht_lin]
571569
-- Assume that `e ∪ {v}` is not `ℤ`-linear independent then we get the contradiction
572570
suffices ¬ LinearIndepOn ℤ id (insert v (Set.range e)) by
573571
contrapose! this

Mathlib/Algebra/MonoidAlgebra/Degree.lean

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -434,11 +434,11 @@ lemma supDegree_leadingCoeff_sum_eq
434434
(∑ j ∈ s, f j).leadingCoeff D = (f i).leadingCoeff D := by
435435
classical
436436
rw [← s.add_sum_erase _ hi]
437-
by_cases hs : s.erase i = ∅
437+
by_cases! hs : s.erase i = ∅
438438
· rw [hs, Finset.sum_empty, add_zero]; exact ⟨rfl, rfl⟩
439439
suffices _ from ⟨supDegree_add_eq_left this, leadingCoeff_add_eq_left this⟩
440440
refine supDegree_sum_lt ?_ (fun j hj => ?_)
441-
· rw [Finset.nonempty_iff_ne_empty]; exact hs
441+
· exact hs
442442
· rw [Finset.mem_erase] at hj; exact hmax j hj.2 hj.1
443443

444444
open Finset in

Mathlib/Algebra/Order/Module/HahnEmbedding.lean

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ theorem iSupIndep_stratum : iSupIndep u.stratum := by
139139
obtain hf' := congrArg ArchimedeanClass.mk hf
140140
contrapose! hf' with h0
141141
rw [← hab, DFinsupp.sum]
142-
by_cases hnonempty : f.support.Nonempty
142+
by_cases! hnonempty : f.support.Nonempty
143143
· have hmem (x : ArchimedeanClass M) : (f x).val ∈ u.stratum x :=
144144
Set.mem_of_mem_of_subset (f x).prop (by simp)
145145
have hmono : StrictMonoOn (fun i ↦ ArchimedeanClass.mk (f i).val) f.support := by
@@ -156,7 +156,7 @@ theorem iSupIndep_stratum : iSupIndep u.stratum := by
156156
contrapose! h
157157
rw [DFinsupp.notMem_support_iff, u.archimedeanClassMk_of_mem_stratum ha h0]
158158
simpa using (f c).prop
159-
· rw [Finset.not_nonempty_iff_eq_empty.mp hnonempty]
159+
· rw [hnonempty]
160160
symm
161161
simpa using h0
162162

@@ -293,7 +293,7 @@ theorem baseEmbedding_pos {x : seed.baseEmbedding.domain} (hx : 0 < x) :
293293
contrapose! hne with hempty
294294
apply DFinsupp.sum_eq_zero
295295
intro c
296-
simpa using DFinsupp.notMem_support_iff.mp (forall_not_of_not_exists hempty c)
296+
simpa using DFinsupp.notMem_support_iff.mp (Finset.eq_empty_iff_forall_notMem.mp hempty c)
297297
have htop : f.support.min' hsupport ≠ ⊤ := by
298298
by_contra! h
299299
have h : ⊤ ∈ f.support := h ▸ f.support.min'_mem hsupport
@@ -338,16 +338,14 @@ theorem baseEmbedding_pos {x : seed.baseEmbedding.domain} (hx : 0 < x) :
338338
rw [DFinsupp.sum, mk_sum hsupport hmono]
339339
rw [seed.archimedeanClassMk_of_mem_stratum (f _).prop
340340
(by simpa using f.support.min'_mem hsupport)]
341-
by_cases hsupport' : (f.support.erase (f.support.min' hsupport)).Nonempty
341+
by_cases! hsupport' : (f.support.erase (f.support.min' hsupport)).Nonempty
342342
· rw [mk_sum hsupport' (hmono.mono (by simp))]
343343
rw [seed.archimedeanClassMk_of_mem_stratum (f _).prop (by
344344
simpa using (Finset.mem_erase.mp <| (f.support.erase _).min'_mem hsupport').2)]
345345
apply Finset.min'_lt_of_mem_erase_min'
346346
apply Finset.min'_mem _ _
347347
· -- special case: `f` has a single term, and becomes 0 after removing it
348-
have : f.support.erase (f.support.min' hsupport) = ∅ :=
349-
Finset.not_nonempty_iff_eq_empty.mp hsupport'
350-
simpa [this] using lt_top_iff_ne_top.mpr htop
348+
simpa [hsupport'] using lt_top_iff_ne_top.mpr htop
351349

352350
theorem baseEmbedding_strictMono [IsOrderedAddMonoid R] : StrictMono seed.baseEmbedding := by
353351
intro x y h

Mathlib/Algebra/Polynomial/Basic.lean

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1053,7 +1053,6 @@ theorem coeffs_empty_iff {p : R[X]} : coeffs p = ∅ ↔ p = 0 := by
10531053
rw [← support_nonempty] at h
10541054
obtain ⟨n, hn⟩ := h
10551055
rw [mem_support_iff] at hn
1056-
rw [← nonempty_iff_ne_empty]
10571056
exact ⟨p.coeff n, coeff_mem_coeffs hn⟩
10581057

10591058
@[simp]

Mathlib/Analysis/Convex/SimplicialComplex/Basic.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ instance : Membership (Finset E) (SimplicialComplex 𝕜 E) :=
8282
fun K s => s ∈ K.faces⟩
8383

8484
lemma nonempty_of_mem_faces (hs : s ∈ K.faces) : s.Nonempty := by
85-
rw [Finset.nonempty_iff_ne_empty]; rintro rfl; exact K.empty_notMem hs
85+
by_contra! rfl; exact K.empty_notMem hs
8686

8787
/-- The underlying space of a simplicial complex is the union of its faces. -/
8888
def space (K : SimplicialComplex 𝕜 E) : Set E :=

Mathlib/Analysis/LocallyConvex/WithSeminorms.lean

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -499,7 +499,7 @@ theorem WithSeminorms.isVonNBounded_iff_seminorm_bounded {s : Set E} (hp : WithS
499499
convert hI {i}
500500
rw [Finset.sup_singleton]
501501
intro hi I
502-
by_cases hI : I.Nonempty
502+
by_cases! hI : I.Nonempty
503503
· choose r hr h using hi
504504
have h' : 0 < I.sup' hI r := by
505505
rcases hI with ⟨i, hi⟩
@@ -508,7 +508,7 @@ theorem WithSeminorms.isVonNBounded_iff_seminorm_bounded {s : Set E} (hp : WithS
508508
refine lt_of_lt_of_le (h i x hx) ?_
509509
simp only [Finset.le_sup'_iff]
510510
exact ⟨i, hi, (Eq.refl _).le⟩
511-
simp only [Finset.not_nonempty_iff_eq_empty.mp hI, Finset.sup_empty, coe_bot, Pi.zero_apply]
511+
simp only [hI, Finset.sup_empty, coe_bot, Pi.zero_apply]
512512
exact ⟨1, zero_lt_one, fun _ _ => zero_lt_one⟩
513513

514514
theorem WithSeminorms.image_isVonNBounded_iff_seminorm_bounded (f : G → E) {s : Set G}

Mathlib/Analysis/SpecialFunctions/Log/PosLog.lean

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -164,11 +164,10 @@ just two summands. -/
164164
theorem posLog_sum {α : Type*} (s : Finset α) (f : α → ℝ) :
165165
log⁺ (∑ t ∈ s, f t) ≤ log (s.card) + ∑ t ∈ s, log⁺ (f t) := by
166166
-- Trivial case: empty sum
167-
by_cases hs : s = ∅
167+
by_cases! hs : s = ∅
168168
· simp [hs, posLog]
169169
-- Nontrivial case: Obtain maximal element…
170-
obtain ⟨t_max, ht_max⟩ := s.exists_max_image (fun t ↦ |f t|)
171-
(Finset.nonempty_iff_ne_empty.mpr hs)
170+
obtain ⟨t_max, ht_max⟩ := s.exists_max_image (fun t ↦ |f t|) hs
172171
-- …then calculate
173172
calc log⁺ (∑ t ∈ s, f t)
174173
_ = log⁺ |∑ t ∈ s, f t| := by

Mathlib/Combinatorics/Additive/ApproximateSubgroup.lean

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,9 @@ namespace IsApproximateSubgroup
7272
@[to_additive one_le]
7373
lemma one_le (hA : IsApproximateSubgroup K A) : 1 ≤ K := by
7474
obtain ⟨F, hF, hSF⟩ := hA.sq_covBySMul
75-
have hF₀ : F ≠ ∅ := by rintro rfl; simp [hA.nonempty.pow.ne_empty] at hSF
76-
exact hF.trans' <| by simpa [Finset.nonempty_iff_ne_empty]
75+
grw [← hF]
76+
have : F.Nonempty := by by_contra! rfl; simp [hA.nonempty.ne_empty] at hSF
77+
simpa
7778

7879
@[to_additive]
7980
lemma mono (hKL : K ≤ L) (hA : IsApproximateSubgroup K A) : IsApproximateSubgroup L A where

Mathlib/Combinatorics/Additive/Energy.lean

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,9 +107,7 @@ variable (s t)
107107
variable {s t}
108108

109109
@[to_additive (attr := simp)] lemma mulEnergy_pos_iff : 0 < Eₘ[s, t] ↔ s.Nonempty ∧ t.Nonempty where
110-
mp h := of_not_not fun H => by
111-
simp_rw [not_and_or, not_nonempty_iff_eq_empty] at H
112-
obtain rfl | rfl := H <;> simp at h
110+
mp h := by by_contra! +distrib rfl | rfl <;> simp at h
113111
mpr h := mulEnergy_pos h.1 h.2
114112

115113
@[to_additive (attr := simp)] lemma mulEnergy_eq_zero_iff : Eₘ[s, t] = 0 ↔ s = ∅ ∨ t = ∅ := by

0 commit comments

Comments
 (0)