Zulip Chat Archive

Stream: new members

Topic: How to fold statements into the calc block?


Sean Leather (Feb 26 2018 at 19:11):

Ah, so #new members is a “stream,” and it has multiple “topics.” Now the terminology is coming together in my head.

Sean Leather (Feb 26 2018 at 19:13):

And I'm too tired to fully comprehend anything else about Zulip right now. I'm sure I'll find lots of messages in the morning. Good night!

Chris Hughes (Feb 26 2018 at 20:15):

I like the generated profile pictures here.

Patrick Massot (Feb 26 2018 at 20:16):

You can still use the opportunity to brighten your previous profile picture before uploading

Mario Carneiro (May 14 2019 at 04:10):

usually this is achieved by constructing the set in a way so that it's obvious that it's a finset. How is isCanonicalPartition defined?

Johan Commelin (May 14 2019 at 04:10):

@Huyen Chau Nguyen to format code on this chat (you can still edit your message) use

```lean
put your code here
```

That way it is formatted as a code block with syntax highlighting.

hpxmd (Jun 04 2019 at 13:24):

Hello, newb in functional languages here! Im stuck on excercise at "2.4. Introducing Definitions"

/- Above, we discussed the process of “currying” a function, that is, taking a function f (a, b) that takes an ordered pair as an argument, and recasting it as a function f' a b that takes two arguments successively. As another exercise, we encourage you to complete the following definitions, which “curry” and “uncurry” a function.
def curry (α β γ : Type) (f : α × β → γ) : α → β → γ := sorry
def uncurry (α β γ : Type) (f : α → β → γ) : α × β → γ := sorry
-/
def curry (α β γ : Type) (f : α × β  γ) : α  β  γ :=

the closest solution i came up with is

def curry (α β γ : Type) (f : α × β  γ) : α  β  γ := λ (a: α) (b: β) (c: γ), c

returns error:

/home/runner/.code.tio:2:56: error: type mismatch, term
  λ (a : α) (b : β) (c : γ), c
has type
  α  β  γ  γ
but is expected to have type
  α  β  γ

i don't understand how i should return this λ itself. As is can't just leave it like "λ (a: α) (b: β) (c: γ)"

Mario Carneiro (Jun 04 2019 at 13:25):

you need to use f at some point

hpxmd (Jun 04 2019 at 13:30):

I tried for like whole day and a half. Im no mathematitian also. Should i just continue reading then?

Marc Huisinga (Jun 04 2019 at 13:30):

the type signature of curry states that given a value of type alpha and a value of type beta, you get a value of type gamma.
the function you defined with your lambda however takes a value of type alpha, a value of type beta and a value of type gamma.
you need to drop the gamma parameter and come up with a way to produce a value of type gamma from values of types alpha and beta, which will involve using f.

Patrick Massot (Jun 04 2019 at 13:30):

you need to use f at some point

See, the question was under-specified. No wonder the continuum hypothesis is undecidable.

Patrick Massot (Jun 04 2019 at 13:32):

Seriously, @hpxmd you need to reread the last paragraph of https://leanprover.github.io/theorem_proving_in_lean/dependent_type_theory.html#simple-type-theory

Johan Commelin (Jun 04 2019 at 13:33):

I tried for like whole day and a half. Im no mathematitian also. Should i just continue reading then?

How many mathematicians do you think know what curry means? I bet that 99% think it is something you put on a sausage.

Patrick Massot (Jun 04 2019 at 13:33):

That's where the specification is explicitly given

Patrick Massot (Jun 04 2019 at 13:33):

Johan, I think you spend way too much time in Germany

hpxmd (Jun 04 2019 at 13:34):

Thanks Patrick, ill try that

hpxmd (Jun 04 2019 at 16:02):

So i had to read wiki to write it:

def curry (α β γ : Type) (f : α × β  γ) : α  β  γ := λ a, λ b, f(a, b)

is this right?

Kevin Buzzard (Jun 04 2019 at 16:02):

Yup!

