Zulip Chat Archive

Stream: Is there code for X?

Topic: If `a + b ≤ 2 * c` then one of them is `≤ c`


Eric Wieser (Dec 10 2022 at 19:59):

Do we have anything resembling the following?

import data.nat.order.lemmas
import tactic.linarith

lemma min_le_of_add_le_two_mul {α} [linear_ordered_semiring α] [has_exists_add_of_le α]
  (a b c : α) (h : a + b  2 * c) : min a b  c :=
begin
  cases le_total a b with hab hba,
  { refine (min_le_left _ _).trans _,
    obtain b, rfl := exists_add_of_le hab,
    have := (add_le_add_left hab a).trans h,
    rw two_mul at this,
    exact le_of_mul_le_mul_left this zero_lt_two },
  { refine (min_le_right _ _).trans _,
    obtain a, rfl := exists_add_of_le hba,
    have := (add_le_add_right hba b).trans h,
    rw two_mul at this,
    exact le_of_mul_le_mul_left this zero_lt_two },
end

Is this the correct set of typeclasses? Or can it be made to work with smul instead of mul?

cc @Junyan Xu (the context is #17743) and @Yaël Dillies (this is order stuff)

Yaël Dillies (Dec 10 2022 at 20:11):

It reminds me of docs#add_le_add_iff_of_ge

Yaël Dillies (Dec 10 2022 at 20:13):

Probably the correct thing to prove is

@[to_additive]
lemma min_le_max_of_mul_le_mul [not_sure α] [has_exists_mul_of_le α]
  {a b c d : α} (h : a * b  c * d) : min a b  max c d := sorry

Eric Wieser (Dec 10 2022 at 20:14):

Obviously the follow-up is the n-ary versions

Yaël Dillies (Dec 10 2022 at 20:14):

I think the key property you want is a ^ 2 ≤ b ^ 2 → a ≤ b. Then the proof is (min a b) ^ 2 ≤ a * b ≤ c * d ≤ (max c d) ^ 2.

Eric Wieser (Dec 10 2022 at 20:21):

Indeed, if I prove (h : a + b ≤ c + d) : min a b ≤ max c d first them my lemmas falls out as special cases

Eric Wieser (Dec 10 2022 at 20:24):

lemma le_of_two_nsmul_le_two_nsmul {α} [linear_ordered_semiring α]
  {a b : α} (h : 2  a  2  b) : a  b :=
begin
  rw [two_nsmul, two_nsmul, two_mul, two_mul] at h,
  exact le_of_mul_le_mul_left h zero_lt_two
end

lemma min_le_max_of_add_le_add {α} [linear_ordered_semiring α] [has_exists_add_of_le α]
  {a b c d : α} (h : a + b  c + d) : min a b  max c d :=
begin
  cases le_total a b with hab hba,
  { refine (min_le_left _ _).trans _,
    obtain b, rfl := exists_add_of_le hab,
    cases le_total c d with hcd hdc,
    { refine le_trans _ (le_max_right _ _),
      obtain d, rfl := exists_add_of_le hcd,
      have := ((add_le_add_left hab _).trans h).trans (add_le_add_right hcd _),
      rw [two_nsmul, two_nsmul] at this,
      exact le_of_two_nsmul_le_two_nsmul this },
    { refine le_trans _ (le_max_left _ _),
      obtain c, rfl := exists_add_of_le hdc,
      have := ((add_le_add_left hab _).trans h).trans (add_le_add_left hdc _),
      rw [two_nsmul, two_nsmul] at this,
      exact le_of_two_nsmul_le_two_nsmul this } },
  { refine (min_le_right _ _).trans _,
    obtain a, rfl := exists_add_of_le hba,
    cases le_total c d with hcd hdc,
    { refine le_trans _ (le_max_right _ _),
      obtain d, rfl := exists_add_of_le hcd,
      have := ((add_le_add_right hba _).trans h).trans (add_le_add_right hcd _),
      rw [two_nsmul, two_nsmul] at this,
      exact le_of_two_nsmul_le_two_nsmul this },
    { refine le_trans _ (le_max_left _ _),
      obtain c, rfl := exists_add_of_le hdc,
      have := ((add_le_add_right hba _).trans h).trans (add_le_add_left hdc _),
      rw [two_nsmul, two_nsmul] at this,
      exact le_of_two_nsmul_le_two_nsmul this } },
end

lemma min_le_of_add_le_two_mul {α} [linear_ordered_semiring α] [has_exists_add_of_le α]
  {a b c : α} (h : a + b  2 * c) : min a b  c :=
by simpa using min_le_max_of_add_le_add (h.trans_eq $ two_mul _)

lemma le_max_of_add_le_two_mul {α} [linear_ordered_semiring α] [has_exists_add_of_le α]
  {a b c : α} (h : 2 * c  a + b) : c  max a b :=
by simpa using min_le_max_of_add_le_add ((two_mul _).symm.trans_le h)

Yaël Dillies (Dec 10 2022 at 20:25):

Can you first prove a ^ 2 ≤ b ^ 2 → a ≤ b as I suggested above?

Eric Wieser (Dec 10 2022 at 20:27):

I doubt it, I expect we don't have any proof that can be additivized here without some new typeclasses

Yaël Dillies (Dec 10 2022 at 20:27):

We sure do. linear_order + monotonicity of multiplication is already enough.

Yaël Dillies (Dec 10 2022 at 20:28):

Something like docs#le_of_pow_le_pow (which is definitely a misnomer!)

Yaël Dillies (Dec 10 2022 at 20:30):

And of course you can generalise this to any strictly monotone function. So the real deal is docs#strict_mono.reflect_le. We only have docs#monotone.reflect_lt :sad: .

Eric Wieser (Dec 10 2022 at 20:33):

Edited the above to at least extract the lemma you asked for

Yaël Dillies (Dec 10 2022 at 20:34):

/me is writing a new proof

Kevin Buzzard (Dec 10 2022 at 20:34):

These look easy by contradiction

Kevin Buzzard (Dec 10 2022 at 20:47):

lemma min_le_of_add_le_two_mul {α} [linear_ordered_semiring α] [has_exists_add_of_le α]
  (a b c : α) (h : a + b  2 * c) : min a b  c :=
begin
  refine le_imp_le_of_lt_imp_lt (λ h2, _) h,
  cases lt_min_iff.1 h2 with h3 h4,
  rw two_mul,
  exact add_lt_add h3 h4,
end

lemma le_max_of_add_le_two_mul {α} [linear_ordered_semiring α] [has_exists_add_of_le α]
  (a b c : α) (h : 2 * c  a + b) : c  max a b :=
begin
  refine le_imp_le_of_lt_imp_lt (λ h2, _) h,
  cases max_lt_iff.1 h2 with h3 h4,
  rw two_mul,
  exact add_lt_add h3 h4,
end

Kevin Buzzard (Dec 10 2022 at 20:52):

import data.nat.order.lemmas
import tactic.linarith

lemma min_le_max_of_add_le_add {α} [linear_ordered_semiring α] [has_exists_add_of_le α]
  {a b c d : α} (h : a + b  c + d) : min a b  max c d :=
begin
  refine le_imp_le_of_lt_imp_lt (λ h2, _) h,
  rw [max_lt_iff, lt_min_iff, lt_min_iff] at h2,
  rcases h2 with ⟨⟨h3, -⟩, -, h4⟩⟩,
  exact add_lt_add h3 h4,
end

Kevin Buzzard (Dec 10 2022 at 20:54):

Proving a conclusion min a b <= c is annoying because you don't know which one will be the min. But having a hypothesis c < min a b is really powerful because you can deduce c < a and c < b.

Yaël Dillies (Dec 10 2022 at 20:54):

import algebra.group_power.basic
import algebra.order.monoid.lemmas
import order.lattice

open function

variables {α β : Type*}

section preorder
variables [add_monoid α] [preorder α] [preorder β] {f g : β  α}
  [covariant_class α α (+) (<)] [covariant_class α α (swap (+)) (<)]

lemma strict_mono.nsmul (hf : strict_mono f) :  {n : }, n  0  strict_mono (λ a, n  f a)
| 0 hn := (hn rfl).elim
| 1 hn := by simpa
| (n + 2) hn := by { simp_rw succ_nsmul _ (n + 1), exact hf.add (strict_mono.nsmul n.succ_ne_zero) }

end preorder

section preorder
variables [monoid α] [preorder α] [preorder β] {f g : β  α}
  [covariant_class α α (*) (<)] [covariant_class α α (swap (*)) (<)]

@[to_additive]
lemma strict_mono.pow (hf : strict_mono f) :  {n : }, n  0  strict_mono (λ a, f a ^ n)
| 0 hn := (hn rfl).elim
| 1 hn := by simpa
| (n + 2) hn := by { simp_rw pow_succ _ (n + 1), exact hf.mul' (strict_mono.pow n.succ_ne_zero) }

@[to_additive]
lemma strict_mono_pow {n : } (hn : n  0) : strict_mono (λ a : α, a ^ n) := strict_mono_id.pow hn

end preorder

section linear_order
variables [monoid α] [linear_order α] [covariant_class α α (*) (<)]
  [covariant_class α α (swap (*)) (<)] {a b c d : α} {n : }

@[to_additive le_of_nsmul_le_nsmul]
lemma le_of_pow_le_pow' {n : } (hn : n  0) : a ^ n  b ^ n  a  b :=
(strict_mono_pow hn).le_iff_le.1

variables [covariant_class α α (*) ()] [covariant_class α α (swap (*)) ()]

@[to_additive]
lemma min_le_max_of_mul_le_mul (h : a * b  c * d) : min a b  max c d :=
le_of_pow_le_pow' two_ne_zero $ by { simp_rw pow_two, exact (mul_le_mul' inf_le_left
  inf_le_right).trans (h.trans $ mul_le_mul' le_sup_left le_sup_right) }

end linear_order

Yaël Dillies (Dec 10 2022 at 20:54):

This all follows what I said above.

Yaël Dillies (Dec 10 2022 at 20:56):

(btw I'm a bit horrified by the amount of imports I need to say "give me basic algebraic order theory". How come lattices not be imported by the algebraic order hierarchy?)

Junyan Xu (Dec 10 2022 at 21:19):

Kevin's proof also works under these assumptions (don't even need to assume [covariant_class α α (*) (≤)] [covariant_class α α (swap (*)) (≤)]:

import algebra.order.monoid.defs
import order.min_max

lemma min_le_max_of_add_le_add {α} [has_add α] [linear_order α]
  [covariant_class α α (+) (<)] [covariant_class α α (function.swap (+)) (<)]
  (a b c d : α) (h : a + b  c + d) : min a b  max c d :=
begin
  simp_rw [min_le_iff, le_max_iff],
  contrapose! h,
  exact add_lt_add h.1.1 h.2.2,
end

Eric Wieser (Dec 10 2022 at 21:21):

Are the lt versions easy too, with either spelling?

Eric Wieser (Dec 10 2022 at 21:23):

Note that docs#zpow_strict_mono already exists, so your name might need disambiguating somehow

Junyan Xu (Dec 10 2022 at 21:28):

It's worrying that docs#zpow_strict_mono_left and docs#pow_strict_mono_left aren't analogous facts ...

Yaël Dillies (Dec 10 2022 at 21:28):

I've been annoyed for a long at those names but it's really hard to come up with better names before you have all the lemmas.

Junyan Xu (Dec 10 2022 at 21:30):

Are the lt versions easy too, with either spelling?

If you mean this, it holds with (<) in the covariant hypotheses replaced by (≤), or under the cleaner assumption linear_ordered_add_comm_monoid:

lemma min_lt_max_of_add_lt_add {α} [linear_ordered_add_comm_monoid α]
  (a b c d : α) (h : a + b < c + d) : min a b < max c d :=
begin
  simp_rw [min_lt_iff, lt_max_iff],
  contrapose! h,
  exact add_le_add h.1.1 h.2.2,
end

Junyan Xu (Dec 10 2022 at 21:32):

(I think the (≤) version doesn't necessarily hold for linear_ordered_add_comm_monoid because you can consider absorptive addition on {0,1,2} then you'd have 1 + 1 = 2 + 2 = 2 but 2 ≰ 1.)

Yaël Dillies (Dec 10 2022 at 21:36):

Updated my snippet above to include the < versions.

Eric Wieser (Dec 10 2022 at 22:36):

Is the mathlib4 tide past the natural place to PR these yet?

Yaël Dillies (Dec 10 2022 at 23:35):

Mostly not, but it's very close to the border.

Eric Wieser (Dec 10 2022 at 23:38):

Are you happy to PR the earlier mono lemmas?

Eric Wieser (Dec 11 2022 at 12:04):

#17895


Last updated: Dec 20 2023 at 11:08 UTC