Zulip Chat Archive

Stream: general

Topic: Implicit proof (proposition) argument in partial function


Jineon Baek (Apr 27 2022 at 01:11):

I would like to define a partial function like the following.

import tactic.basic

def f (a b : ) {h : a < b} :  := a + b

example (a b : ) (h : a < b) : f a b = f a b := sorry

So the function f is basically addition, but it is restricted so that the second argument is always greater than one.

I didn't want to put the hypothesis a < b every time I invoke the function f a b, so I made the hypothesis implicit.
But then the example line gives me the following (rather confusing for me) error.

don't know how to synthesize placeholder
context:
a b : ,
h : a < b
 a < b

To the best of my knowledge the value of h : a < b does not affect f a b h at all because all proofs of a proposition is considered equal in lean, and I believe it can be also shown by rfl. The seemingly obvious placeholder message makes me confused further. Your insight on why is it happening, and what can we do to make it work would be much appreciated here.

Julian Berman (Apr 27 2022 at 02:21):

I'm no expert, but I think from what I've seen, fundamentally the recommendation is to not try to define partial functions like that. Instead define a total function which returns garbage outside the range you care about, but when you prove things about your function, now you can include the hypothesis that the value is in the range where it makes sense.

E.g. in Lean you can indeed divide by zero, and get some garbage value, but no mathematically meaningful proof will do so (with the caveat that sometimes things indeed do do so because the garbage value sometimes conveniently simplifies proofs!)

Kyle Miller (Apr 27 2022 at 02:46):

Implicit arguments are solved for using unification. The "don't know how to synthesize placeholder" error means that there was nothing in the expression that led Lean to fill in a value for h using unification alone.

It's true that all proofs of propositions are equal to each other, but Lean won't try to synthesize a proof for you for implicit arguments.

You can tell Lean the name of a tactic to use, though, to try to synthesize a proof for optional arguments. For example, if you expect h to always be a local variable, you can use tactic.assumption.

import tactic.basic

def f (a b : ) (h : a < b . tactic.assumption) :  := a + b

example (a b : ) (h : a < b) : f a b = f a b h := sorry
-- notice that we can still pass `h` ourselves if we want

Another choice is obviously to use the tidy tactic (or whatever it is that obviously is set to do).

Junyan Xu (Apr 27 2022 at 03:30):

I wonder if people have considered using d : Π (i j : ι) (h : c.rel i j . tactic.omega), self.X i ⟶ self.X j to define docs#homological_complex; what would be the advantage/disadvantage compared to the current approach? (tactic#omega is probably too powerful for this purpose.)

Jineon Baek (Apr 27 2022 at 17:32):

Thank you for all of your input. Both directions (not using partial function / using tactic synthesis) help practically. @Kyle Miller May I ask what is exactly meant for 'unification'? My guess is that it is a process of deriving what is equal to what from the assumption that two things are equal, like from f a 3 = f 4 bwe infer a=4 and 3=b. Also, I wonder if such tactic synthesis is also possible in lean4 - I'll defer this question to lean4 if needed.


Last updated: Dec 20 2023 at 11:08 UTC