hpxmd (Jun 04 2019 at 16:04):

then i guess i dont understand this lambda calculus thing

hpxmd (Jun 04 2019 at 16:04):

thank you

Patrick Massot (Jun 04 2019 at 16:06):

This has not much to do with lambda calculus

Kevin Buzzard (Jun 04 2019 at 16:06):

This is exactly completely basic lambda calculus, isn't it?

Patrick Massot (Jun 04 2019 at 16:07):

No, it's about functions of two variable vs function of one variable with values in functions of one variable.

Patrick Massot (Jun 04 2019 at 16:07):

You could write the answer as a(bf(a,b))a \mapsto (b \mapsto f (a,b)) and you woudln't see any λ\lambda

Patrick Massot (Jun 04 2019 at 16:08):

The point of lambda-calculus is not using a stupid notation instead of a legible one (reading: the one we are used to). It's about the reduction rules

Marc Huisinga (Jun 04 2019 at 17:20):

this topic made me curious: when getting started with lean (or a similar language), did the function application syntax without parens feel unnatural or even hard to read to any of you, compared to the syntax with parens?
i'm asking because i've heard this complaint quite a lot over the years from people coming from traditional programming languages, and i've been wondering whether this initial feeling is common for everyone, or whether it's just because i've mostly talked to people that had gotten used to the syntax with parens over the years.

Kevin Buzzard (Jun 04 2019 at 17:58):

I was a mathematician for 25 years before I learnt any functional programming and yes, the lack of brackets looked super-weird to me. I still occasionally put them in by accident.

Koundinya Vajjha (Jun 04 2019 at 18:00):

Yes but use it long enough and you'll start hating brackets. :-)

Patrick Massot (Jun 04 2019 at 18:02):

I've caught myself not writing brackets on paper

Sebastien Gouezel (Jun 04 2019 at 18:53):

In dynamics it is very common to omit the brackets.

Scott Morrison (Jun 04 2019 at 19:20):

Meh. We should be writing function application as x f anyway. Losing the brackets is partial progress. :-)

Andrew Ashworth (Jun 04 2019 at 22:42):

Reverse Polish notation was the best thing in calculators. Maybe I ought to implement it in lean 4, hah.

Andrew Ashworth (Jun 04 2019 at 22:46):

Then you can stare at expressions like 15 7 1 1 + − ÷ 3 × 2 1 1 + + − and truly live the bracket free life

Robert Solovay (Jun 23 2019 at 08:56):

How do I enter the Greek letter lambda (symbol for functional abstraction) in the Lean javascript window?

Kevin Buzzard (Jun 23 2019 at 08:56):

\lam

Kevin Buzzard (Jun 23 2019 at 08:57):

\la apparently works too

Robert Solovay (Jun 23 2019 at 08:57):

Thanks.

Kevin Buzzard (Jun 23 2019 at 08:57):

Nice to see you here, by the way!

Jesse Michael Han (Jun 23 2019 at 11:49):

welcome!

jachym simon (Jun 25 2019 at 19:35):

Hi!
I am trying to proof completeness theorem for Hilbert style classical propositional system. While working my way through I ran into this lemma below. The lemma is quite important, but i am not able to prove it. I can do that for n and k particular numbers (1,2,3, ..), but not for n and k general. Is there some way to prove it?

def eval := ℕ → bool
def g(n:ℕ)(f:eval): ℕ → bool := (λ m:ℕ, nat.lt_by_cases (λ h:m<n, f m) (λ h, tt) (λ h, tt))

lemma Lemma1(n:ℕ)(f:eval): ∀ k:ℕ, k < n → g n f k = f k :=

Thanks :)

Kenny Lau (Jun 25 2019 at 19:40):

def eval :=   bool
def g(n:)(f:eval):   bool := (λ m:, nat.lt_by_cases (λ h:m<n, f m) (λ h, tt) (λ h, tt))

lemma Lemma1(n:)(f:eval):  k:, k < n  g n f k = f k :=
λ k hk, dif_pos hk

