Zulip Chat Archive

Stream: new members

Topic: An example involving Ch.2 and NNG


Debendro Mookerjee (Mar 16 2020 at 23:13):

In chapter 2 in Theorem Proving in Lean, we learn about definitions, so to try it out I made this definition:
def dvd (m n: ℕ): Prop := ∃ k, n = m * k
In the Natural Number Game, we learn about tactics like rw,etc. So I was wondering how to rewrite a goal with a definition. I have this statement in my tatic state:
hbleft : n = a * b. Clearly we see that a divides n. But when I say rw dvd at hbleft Lean rejects this as a valid piece of code. So I can I apply dvd to the statement hbleft to show a divides n?

Kenny Lau (Mar 16 2020 at 23:15):

have hadn : dvd a n := \<_, hbleft\>

Debendro Mookerjee (Mar 16 2020 at 23:22):

Thanks, it works now

Debendro Mookerjee (Mar 16 2020 at 23:31):

Also in the natural number game we could use the rw tactic to invoke previous theorems; does that same thing work for conditional sentences that I assume to be true? For instance I have a conditional sentence hp : dvd p n → q and in my tactic state I have hadn : dvd a n Can I use my hpto rewrite hadn. I tried rw hp at hadn and apply hp at hadn but Lean stated that code was not valid. How to I use hp to simplify hadn?

Reid Barton (Mar 16 2020 at 23:44):

You can only rw with an equality or an iff. An implication is just a function, so you can apply it, but there is no such thing as apply at. Here, you could write replace hadn := hp hadn

Reid Barton (Mar 16 2020 at 23:44):

Or just use hp hadn directly wherever you need it

Reid Barton (Mar 16 2020 at 23:45):

Or have hq : q, { apply hp, exact hadn }, or many other variations.

Debendro Mookerjee (Mar 16 2020 at 23:57):

@Reid Barton I used have hq : q, { apply hp, exact hadn }, and replace hadn := hp hadn but got this error:

type mismatch at application
  hp hadn
term
  hadn
has type
  dvd a n
but is expected to have type
  dvd p n

Reid Barton (Mar 16 2020 at 23:58):

Ah, well, yeah

Reid Barton (Mar 16 2020 at 23:58):

I missed that it was a trick question. a is not p.

Debendro Mookerjee (Mar 17 2020 at 00:02):

But when I replace a with p I get the error:

type mismatch at application
  hp hadn
term
  hadn
has type
  dvd p n
but is expected to have type
  dvd p n
types contain aliased name(s): p
remark: the tactic `dedup` can be used to rename aliases

Debendro Mookerjee (Mar 17 2020 at 00:03):

So what is dedup and how is it used?

Kenny Lau (Mar 17 2020 at 00:03):

It means you have two variables with the same name p

Reid Barton (Mar 17 2020 at 00:04):

You've done something wrong earlier.

Debendro Mookerjee (Mar 17 2020 at 00:04):

But if I use difference variable names a and p I still get the Type Mismatch

Bryan Gin-ge Chen (Mar 17 2020 at 00:05):

Please post your code. It's very hard to help without seeing what you're working with.

Debendro Mookerjee (Mar 17 2020 at 00:07):

def composite (d : ℕ): Prop:= ¬ prime d

theorem composite_fact (c: ℕ) : composite c ↔ ∃ (a b: ℕ), c = a*b ∧ a ≤ b := sorry

Main part:

theorem practice (n p : ℕ) (hn : n > 1) (hp : dvd p n → p*p >  n) : ¬ composite  n :=
begin
  intro h,
  rw composite_fact at h,
  cases h with p ha,
  cases ha with b hb,

  have hbleft: n = p*b, from and.left hb,
  have hbright: p ≤ b, from and.right hb,

  have hadn : dvd p n,

  rw dvd,
  use b,
  rw hbleft,

  replace hadn := hp hadn,

end

Reid Barton (Mar 17 2020 at 00:10):

This proof, and possibly statement, doesn't make sense

Kevin Buzzard (Mar 17 2020 at 00:10):

please can you post exactly one code block containing all imports and opens, so people can just cut and paste to see your problem.

Reid Barton (Mar 17 2020 at 00:11):

What are you trying to prove in English?

Debendro Mookerjee (Mar 17 2020 at 00:15):

(deleted)

Kevin Buzzard (Mar 17 2020 at 00:15):

but 1 is a factor of n

Kevin Buzzard (Mar 17 2020 at 00:16):

just because it's called p doesn't make it prime :-)

Reid Barton (Mar 17 2020 at 00:16):

It's not what your practice statement says anyways.

Kevin Buzzard (Mar 17 2020 at 00:16):

