Zulip Chat Archive

Stream: Is there code for X?

Topic: Flipping an inequality


Labyrinth (Oct 02 2025 at 16:13):

Hi, newbie here.

I have a rather simple question: How to turn a goal of the form b \ge a to a goal of the form a \le b?

I've seen that b \ge a is an abbreviation for a \le b, so I thought the following would work (from Glimpse of Lean):

def extraction (φ :   ) :=  n m, n < m  φ n < φ m

lemma id_le_extraction' : extraction φ   n, n  φ n := by
  intro hyp n
  induction n with
  | zero => exact Nat.zero_le (φ 0)
  | succ n ih => exact Nat.succ_le_of_lt (by
      calc n  φ n := ih
        _    < φ (n + 1) := by apply hyp; exact lt_add_one n)

lemma extraction_ge : extraction φ   N N',  n  N', φ n  N := by
  intro hyp N N'
  use max N N'
  constructor
  calc
    N'     max N N'  := Nat.le_max_right N N'
    _   φ (max N N') := id_le_extraction' hyp (max N N')

However, before even being able to finish the proof, I got an error.
Even more confusingly, it says

'calc' expression has type
  N'  φ (max N N') : Prop
but is expected to have type
  max N N'  N' : Prop

And I have no clue why the max N N' ≥ N' : Prop is "expected".

Any help?

Labyrinth (Oct 02 2025 at 16:15):

PS: I know that I can do the calc the "other way around" to comply with the inequality in the goal, but I still want to know how to flip the inequality and why it's giving me that error message.

Labyrinth (Oct 02 2025 at 16:16):

Update: I figured it out, and turns out I'm just terrible at reading... How do I delete an entire topic? lol...

Kenny Lau (Oct 02 2025 at 16:20):

@Labyrinth btw the idiomatic answer is that \ge is not supported and you should use \le everywhere.

Labyrinth (Oct 02 2025 at 16:20):

@Kenny Lau Not supported? By what? Lean 4 Web seems to understand it fine

Kenny Lau (Oct 02 2025 at 16:21):

it means "just don't use it at all"

Kenny Lau (Oct 02 2025 at 16:21):

not supported by the wealth of theorems that are in mathlib

Jireh Loreaux (Oct 02 2025 at 16:22):

Kenny, that's not really accurate. Just because our style guidelines say "prefer ≤ to ≥" doesn't mean the latter is "not supported" or you "shouldn't use it".

Jireh Loreaux (Oct 02 2025 at 16:23):

In fact, ∃ n ≥ N is exactly one of the cases that we use throughout Mathlib.

Labyrinth (Oct 02 2025 at 16:23):

@Kenny Lau Is it that bad? I can only believe you - I haven't done much in Lean yet to contradict anyone, but shouldn't defining it as an abbreviation for le work just fine?

Jireh Loreaux (Oct 02 2025 at 16:24):

In fact, a ≥ b is already an abbreviation for b ≤ a, so you should be able to use them (almost) interchangeably everywhere.

Kenny Lau (Oct 02 2025 at 16:25):

my answer to that would be, abbrev isn't as strong as I would like it to be, it doesn't actually behave as abbreviation everywhere, Lean still actually treats them as different objects

Kenny Lau (Oct 02 2025 at 16:25):

I would like to see notation everywhere basically

Labyrinth (Oct 02 2025 at 16:26):

What's the difference between abbrev and notation?

Jireh Loreaux (Oct 02 2025 at 16:26):

sure, but it's almost the same, and there's no need to confuse new users by saying they should never write .

Robin Arnez (Oct 02 2025 at 16:26):

Yeah, working with a ≥ b is totally fine but mathlib prefers the spelling b ≤ a. In other words, you can use all of mathlib's API just as well with with maybe ge_iff_le sometimes but this is simply not done in mathlib

Weiyi Wang (Oct 02 2025 at 16:26):

To answer one of the original question, you can do this to explicitly flip the inequality

rw [ge_iff_le]

Jireh Loreaux (Oct 02 2025 at 16:27):

notation is syntactically equal to the original, while abbrev is reducibly definitionally equal to the original.

Labyrinth (Oct 02 2025 at 16:27):

Is there any situation in which the difference matters?

Robin Arnez (Oct 02 2025 at 16:28):

Well, when you have an abbrev, you will still see the name (or the notation) of the abbrev and not of the underlying definition. With syntax, writing it either way has literally no noticeable difference

Robin Arnez (Oct 02 2025 at 16:29):

This sometimes matters for e.g. rw because rw works more on a basis of "syntactical" equality

Labyrinth (Oct 02 2025 at 16:30):

Well, when you have an abbrev, you will still see the name (or the notation) of the abbrev and not of the underlying definition. With syntax, writing it either way has literally no noticeable difference

So, it affects the "goal view" or whatever it's called(?)

Jireh Loreaux (Oct 02 2025 at 16:30):

yes, but it's a small-ish difference which I would ignore while you're still learning. Basically, notation is for providing notation (e.g., M →* N for MonoidHom M N) whereas abbrev is for defining two things which are the same under the hood, but you like to have a different name for it, e.g., StrongDual 𝕜 E is an abbreviation for E →L[𝕜] 𝕜 (which itself is notation for ContinuousLinearMap (RingHom.id 𝕜) E E).

Labyrinth (Oct 02 2025 at 16:32):

Understood. Thanks!

Kenny Lau (Oct 02 2025 at 16:32):

Labyrinth said:

Is there any situation in which the difference matters?

yes, abbrev creates a new object that Lean unfolds most of the time, and notation means that it's just a shorthand and to Lean they are always the same object

Kenny Lau (Oct 02 2025 at 16:34):

I think I would still like to insist on the point that mathlib "basically always" prefers <= over >=

Jireh Loreaux (Oct 02 2025 at 16:35):

Kenny, if Labyrinth were writing a PR, then this would be a relevant comment, but for a new user not trying to contribute to Mathlib at the moment, it's just noise. But sure, you're correct that Mathlib almost always prefers .

Kenny Lau (Oct 02 2025 at 16:36):

it's relevant if they are trying to use theorems in lean / mathlib and not finding the theorems they want for >= and only finding the <= theorems

Kenny Lau (Oct 02 2025 at 16:36):

they still basically have to use ge_iff_le to turn every >= into <=

Jireh Loreaux (Oct 02 2025 at 16:43):

Sure, for finding lemmas it's helpful to know. I take back what I said about your "basically always" comment, as I was conflating it with your earlier comment that is "not supported" or "shoudn't be used".

Labyrinth (Oct 02 2025 at 17:03):

Unrelated side note: I love Lean (<insert image of original "I Love Lean!!!" meme but edited to have Lean 4 on top of the drink>). I was trying to use Rocq not long ago, and I could not find proper documentation or tutorials for beginners. The entry barrier was just too strong and academic. Lean 4 has been really easy to pick up, and in just an hour or two I got more progress than in several hours of trying to make Rocq work

Jason Reed (Oct 02 2025 at 18:15):

I had a pre-edit comment here about thinking that local hypotheses of > or \ge were useful for grw, but I think I've talked myself out of it. It seems like suffices to manipulate either side of an inequality in either a hypothesis or goal, even if all goals in sight are < or \le.

import Mathlib

example (a b c : ) : True := by
  have k : a < b := by sorry
  have h : b < c := by sorry
  grw [h] at k
  -- now k : a < c
  sorry

example (a b c : ) : True := by
  have k : a < b := by sorry
  have h : c < a := by sorry
  grw [ h] at k
  -- now k : c < b
  sorry

example (a b c : ) : a < b := by
  have h : a < c := by sorry
  grw [h]
  -- now goal is c < b
  sorry

example (a b c : ) : a < b := by
  have h : c < b := by sorry
  grw [ h]
  -- now goal is a < c
  sorry

Although maybe it is still worth drawing attention to grw as a situation where a < b and b > a are not interchangeable, as the former implies trying to generalized-rewrite a to b and the latter b to a.


Last updated: Dec 20 2025 at 21:32 UTC