Zulip Chat Archive
Stream: Is there code for X?
Topic: surjective is not funprop!
Kenny Lau (Jul 09 2025 at 11:21):
import Mathlib
lemma foo : Function.Surjective (id : ℕ → ℕ) := by fun_prop
/-
`Function.Surjective id` is not a `fun_prop` goal!
Maybe you forgot marking `Function.Surjective` with `@[fun_prop]`.
-/
attribute [fun_prop] Function.Surjective
attribute [fun_prop] Function.surjective_id
lemma foo' : Function.Surjective (id : ℕ → ℕ) := by fun_prop
Kenny Lau (Jul 09 2025 at 11:22):
Why is Function.Surjective not marked as fun_prop?
Floris van Doorn (Jul 09 2025 at 11:32):
Nobody has done it yet.
I think it would be good to mark Surjective and friends as fun_prop, I think this was recently suggested elsewhere on Zulip.
Kenny Lau (Jul 09 2025 at 19:28):
@Floris van Doorn I want to do it. Which file should I do this in? I see that Mathlib.Tactic.FunProp is imported by:
Mathlib.Tactic.FunProp.Differentiable
Mathlib.Topology.Defs.Basic
Mathlib.MeasureTheory.MeasurableSpace.Embedding
Mathlib.Tactic.FunProp.ContDiff
Mathlib.Tactic.ContinuousFunctionalCalculus
Mathlib
Mathlib.Tactic
which all seem to be quite late in the import hierarchy compared to Mathlib/Logic/Function/Defs.lean which contains the definitions of injective, surjective, and bijective.
Ruben Van de Velde (Jul 09 2025 at 19:53):
Yeah, somewhere under Mathlib.Tactic.FunProp
Kenny Lau (Jul 10 2025 at 00:45):
@Ruben Van de Velde are you referring to the file itself, or a new file? If it's a new file, where should I put the new file?
Aaron Liu (Jul 10 2025 at 00:46):
Is docs#Function.Injective a fun_prop property? Can you put it together with that if it is?
Jireh Loreaux (Jul 10 2025 at 05:00):
@Kenny Lau you should only need to import Mathlib.Tactic.FunProp.Attr in order to mark them as @[fun_prop], and this file has very lightweight imports.
Kenny Lau (Jul 10 2025 at 09:40):
@Jireh Loreaux Are you saying I should import M.T.FunProp.Attr from M.Logic.Function.Defs?
Michael Rothgang (Jul 10 2025 at 09:47):
I'm not Jireh, but that's how I read the message.
Jireh Loreaux (Jul 10 2025 at 13:36):
Yes. The imports for Mathlib.Logic.Function.Defs are so minimal that the large-import tag might get placed on it anyway, but if so and someone complains we can have a discussion.
Kenny Lau (Aug 10 2025 at 17:16):
(#mathlib4 > `fun_prop` for Injective/Surjective/Bijective? @ 💬 )
Robert Maxton (Aug 11 2025 at 11:21):
Indeed, the only reason I haven't done it myself is that I've been waiting til I have the attention to write a script to find all the lemmas that prove injective/etc
Robert Maxton (Aug 11 2025 at 11:21):
and automatically fun_prop them, as I expect there to be hundreds if not thousands of them ^.^;
Kenny Lau (Aug 11 2025 at 11:35):
ah, I should add that I have made a very small start at #28191
Kenny Lau (Aug 11 2025 at 11:36):
@Robert Maxton Loogle already exists
Robert Maxton (Aug 11 2025 at 11:37):
Loogle exists, but I don't see an amazing way of tying it into a script, and for that matter I don't even see a way to get more than the first 200 results ^.^;
Kenny Lau (Aug 11 2025 at 11:38):
I think #loogle exists as a command if you do the right things
Jovan Gerbscheid (Aug 11 2025 at 12:03):
Would it also make sense to have fun_prop for Monotone/Antitone?
Btw I was recently running into the annoyance that the Monotone/Antitone lemmas are also useful in their unfolded form, since gcongr currently only takes that form. Any advice on what to do here? State them only in one form, or have some automation to get both forms?
Kenny Lau (Aug 11 2025 at 12:03):
yes
Kenny Lau (Aug 11 2025 at 12:03):
Jovan Gerbscheid said:
since
gcongrcurrently only takes that form
change gcongr?
Jovan Gerbscheid (Aug 13 2025 at 09:11):
There is another reason to prefer the expanded form, at least when dealing with a lambda function (Monotone fun x => ...), namely that the lambda may not get beta-reduced:
import Mathlib
example (a b : ℝ) (h : a ≤ b) : False := by
have := monotone_mul_left_of_nonneg zero_le_two h
-- this : (fun x => 2 * x) a ≤ (fun x => 2 * x) b
But yes it would make sense to prove only the Monotone version for non-lambda functions.
Alex Meiburg (Aug 14 2025 at 18:58):
I also today ran into wanting StrictMono and StrictAnti as well.
On that note,
theorem Real.sqrt_mono : Monotone Real.sqrt :=
fun _ _ ↦ Real.sqrt_le_sqrt
was missing too...
Jovan Gerbscheid (Aug 14 2025 at 19:03):
Note that the naming convention is to call it sqrt_monotone, as we are referring to the definition Monotone. I have a PR somewhere to fix this, which I'll get back to after the fix to gcongr gets merged in #28339
Jireh Loreaux (Aug 14 2025 at 21:33):
or rather monotone_sqrt.
Jovan Gerbscheid (Aug 14 2025 at 21:58):
No, the naming convention specifically says to use monotone and friends as suffixes. Similarly for surjective and friends
Jireh Loreaux (Aug 14 2025 at 22:00):
I always forget that one. I really dislike that convention.
Alex Meiburg (Aug 17 2025 at 14:45):
Well, #28550 should be an easy review at least
Last updated: Dec 20 2025 at 21:32 UTC