jachym simon (Jun 25 2019 at 20:24):

def eval :=   bool
def g(n:)(f:eval):   bool := (λ m:, nat.lt_by_cases (λ h:m<n, f m) (λ h, tt) (λ h, tt))

lemma Lemma1(n:)(f:eval):  k:, k < n  g n f k = f k :=
λ k hk, dif_pos hk

Thank you :)

jachym simon (Jun 26 2019 at 07:19):

HI again,
i have got one more connected question. How do i prove the two below? Thought it would be the same, but it does not seem to work.

def eval :=   bool
def g(n:)(f:eval):   bool := (λ m:, nat.lt_by_cases (λ h:m<n, f m) (λ h, tt) (λ h, tt))

lemma Lemma2(n:)(f:eval):  k:, k = n  g n f k = tt  :=
lemma Lemma3(n:)(f:eval):  k:, k > n  g n f k = tt  :=

Mario Carneiro (Jun 26 2019 at 07:23):

It might be simpler to not use lt_by_cases

Mario Carneiro (Jun 26 2019 at 07:23):

and just use if

Mario Carneiro (Jun 26 2019 at 07:26):

def eval :=   bool
def g (n : ) (f : eval) (m : ) : bool := if m < n then f m else tt

lemma Lemma2 (n : ) (f : eval) (k : ) (h : k = n) : g n f k = tt :=
have ¬ k < n, from λ h', ne_of_lt h' h,
by simp [g, this]

lemma Lemma3 (n : ) (f : eval) (k : ) (h : k > n) : g n f k = tt :=
have ¬ k < n, from not_lt_of_gt h,
by simp [g, this]

Daniel Donnelly (Aug 24 2019 at 09:29):

Yep, that was it. It was just updating something in the background

Juho Kupiainen (Sep 20 2019 at 17:37):

How can I browse Lean's mathlib with VS code. Lean works in VS code, but when I open a file in mathlib (I cloned the code) it cannot resolve the imports. I did "leanpkg configure" and "leanpkg build" in the root directory of mathlib

Bryan Gin-ge Chen (Sep 20 2019 at 18:06):

Are you opening the entire mathlib directory in VS Code? Often these issues occur when you just try to open a random file from mathlib without having opened the directory as a workspace.

Juho Kupiainen (Sep 20 2019 at 18:13):

Opening the directory helped after I had created a new project according to the instruction on mathlib github page.

Marko Grdinić (Oct 14 2019 at 08:25):

import data.rat

def mean (l : list rat) : rat := list.sum l / l.length
def E (f : rat -> rat) (l : list rat) := mean $ list.map f l

theorem E.const_left (f : rat -> rat) (c : rat) (l : list rat)
    : E (fun x, c * f x) l = c * E f l  := sorry

theorem E.const_right (c : rat) (l : list rat) : E (fun x, x * c) l = E id l * c :=
    have mult_dist : (fun x, x * c) = (fun x, c * x), from funext $ fun x, mul_comm x c,
    have const_left : E (fun x, c * x) l = c * E id l, from E.const_left id c l,
    calc
        E (fun x, x * c) l = E (fun x, c * x) l : by rw mult_dist
        ... = c * E id l : by rw const_left
        ... = E id l * c : by rw mul_comm

I am trying to rewrite the above so the extraneous names and type annotations are eliminated. Here is what I want to write.

import data.rat

def mean (l : list rat) : rat := list.sum l / l.length
def E (f : rat -> rat) (l : list rat) := mean $ list.map f l

theorem E.const_left (f : rat -> rat) (c : rat) (l : list rat)
    : E (fun x, c * f x) l = c * E f l  := sorry

theorem E.const_right (c : rat) (l : list rat) : E (fun x, x * c) l = E id l * c :=
    calc
        E (fun x, x * c) l = E (fun x, c * x) l : by {rw (funext $ fun x, mul_comm x c)}
        ... = c * E id l : by {rw (E.const_left id c l)}
        ... = E id l * c : by rw mul_comm

