Skip to content

Commit 06bb38c

Browse files
committed
feat(push_neg): push_neg +distrib syntax (leanprover-community#31406)
This PR adds the syntax `push_neg +distrib`, `by_cases! +distrib`, `contrapose! +distrib` and `by_contra! +distrib`. This is much more convenient to use than writing out `set_option push_neg.use_distrib true in`. All uses of the `set_option` version have been replaced with the new syntax. I also add a missing `namespace` in the definition of `by_cases!` and `by_contra!`
1 parent bb08bd8 commit 06bb38c

File tree

21 files changed

+132
-67
lines changed

21 files changed

+132
-67
lines changed

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

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -854,10 +854,9 @@ lemma Nonempty.pow (hs : s.Nonempty) : ∀ {n}, (s ^ n).Nonempty
854854
| 0 => by simp
855855
| n + 1 => by rw [pow_succ]; exact hs.pow.mul hs
856856

857-
set_option push_neg.use_distrib true in
858857
@[to_additive (attr := simp)] lemma pow_eq_empty : s ^ n = ∅ ↔ s = ∅ ∧ n ≠ 0 := by
859858
constructor
860-
· contrapose!
859+
· contrapose! +distrib
861860
rintro (hs | rfl)
862861
-- TODO: The `nonempty_iff_ne_empty` would be unnecessary if `push_neg` knew how to simplify
863862
-- `s ≠ ∅` to `s.Nonempty` when `s : Finset α`.
@@ -1007,10 +1006,9 @@ lemma Nonempty.zpow (hs : s.Nonempty) : ∀ {n : ℤ}, (s ^ n).Nonempty
10071006
| (n : ℕ) => hs.pow
10081007
| .negSucc n => by simpa using hs.pow
10091008

1010-
set_option push_neg.use_distrib true in
10111009
@[to_additive (attr := simp)] lemma zpow_eq_empty : s ^ n = ∅ ↔ s = ∅ ∧ n ≠ 0 := by
10121010
constructor
1013-
· contrapose!
1011+
· contrapose! +distrib
10141012
rintro (hs | rfl)
10151013
· exact nonempty_iff_ne_empty.1 (nonempty_iff_ne_empty.2 hs).zpow
10161014
· rw [← nonempty_iff_ne_empty]

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

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -662,10 +662,9 @@ lemma Nonempty.pow (hs : s.Nonempty) : ∀ {n}, (s ^ n).Nonempty
662662
| 0 => by simp
663663
| n + 1 => by rw [pow_succ]; exact hs.pow.mul hs
664664

665-
set_option push_neg.use_distrib true in
666665
@[to_additive (attr := simp)] lemma pow_eq_empty : s ^ n = ∅ ↔ s = ∅ ∧ n ≠ 0 := by
667666
constructor
668-
· contrapose!
667+
· contrapose! +distrib
669668
rintro (hs | rfl)
670669
· exact hs.pow
671670
· simp
@@ -820,10 +819,9 @@ lemma Nonempty.zpow (hs : s.Nonempty) : ∀ {n : ℤ}, (s ^ n).Nonempty
820819
| (n : ℕ) => hs.pow
821820
| .negSucc n => by simpa using hs.pow
822821

823-
set_option push_neg.use_distrib true in
824822
@[to_additive (attr := simp)] lemma zpow_eq_empty : s ^ n = ∅ ↔ s = ∅ ∧ n ≠ 0 := by
825823
constructor
826-
· contrapose!
824+
· contrapose! +distrib
827825
rintro (hs | rfl)
828826
· exact hs.zpow
829827
· simp

Mathlib/Algebra/Group/UniqueProds/Basic.lean

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ attribute [to_additive] TwoUniqueProds
260260
lemma uniqueMul_of_twoUniqueMul {G} [Mul G] {A B : Finset G} (h : 1 < #A * #B →
261261
∃ p1 ∈ A ×ˢ B, ∃ p2 ∈ A ×ˢ B, p1 ≠ p2 ∧ UniqueMul A B p1.1 p1.2 ∧ UniqueMul A B p2.1 p2.2)
262262
(hA : A.Nonempty) (hB : B.Nonempty) : ∃ a ∈ A, ∃ b ∈ B, UniqueMul A B a b := by
263-
set_option push_neg.use_distrib true in by_cases! hc : #A ≤ 1 ∧ #B ≤ 1
263+
by_cases! +distrib hc : #A ≤ 1 ∧ #B ≤ 1
264264
· exact UniqueMul.of_card_le_one hA hB hc.1 hc.2
265265
rw [← Finset.card_pos] at hA hB
266266
obtain ⟨p, hp, _, _, _, hu, _⟩ := h (Nat.one_lt_mul_iff.mpr ⟨hA, hB, hc⟩)
@@ -435,7 +435,7 @@ open UniqueMul in
435435
let _ := isWellFounded_ssubset (α := ∀ i, G i) -- why need this?
436436
apply IsWellFounded.induction (· ⊂ ·) A; intro A ihA B hA
437437
apply IsWellFounded.induction (· ⊂ ·) B; intro B ihB hB
438-
set_option push_neg.use_distrib true in by_cases! hc : #A ≤ 1 ∧ #B ≤ 1
438+
by_cases! +distrib hc : #A ≤ 1 ∧ #B ≤ 1
439439
· exact of_card_le_one hA hB hc.1 hc.2
440440
obtain ⟨i, hc⟩ := exists_or.mpr (hc.imp exists_of_one_lt_card_pi exists_of_one_lt_card_pi)
441441
obtain ⟨ai, hA, bi, hB, hi⟩ := uniqueMul_of_nonempty (hA.image (· i)) (hB.image (· i))

Mathlib/Analysis/SpecialFunctions/BinaryEntropy.lean

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,6 @@ lemma differentiableAt_binEntropy_iff_ne_zero_one :
183183
· simp [log_inv, mul_neg, ← neg_mul, ← negMulLog_def, differentiableAt_negMulLog_iff] at h
184184
· fun_prop (disch := simp)
185185

186-
set_option push_neg.use_distrib true in
187186
/-- Binary entropy has derivative `log (1 - p) - log p`.
188187
It's not differentiable at `0` or `1` but the junk values of `deriv` and `log` coincide there. -/
189188
lemma deriv_binEntropy (p : ℝ) : deriv binEntropy p = log (1 - p) - log p := by
@@ -196,7 +195,7 @@ lemma deriv_binEntropy (p : ℝ) : deriv binEntropy p = log (1 - p) - log p := b
196195
all_goals fun_prop (disch := assumption)
197196
-- pathological case where `deriv = 0` since `binEntropy` is not differentiable there
198197
· rw [deriv_zero_of_not_differentiableAt (differentiableAt_binEntropy_iff_ne_zero_one.not.2 hp)]
199-
push_neg at hp
198+
push_neg +distrib at hp
200199
obtain rfl | rfl := hp <;> simp
201200

202201
/-! ### `q`-ary entropy -/

Mathlib/Data/EReal/Operations.lean

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -751,7 +751,7 @@ lemma mul_ne_top (a b : EReal) :
751751
rw [ne_eq, mul_eq_top]
752752
-- push the negation while keeping the disjunctions, that is converting `¬(p ∧ q)` into `¬p ∨ ¬q`
753753
-- rather than `p → ¬q`, since we already have disjunctions in the rhs
754-
set_option push_neg.use_distrib true in push_neg
754+
push_neg +distrib
755755
rfl
756756

757757
lemma mul_eq_bot (a b : EReal) :
@@ -763,7 +763,7 @@ lemma mul_eq_bot (a b : EReal) :
763763
lemma mul_ne_bot (a b : EReal) :
764764
a * b ≠ ⊥ ↔ (a ≠ ⊥ ∨ b ≤ 0) ∧ (a ≤ 0 ∨ b ≠ ⊥) ∧ (a ≠ ⊤ ∨ 0 ≤ b) ∧ (0 ≤ a ∨ b ≠ ⊤) := by
765765
rw [ne_eq, mul_eq_bot]
766-
set_option push_neg.use_distrib true in push_neg
766+
push_neg +distrib
767767
rfl
768768

769769
/-- `EReal.toENNReal` is multiplicative. For the version with the nonnegativity

Mathlib/Data/Finite/Prod.lean

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -178,8 +178,7 @@ protected theorem infinite_prod :
178178
· exact h.1.prod_right h.2
179179

180180
theorem finite_prod : (s ×ˢ t).Finite ↔ (s.Finite ∨ t = ∅) ∧ (t.Finite ∨ s = ∅) := by
181-
set_option push_neg.use_distrib true in
182-
contrapose!; exact Set.infinite_prod
181+
contrapose! +distrib; exact Set.infinite_prod
183182

184183
protected theorem Finite.offDiag {s : Set α} (hs : s.Finite) : s.offDiag.Finite :=
185184
(hs.prod hs).subset s.offDiag_subset_prod
@@ -236,7 +235,7 @@ theorem infinite_image2 (hfs : ∀ b ∈ t, InjOn (fun a => f a b) s) (hft : ∀
236235

237236
lemma finite_image2 (hfs : ∀ b ∈ t, InjOn (f · b) s) (hft : ∀ a ∈ s, InjOn (f a) t) :
238237
(image2 f s t).Finite ↔ s.Finite ∧ t.Finite ∨ s = ∅ ∨ t = ∅ := by
239-
set_option push_neg.use_distrib true in contrapose!
238+
contrapose! +distrib
240239
rw [Set.infinite_image2 hfs hft]
241240
grind only [Set.Infinite.nonempty]
242241

Mathlib/Geometry/Euclidean/Angle/Oriented/Basic.lean

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -410,8 +410,7 @@ theorem oangle_eq_zero_or_eq_pi_iff_right_eq_smul {x y : V} :
410410
are linearly independent. -/
411411
theorem oangle_ne_zero_and_ne_pi_iff_linearIndependent {x y : V} :
412412
o.oangle x y ≠ 0 ∧ o.oangle x y ≠ π ↔ LinearIndependent ℝ ![x, y] := by
413-
set_option push_neg.use_distrib true in
414-
contrapose!; exact oangle_eq_zero_or_eq_pi_iff_not_linearIndependent o
413+
contrapose! +distrib; exact oangle_eq_zero_or_eq_pi_iff_not_linearIndependent o
415414

416415
/-- Two vectors are equal if and only if they have equal norms and zero angle between them. -/
417416
theorem eq_iff_norm_eq_and_oangle_eq_zero (x y : V) : x = y ↔ ‖x‖ = ‖y‖ ∧ o.oangle x y = 0 := by

Mathlib/LinearAlgebra/LinearIndependent/Defs.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -633,7 +633,7 @@ theorem not_linearIndependent_iffₒₛ :
633633
∃ (s t : Finset ι) (f : ι → R),
634634
Disjoint s t ∧ ∑ i ∈ s, f i • v i = ∑ i ∈ t, f i • v i ∧ ∃ i ∈ s, 0 < f i := by
635635
simp only [linearIndependent_iffₒₛ, pos_iff_ne_zero]
636-
set_option push_neg.use_distrib true in push_neg
636+
push_neg +distrib
637637
refine ⟨fun ⟨s, t, f, hst, heq, h⟩ => ?_,
638638
fun ⟨s, t, f, hst, heq, hi⟩ => ⟨s, t, f, hst, heq, .inl hi⟩⟩
639639
rcases h with ⟨i, hi, hfi⟩ | ⟨i, hi, hgi⟩

Mathlib/NumberTheory/Padics/PadicVal/Basic.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ theorem maxPowDiv_eq_multiplicity {p n : ℕ} (hp : 1 < p) (hn : n ≠ 0) (h : F
9898
@[csimp]
9999
theorem padicValNat_eq_maxPowDiv : @padicValNat = @maxPowDiv := by
100100
ext p n
101-
set_option push_neg.use_distrib true in by_cases! h : 1 < p ∧ 0 < n
101+
by_cases! +distrib h : 1 < p ∧ 0 < n
102102
· rw [padicValNat_def' h.1.ne' h.2.ne', maxPowDiv_eq_multiplicity h.1 h.2.ne']
103103
exact Nat.finiteMultiplicity_iff.2 ⟨h.1.ne', h.2
104104
· rcases h with (h | h)

Mathlib/NumberTheory/WellApproximable.lean

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -296,8 +296,7 @@ theorem addWellApproximable_ae_empty_or_univ (δ : ℕ → ℝ) (hδ : Tendsto
296296
rw [OrderIso.apply_blimsup e, ← hu₀ p]
297297
exact blimsup_congr (Eventually.of_forall fun n hn =>
298298
approxAddOrderOf.vadd_eq_of_mul_dvd (δ n) hn.1 hn.2)
299-
set_option push_neg.use_distrib true in
300-
by_cases! h : ∀ p : Nat.Primes, A p =ᵐ[μ] (∅ : Set 𝕊) ∧ B p =ᵐ[μ] (∅ : Set 𝕊)
299+
by_cases! +distrib h : ∀ p : Nat.Primes, A p =ᵐ[μ] (∅ : Set 𝕊) ∧ B p =ᵐ[μ] (∅ : Set 𝕊)
301300
· replace h : ∀ p : Nat.Primes, (u p +ᵥ E : Set _) =ᵐ[μ] E := by
302301
intro p
303302
replace hE₂ : E =ᵐ[μ] C p := hE₂ p (h p)

0 commit comments

Comments
 (0)