Unrelated: if you put ```lean at the top of where you quote your code, then it comes out in neat colours

Debendro Mookerjee (Mar 17 2020 at 00:37):

Wait really?

Debendro Mookerjee (Mar 17 2020 at 00:37):

theorem practice (n p : ) (hn : n > 1) (hp : dvd p n  p*p >  n) : ¬ composite  n :=
begin
  intro h,
  rw composite_fact at h,
  cases h with p ha,
  cases ha with b hb,

  have hbleft: n = p*b, from and.left hb,
  have hbright: p  b, from and.right hb,

  have hadn : dvd p n,

  rw dvd,
  use b,
  rw hbleft,

  replace hadn := hp hadn,

end

Debendro Mookerjee (Mar 17 2020 at 00:38):

Oh wow...

Kevin Buzzard (Mar 17 2020 at 00:52):

Your hypothesis hp says "if the fixed number pp you chose at the beginning divides nn, then also assume that p2>np^2>n. So for example practice 7 5 says "if 7>1, and if the statement 'if 5 divides 7 then 5^2>7' is true (which it is, because 5 doesn't divide 7) then 7 is not composite". In particular practice 7 5 is false so you can't prove practice in general. You need to learn to work basic logic before you can get to Hungerford.

jack (Mar 17 2020 at 08:50):

Hi there, I m stuck again :rolling_on_the_floor_laughing:

jack (Mar 17 2020 at 08:51):

theorem Equivalence1 (A B : Prop) :
(A  B)  (¬ A  B) :=
-- classical should be used
assume h,
--classical.by_contradiction $
--assume h1,
_

theorem Equivalence2 (A B : Prop) :
(¬ A  B)  (A  B) :=
assume h,
assume a,
_

jack (Mar 17 2020 at 08:52):

Maybe equivalence2 is simpler.

Johan Commelin (Mar 17 2020 at 08:53):

If you use

```lean
code goes here
```

for your codeblocks, you even get fancy colors (-;

jack (Mar 17 2020 at 08:54):

This is not the homework, but I would like to challenge myself.

jack (Mar 17 2020 at 08:55):

Still SO difficult ...

Johan Commelin (Mar 17 2020 at 08:56):

Hint: or.cases_on

jack (Mar 17 2020 at 08:58):

#check @or.cases_on seems similar to or.elim... actually I see no difference between them.

Marc Huisinga (Mar 17 2020 at 08:59):

it is!

for the first one, i'd try using (classical.em A).elim instead, maybe you had the law of excluded middle in class to motivate things like by_contradiction

jack (Mar 17 2020 at 09:01):

100% correct!

Marc Huisinga (Mar 17 2020 at 09:06):

(note that (classical.em A).elim is just or.elim (classical.em A), i should perhaps be careful with using notation that might not have been introduced yet)

jack (Mar 17 2020 at 09:12):

theorem Equivalence2 (A B : Prop) :
(¬ A  B)  (A  B) :=
assume h,
assume a,
or.cases_on h
(assume na ,
or.cases_on h (
assume na,
_
) $
assume b: B, b
) $ assume b : B, b

I m getting into a circle.

Johan Commelin (Mar 17 2020 at 09:13):

Hint: false.elim

Johan Commelin (Mar 17 2020 at 09:14):

You should remove the second block of or.cases_on h _ _

jack (Mar 17 2020 at 09:15):

#check @false.elim gives me Π {C : Sort u_1}, false → C. Is it pi-calculus?

Marc Huisinga (Mar 17 2020 at 09:15):

think about the proof you'd write on paper. you've got ¬ A ∨ B and A. in the first case, where you've got ¬ A, you've got a contradiction on your hands that allows you to get false, and thus prove anything (with false.elim).

Marc Huisinga (Mar 17 2020 at 09:16):

this is known as the principle of explosion, "from falsehood, anything follows"

Johan Commelin (Mar 17 2020 at 09:17):

jack said:

#check @false.elim gives me Π {C : Sort u_1}, false → C. Is it pi-calculus?

I don't know anything about calculus, but this is telling you that if you can find a contradiction (i.e., proof of false), then you can prove everything.

jack (Mar 17 2020 at 09:18):

OK got you. After adding a false.elim I 've got a A and \not A, then I can get a false \not A A. Cheers!

jack (Mar 17 2020 at 09:21):

My proves seems like this:

theorem Equivalence2 (A B : Prop) :
(¬ A  B)  (A  B) :=
assume h,
assume a,
or.cases_on h
(
assume na,
false.elim $
na a
) $ assume b : B, b

I'm wondering if I can use $ to remove the parentheses.

Kevin Buzzard (Mar 17 2020 at 09:22):

jack said:

#check @false.elim gives me Π {C : Sort u_1}, false → C. Is it pi-calculus?

Pi is the name of the types, lambda is the name of the terms. λ a, b has type Π A, B

jack (Mar 17 2020 at 09:22):

or.elim is a 3-parameter operator, where comes the problem.

Marc Huisinga (Mar 17 2020 at 09:22):

i don't think so, $ won't allow you to eliminate all parentheses, only the ones at the end. the proof looks good!

jack (Mar 17 2020 at 09:22):

Thank you @Kevin Buzzard

jack (Mar 17 2020 at 09:23):

Thanks to all of you :grinning_face_with_smiling_eyes: I have only 50% left.

Johan Commelin (Mar 17 2020 at 09:26):

@jack If you wanna golf: assume b : B, b is the same as id

Johan Commelin (Mar 17 2020 at 09:27):

theorem Equivalence2 (A B : Prop) :
(¬ A  B)  (A  B) :=
assume h a, h.cases_on (false.elim  absurd a) id

jack (Mar 17 2020 at 09:29):

Do you invent this language @Johan Commelin ? Or do you use it every day?

Johan Commelin (Mar 17 2020 at 09:30):

What do you mean?

Johan Commelin (Mar 17 2020 at 09:30):

I use Lean pretty much every day. But I usually don't write my proofs like this.

Johan Commelin (Mar 17 2020 at 09:30):

I prefer tactic mode.

jack (Mar 17 2020 at 09:31):

Maybe I'll learn to use it at the end of this semester.

jack (Mar 17 2020 at 09:34):

Could you please explain a little more? Never seen this in the class.

Johan Commelin (Mar 17 2020 at 09:35):

It is called "function composition"

Johan Commelin (Mar 17 2020 at 09:35):

f ∘ g = \lambda x, f (g x)

jack (Mar 17 2020 at 09:37):

Does it mean false.elim ∘ absurd a is the same as false.elim (absurd a)?

Johan Commelin (Mar 17 2020 at 09:37):

Nope

Johan Commelin (Mar 17 2020 at 09:38):

It's the same as assume blabla, false.elim (absurd a blabla)

jack (Mar 17 2020 at 09:41):

Amazing!

jack (Mar 17 2020 at 10:00):

h : A  B
 ¬A  B

May I have some hint please?

Kenny Lau (Mar 17 2020 at 10:01):

case on whether A is true or false

jack (Mar 17 2020 at 10:05):

Do you mean or.cases_on? Which only works with a ... \or ... but there isn't.

Kenny Lau (Mar 17 2020 at 10:13):

use classical.em

jack (Mar 17 2020 at 10:34):

theorem Equivalence1 (A B : Prop) :
(A  B)  (¬ A  B) :=
-- classical should be used
assume h,
have h1 : A  ¬ A, from classical.em A,
h1.cases_on
(assume a : A,
 or.intro_right _ $ h a
) $
 assume na : ¬ A,
 or.intro_left _ na

jack (Mar 17 2020 at 10:35):

Finally I made it :tada: There must be some fancy syntax which could simplify the prove.

jack (Mar 17 2020 at 10:35):

Thanks a lot @Kenny Lau

Kevin Buzzard (Mar 17 2020 at 11:48):

theorem Equivalence1 (A B : Prop) : (A  B)  (¬ A  B) :=
λ h, (classical.em A).elim (λ a, or.intro_right _ $ h a) $ or.intro_left _

Kevin Buzzard (Mar 17 2020 at 11:49):

Same proof but bundled up into a more compact form.

Kevin Buzzard (Mar 17 2020 at 11:51):

import tactic

run_cmd tactic.skip -- working around open_locale bug

open_locale classical

theorem Equivalence1 (A B : Prop) : (A  B)  (¬ A  B) :=
begin
  intro hAB,
  by_cases A,
  { right,
    apply hAB,
    assumption
  },
  { left,
    assumption
  }
end

Same proof but in tactic mode.

Anas Himmi (Mar 17 2020 at 11:54):

what does the $ sign mean?

jack (Mar 17 2020 at 12:31):

It means saving some paratheses, e.g. foo $ a b c <-> foo (a b c)

Kevin Buzzard (Mar 17 2020 at 12:44):

theorem Equivalence1 (A B : Prop) : (A  B)  (¬ A  B) :=
λ h, (classical.em A).elim (λ a, or.intro_right _ (h a)) (or.intro_left _)

$-free version

Anas Himmi (Mar 17 2020 at 13:04):

thank you!

Kevin Buzzard (Mar 17 2020 at 13:04):

@anas himmi you can work out what most things mean in Lean if you know how. For example, if you realise that $ is notation then #print notation $ is the next step. It tells you _ $:1 _:0 := #1 #0 which is a rather encrypted way of saying that f $ g means f g except that the binding power of $ is 1, which is very low.

Kevin Buzzard (Mar 17 2020 at 13:05):

This means that the composition happens last, saving you from having to write the brackets (which have super-high binding power). I wrote a blog post about binding power in Lean here.

Kevin Buzzard (Mar 17 2020 at 13:05):

You can compare with #print notation + and so on.

Anas Himmi (Mar 17 2020 at 13:06):

i tested it out before asking but didn't understand the notation. now i see it better


Last updated: Dec 20 2023 at 11:08 UTC