It says that the rewrite tactic fails for some reason. At first I thought that it might have been because in the original version some of the arguments were implicit, but that turned out to not be it. I am not sure what to think about this. I am having trouble with similar rewrites in other places. Lean seems to be bad at inferring the right types in the calc block proofs from expressions on the left side.

Johan Commelin (Oct 14 2019 at 08:31):

In the first one, maybe you can try by { funext, ext, rw mul_comm }?

Mario Carneiro (Oct 14 2019 at 08:34):

theorem E.const_right (c : rat) (l : list rat) : E (fun x, x * c) l = E id l * c :=
    calc
        E (fun x, x * c) l = E (fun x, c * x) l : by simp only [mul_comm]
        ... = c * E id l : by rw  E.const_left; refl
        ... = E id l * c : by rw mul_comm

Mario Carneiro (Oct 14 2019 at 08:35):

If you use ```lean ... ``` then you get syntax highlighting btw

Mario Carneiro (Oct 14 2019 at 08:36):

also:

theorem E.const_right (c : rat) (l : list rat) : E (fun x, x * c) l = E id l * c :=
by rw [mul_comm,  E.const_left]; simp only [mul_comm, id]

Marko Grdinić (Oct 14 2019 at 08:44):

I am surprised by .. = c * E id l : by rw ← E.const_left; refl. Why rewrite to the left? That does not make much sense to me.

Mario Carneiro (Oct 14 2019 at 08:46):

rw will rewrite any subterm of the entire goal using the given equation from left to right (or right to left if you give the <-). That means that it can be used to rewrite the right side of the equation as well as the left side, at which point both sides become equal and refl closes the goal

Marko Grdinić (Oct 14 2019 at 08:49):

Ah, I see. I just realized that ... = c * E id l : by rw E.const_left; refl works too. The type error does not indicate what the problem is.

Mario Carneiro (Oct 14 2019 at 08:52):

Oh, I guess it was able to match f := \lam x, x even if you write from left to right, I wouldn't have expected that

Mario Carneiro (Oct 14 2019 at 08:52):

The matching problem from right to left is easier, because it doesn't have to do any higher order matching

Mario Carneiro (Oct 14 2019 at 08:53):

That is, it's easy to match c * E id l against the pattern ?c * E ?f ?l

Marko Grdinić (Oct 14 2019 at 09:01):

Yeah, I think I understand it now.

rewrite tactic failed, did not find instance of the pattern in the target expression
  E (λ (x : ℚ), c * id x) l
state:
c : ℚ,
l : list ℚ
⊢ E (λ (x : ℚ), c * x) l = c * E id l

I should have looked at the type error more carefully. c * id x and c * x are not quite the same thing here.

Is there a way to make ... = c * E id l : by {rw (E.const_left id c l)} work by getting it to simplify the expression passed to rw namely the E.const_left id c l ?

Mario Carneiro (Oct 14 2019 at 09:02):

sure, but it would take more than one line to do so

Mario Carneiro (Oct 14 2019 at 09:03):

        ... = c * E id l : by {
          have := E.const_left id c l,
          dsimp only [id] at this,
          rw this }

Mario Carneiro (Oct 14 2019 at 09:04):

it's easier in this case to rewrite backwards so you get E (λ (x : ℚ), c * x) l = E (λ (x : ℚ), c * id x) l, which can then be closed by refl

Mario Carneiro (Oct 14 2019 at 09:05):

because id x is defeq to x

Marko Grdinić (Oct 14 2019 at 09:07):

Thank you very much. This was definitely instructive for me.

Reid Barton (Oct 14 2019 at 13:19):

You can also use erw (E.const_left id c l), which unfolds definitions while matching. However, we tend not to use erw much because it can be slow.

Reid Barton (Oct 14 2019 at 13:19):

In this case you can also just use the term E.const_left id c l directly, without bothering with by rw


Last updated: Dec 20 2023 at 11:08 UTC