Zulip Chat Archive

Stream: lean4

Topic: Let, have, show and assume


Artur Chakhvadze (Mar 15 2024 at 20:10):

Hi! I just started learning Lean 4 and I cannot understand the precise semantics and differences between let, have, show and assume. I haven't found any reference that explains in detail. Can someone clarify this for me?

Robert Maxton (Mar 15 2024 at 20:34):

@Artur Chakhvadze
First, of those, only let can be used as a term; the rest are all only applicable in tactic mode.

let defines a variable (which can be a function or a type, since those are all 'first class' in Lean -- that is, you can compute on them.)

Robert Maxton (Mar 15 2024 at 20:36):

have is like let, but assumes you only care about the type, so it throws away the actual definition. This is mostly useful for Props where the definition is a proof, and all you really care about is that the Prop is inhabited and not which specific proof you used to inhabit it (proof-irrelevance).

Julian Berman (Mar 15 2024 at 20:45):

have can be used in term mode too:

example : 2 = 2 := have : true := rfl; rfl

Robert Maxton (Mar 15 2024 at 20:46):

... huh. I literally just tried that to double check and got errors
oh, whoops, I typo'd. Nevermind! Then yes, let and have can both be used in term-mode

Julian Berman (Mar 15 2024 at 20:47):

It looks like show works in term mode as well:

example : 2 = 2 := show 2 = 2 from Eq.refl 2

Robert Maxton (Mar 15 2024 at 20:48):

Ah, that's show ... from..., which is not the same as show. But I suppose that's a quibble.

Julian Berman (Mar 15 2024 at 20:49):

I think the important bit is less what mode they work in. I'd add obtain and rcases as others which are "kind of similar".

Robert Maxton (Mar 15 2024 at 20:49):

I'm actually typing up an explanation, but keep getting interrupted :v

Julian Berman (Mar 15 2024 at 20:50):

Oh I'll keep quiet then :) go for it.

Robert Maxton (Mar 15 2024 at 20:52):

show t looks for a goal that unifies with t, which means it looks for a goal whose type is compatible with t. If t is a complete term, that means it needs to have the same type as t; if t has holes (_s) or metavariables (like ?foo), it looks for a goal for which some substitution of the holes and metavariables could be the same type as t. It makes that the current active goal and replaces the statement of the goal with t, with as many holes and metavariables filled in as it can infer.

(There is a detail here I don't actually know, which is the precise transparency level show works on when unifying. I suspect it works up to reducibility, but it may only work up to definitional equality. For a good overview of the difference, see this post)

Julian Berman (Mar 15 2024 at 20:55):

(I said I'd be quiet :), but since I suspect there's a chance someone new doesn't know what a few of those words mean, I think a "simplified" version of what show does is is it expresses "I have some goal, but I think that goal is really equivalent to a different one, so I'm telling Lean I'm going to prove the other equivalent goal and that it should be happy with that".

The details of what "equivalent" and "should be happy with" are what Robert explained with more precise words.)

Robert Maxton (Mar 15 2024 at 21:00):

show p from t involves let_fun, which is a bit confusing (at least to me!) so I'm going to skim over the details; it essentially constructs a term of type p from the argument t. from means it's working in term mode, so t should be a 'function' (or theorem, which is just a function on Props) that returns something of type p.

Alternatively, you can use show p by t, which is equivalent to show p from by t but looks less silly; it moves into tactic mode and constructs a p by the tactic(s) t.

Robert Maxton (Mar 15 2024 at 21:03):

aaaand I don't think assume is actually a thing! At least, Lean doesn't recognize it and I don't see any hits for assume outside of comments in the github.

Robert Maxton (Mar 15 2024 at 21:04):

aight, done, you can correct me at well now :p

Artur Chakhvadze (Mar 15 2024 at 21:09):

Thanks a lot for explaining everything in such detail! It is a shame that the official documentation doesn't have a page with those explanations.

I think I saw assume in some Lean 3 snippets and it probably isn't a thing in Lean 4 anymore.

One last question I have -- why do two first examples typecheck and the last one with have shows an error?
image.png

Robert Maxton (Mar 15 2024 at 21:15):

One thing I do recommend is to get your own copy of Mathlib in VSCode and abuse the hell out of the hover feature; it lets gives you quick access to all the docstring comments, which are honestly the principal source of documentation in Lean and Mathlib

Robert Maxton (Mar 15 2024 at 21:16):

it also lets you go-to-definition in a pinch, tho that can be very dense

Robert Maxton (Mar 15 2024 at 21:22):

w.r.t. example: so, as a side note, there's the theorem rfl, which is a term of type ∀ {α : Sort u} {a : α}, a = a; and then there's the tactic rfl, which is a much stronger low-level tactic that will do quite a bit more. so most of the time you will probably want := by rfl instead of := rfl

Anyway that's kind of orthogonal to your actual question lol. I'm not entirely sure why that happens, but I can at least give you the first step:

Robert Maxton (Mar 15 2024 at 21:28):

So, details on show ... from ... after all: show p from t is sugar for ((fun this => t) this) : p; that is, it makes a constant function fun _ => t, calls it on a dummy value, and then asserts the output has type p. This expansion passes through a let_fun definition that I believe is also how top-level definitions and theorems are implemented under the hood; they're both defined in such a way that the unification/type inference system, which is pretty powerful in Lean, has a chance to compare the intended and actual results before the type checker has to do its final verification.

Robert Maxton (Mar 15 2024 at 21:31):

I had thought that have also went through let_fun like that, but maybe not? Or maybe I'm just barking up the wrong tree entirely

Mario Carneiro (Mar 15 2024 at 22:03):

Artur Chakhvadze said:

I think I saw assume in some Lean 3 snippets and it probably isn't a thing in Lean 4 anymore.

It's spelled intro now


Last updated: May 02 2025 at 03:31 UTC