Zulip Chat Archive

Stream: new members

Topic: terminology for parts of a lean proof


rzeta0 (Jun 10 2024 at 12:33):

I'm a beginner so forgive the basic question about terminology:

-- 01 - First Proof by Calculation
import Mathlib.Tactic

example {x y : } (h1 : y = x + 4) (h2 : x = 3) : y = 7 := by
    calc
        y = x + 4 := by rw [h1]
        _ = 3 + 4 := by rw [h2]
       _ = 7 := by norm_num

Questions:

  1. Is example the name of the theorem we're proving (noting example is a special case)?
  2. Is the next section {x y : ℝ} called a type declaration?
  3. Is calc a strategy?
  4. I guess by rw and by num_norm are called tactics.
  5. UPDATE: is the section after := by called a justification?

I'm creating tutorials as I learn myself, and would like to know what the official naming of these things are.

Filippo A. E. Nuccio (Jun 10 2024 at 12:37):

Well, example is somewhat unique: if your code were

-- 01 - First Proof by Calculation
import Mathlib.Tactic

lemma foo{x y : } (h1 : y = x + 4) (h2 : x = 3) : y = 7 := by
    calc
        y = x + 4 := by rw [h1]
        _ = 3 + 4 := by rw [h2]
       _ = 7 := by norm_num

then we would say that foo is the name of the lemma, because actually it is the name of the term in the type y=7 that you are producing (in the context {x y : ℝ} (h1 : y = x + 4) (h2 : x = 3).

Filippo A. E. Nuccio (Jun 10 2024 at 12:37):

For example we are producing an "unnamed" term.

Filippo A. E. Nuccio (Jun 10 2024 at 12:38):

A type declaration is x: ℝ: it declares thatx is a term of type R\mathbb{R}.

Filippo A. E. Nuccio (Jun 10 2024 at 12:41):

In that example x and y are called "implicit variables": the fact that they are implicit comes from them living between curly braces, and it affects the way the lemma foo will be used. So all in all {x y : ℝ} are implicit variables declared to be of type .

Filippo A. E. Nuccio (Jun 10 2024 at 12:43):

  1. : calcis a "mode" (sometimes an "environment"): the two main other modes are "tactic mode" and "term mode". These are ways to make lean produce terms of the required type. See here.
  2. Yes, both rw and num_norm are tactics
  3. That section is called a proof, normally.

rzeta0 (Jun 10 2024 at 19:51):

thanks Filippo- I will need to read further about "modes"

also - what is the name given to the symbol/syntaxc := ... is it called a justification marker?

Markus Schmaus (Jun 10 2024 at 20:15):

  1. rw and num_norm are called tactics,by is a keyword which starts tactic mode, just like calc is a keyword which starts calc mode.
  2. everything after := is called the proof. By default you start out in term mode, by then start the tactic mode, and calc then starts the calc mode.

rzeta0 (Jun 10 2024 at 20:39):

hi @Markus Schmaus - so in the given example :

lemma foo{x y : } (h1 : y = x + 4) (h2 : x = 3) : y = 7 := by
    calc

... it seems like by starts tactic mode, but is immediately overridden by calc which starts calc mode. Does this mean by was not necessary?

if everything after := is a proof, then are the per-line := sub-proofs proving or justifying whatever equality/relation is immediately to their left?

Ruben Van de Velde (Jun 10 2024 at 20:43):

calc is both a mode and a tactic, just to confuse you :)

Ruben Van de Velde (Jun 10 2024 at 20:43):

And yes, in calc, you have a ~ b := proof that a ~ b

Markus Schmaus (Jun 10 2024 at 21:07):

I don't think there is a standard way to directly go from term mode to calc mode, so the by is necessary, but it would be quite easy to make a macro that directly goes to calc mode.

rzeta0 said:

if everything after := is a proof, then are the per-line := sub-proofs proving or justifying whatever equality/relation is immediately to their left?

Yes, these are proofs for the equality to the left. They are currently all done in tactic mode, but at least the first line could also be directly proven in term mode:

import Mathlib.Tactic

lemma foo{x y : } (h1 : y = x + 4) (h2 : x = 3) : y = 7 := by
    calc
        y = x + 4 := h1
        _ = 3 + 4 := by rw [h2]
        _ = 7 := by norm_num

That's because h1 is the proof for y = x + 4, and therefore can directly be used to proof y = x + 4 again.

Ruben Van de Velde (Jun 10 2024 at 21:08):

Try

import Mathlib.Tactic

lemma foo{x y : } (h1 : y = x + 4) (h2 : x = 3) : y = 7 :=
    calc
        y = x + 4 := h1
        _ = 3 + 4 := by rw [h2]
        _ = 7 := by norm_num

Ruben Van de Velde (Jun 10 2024 at 21:08):

No by necessary

Markus Schmaus (Jun 10 2024 at 21:09):

I stand corrected. I thought I tried that, but I must have had a typo somewhere.

rzeta0 (Jun 10 2024 at 21:26):

Ruben, Marcus - so for a beginner like me, one of the challenges is to avoid getting sucked into what is "possible" due to the idiosyncrasies of the syntax (think C++) - and maintaining focus on good idiomatic structures.

So for this example, like so many I have seen in beginner tutorials, should we say that by should always be there at the end of the line that initiates a proof?

As I say, every example I have seen has a by at the end of the first line.

Markus Schmaus (Jun 10 2024 at 23:37):

I have been a beginner myself not so long ago and in many ways I still am. I would argue that understanding how tactic mode and term mode relate to each other is essential for understanding Lean works, so you have an easier time writing your own proofs.

Have a look at the following simple proof, which I copied from here.

namespace Nat
protected theorem sub_lt_left_of_lt_add' {n k m : Nat} (H : n  k) (h : k < n + m) : k - n < m := by
  have := Nat.sub_le_sub_right (succ_le_of_lt h) n
  rwa [Nat.add_sub_cancel_left, Nat.succ_sub H] at this

have introduces an auxiliary hypothesis, which is proven by Nat.sub_le_sub_right (succ_le_of_lt h) n in term mode without by.

The tradeoff between tactic and term mode is roughly this: In term mode you specify the proof precisely, so Lean can often infer the type of the proof, i.e. the statement it proves. If you have specified the statement, you can use tactic mode to have Lean find the proof semi-automatically. Since theorems have to include the statement, proofs for theorems typically use tactic mode, the same is true for lines in a calc proof.

Bbbbbbbbba (Jun 11 2024 at 02:45):

rzeta0 said:

Ruben, Marcus - so for a beginner like me, one of the challenges is to avoid getting sucked into what is "possible" due to the idiosyncrasies of the syntax (think C++) - and maintaining focus on good idiomatic structures.

So for this example, like so many I have seen in beginner tutorials, should we say that by should always be there at the end of the line that initiates a proof?

As I say, every example I have seen has a by at the end of the first line.

As far as the compiler is concerned, you have quite some freedom where to put by:

example {x y : } (h1 : y = x + 4) (h2 : x = 3) : y = 7 := by norm_num [h1, h2]

example {x y : } (h1 : y = x + 4) (h2 : x = 3) : y = 7 :=
  by norm_num [h1, h2]

However most proofs I encounter with any sort of complexity are tactic proofs, so putting by at the end of the first line is a very reasonable style rule.

Patrick Massot (Jun 11 2024 at 14:33):

rzeta0 said:

I'm creating tutorials as I learn myself, and would like to know what the official naming of these things are.

I think that writing tutorials so early in your learning process is a very dangerous thing to do, unless you keep them on your hard drive to make sure nobody else read them.

rzeta0 (Jun 11 2024 at 15:22):

(deleted)

Kyle Miller (Jun 11 2024 at 16:30):

On the other hand, sometimes tutorials are best written by a newcomer since newcomers are seeing everything with fresh eyes. Paired with someone who knows the system and can edit it to avoid incorrect things, it could be useful to others.

This never stopped people from writing monad tutorials for Haskell though :-) https://wiki.haskell.org/Monad_tutorials_timeline (I think I too wrote a monad tutorial at some point, but it didn't make the list.)

Martin Dvořák (Jun 11 2024 at 16:39):

Kyle Miller said:

https://wiki.haskell.org/Monad_tutorials_timeline

Maybe, if I read all of them, I will finally understand what a monad is (I have already "learnt" about monads circa 6 times and yet I still don't know what a monad is).

llllvvuu (Jun 11 2024 at 19:35):

Given that millions of JavaScript programmers use async/await (do notation) and Promise.then (de-sugared monadic bind) daily without issue, it makes me wonder whether monad tutorials are cursed and should be avoided.

Patrick Massot (Jun 11 2024 at 20:01):

I’m sorry my comment was too strong. rzeta0, you should of course feel free to write whatever you want, although warning readers would probably be nicer.

Mauricio Collares (Jun 20 2024 at 10:39):

llllvvuu said:

Given that millions of JavaScript programmers use async/await (do notation) and Promise.then (de-sugared monadic bind) daily without issue, it makes me wonder whether monad tutorials are cursed and should be avoided.

Writing them is still very educational for the author! But I agree with https://byorgey.wordpress.com/2009/01/12/abstraction-intuition-and-the-monad-tutorial-fallacy/

Michael Rothgang (Jun 20 2024 at 11:00):

Bbbbbbbbba said:

rzeta0 said:

Ruben, Marcus - so for a beginner like me, one of the challenges is to avoid getting sucked into what is "possible" due to the idiosyncrasies of the syntax (think C++) - and maintaining focus on good idiomatic structures.

So for this example, like so many I have seen in beginner tutorials, should we say that by should always be there at the end of the line that initiates a proof?

As I say, every example I have seen has a by at the end of the first line.

As far as the compiler is concerned, you have quite some freedom where to put by:

example {x y : } (h1 : y = x + 4) (h2 : x = 3) : y = 7 := by norm_num [h1, h2]

example {x y : } (h1 : y = x + 4) (h2 : x = 3) : y = 7 :=
  by norm_num [h1, h2]

However most proofs I encounter with any sort of complexity are tactic proofs, so putting by at the end of the first line is a very reasonable style rule.

Also, the style guide to mathlib (in Lean 4) mandates putting by at the end of first line; this might be why many projects also follow this.

rzeta0 (Jun 20 2024 at 12:10):

is this the style guide you're referring to?

https://leanprover-community.github.io/contribute/style.html


Last updated: May 02 2025 at 03:31 UTC