Zulip Chat Archive

Stream: maths

Topic: Mechanics of Proof Exercise 5.3.6.3


Jonatas Miguel (Aug 11 2024 at 22:24):

Ahoy all!

I feel like I had to do something weird to be able to solve this exercise, and was hoping to know if others had to do the same or have come up with something else.

For reference, the exercise can be found by clicking this link.

Here's the answer I came up with:

example (P : α  Prop) : ¬ ( x, P x)   x, ¬ P x := by
  constructor
  · intro hnaxPx
    by_cases hxPx :  (x : α), ¬P x
    · apply hxPx
    · -- NOTE: this obtain pattern is kinda weird... I tried an alternative I had used elsewhere, but, it didn't work...
      obtain li, _ri :=
        calc
          (¬∃ (x : α), ¬P x)  ( (x : α), ¬¬P x) := by rel [not_exists]
          _   (x : α), P x := by rel [not_not]
      have haxPx := li hxPx
      -- NOTE: the above lines are necessary because the following two aren't working:
      -- rw [not_exists] at hxPx
      -- NOTE: issue starts here, ¬¬ replacement seems to be impossible for some reason even though I can see it in the InfoView...
      -- rw [not_not] at hxPx
      contradiction
  · intro hexnPx haxPx
    obtain x, nPx := hexnPx
    have hPx := haxPx x
    contradiction

cc: @Heather Macbeth

Jonatas Miguel (Aug 12 2024 at 11:27):

Here's a screenshot of the issue:

Screenshot-2024-08-12-at-7.27.03AM.png

Yaël Dillies (Aug 12 2024 at 11:35):

Do you know about simp_rw?

Jonatas Miguel (Aug 12 2024 at 11:44):

Nope, I haven't seen that being used yet in the book, so I haven't tried to use it.

I always tend to assume that we can solve some of these exercises with what's been used in examples so far and maybe some high school level math, so I try to stick to that as much as I can (for better or worse sometimes, lol).

I have started to take a look at Mathematics in Lean to try to get a better sense of how some of this stuff is working and what other tools I may have available, but I haven't gone too far into that book just yet either.

Jonatas Miguel (Aug 12 2024 at 17:23):

I'm starting to wonder if it has something to do with the specific version of Lean v4 that I'm using. The version specified for the codebase seems to be v4.3.0, not sure if this is relevant or not though.

Kim Morrison (Aug 13 2024 at 01:34):

You can always try in the most recent Lean using the code sandbox (click the icon in the top right of any code block on zulip).

Kim Morrison (Aug 13 2024 at 01:35):

(Oops, you can't because you've forgotten to include your imports in your code block, and in this case it is Heather's custom tactics, which aren't available in the sandbox.)

Kim Morrison (Aug 13 2024 at 01:35):

@Heather Macbeth, should we make the sandbox work with your repo? I don't see why it would be difficult?

Timo Carlin-Burns (Aug 15 2024 at 00:28):

The error is because rw doesn't work for rewriting terms which appear "under binders", e.g. terms after ∀ x, or ∃ x, . I think the expected way to prove this exercise is using only "logic" tactics like intro, constructor, use, by_cases, have, obtain, contradiction, and apply.

Heather Macbeth (Aug 15 2024 at 00:46):

Kim Morrison said:

Heather Macbeth, should we make the sandbox work with your repo? I don't see why it would be difficult?

@Kim Morrison There are a few quirks, for example there are files from the repo which could not be imported, because they contain exercises with sorries in the statements.

Heather Macbeth (Aug 15 2024 at 00:50):

@Jonatas Miguel As Timo says, the solution I have in mind would replace this part of your proof

      obtain li, _ri :=
        calc
          (¬∃ (x : α), ¬P x)  ( (x : α), ¬¬P x) := by rel [not_exists]
          _   (x : α), P x := by rel [not_not]
      have haxPx := li hxPx

with only "logic" tactics, i.e. no use of rel.

The proof of not_exists is in Example 5.16 and the proof of not_not is basically in Example 5.2.6, so rather than invoking those lemmas by name in your proof, you can adapt the ideas from the proofs of those lemmas.

Heather Macbeth (Aug 15 2024 at 00:52):

By the way, the reason your code wasn't working on standard Mathlib is because Mathlib's rel doesn't handle . This is for slightly subtle reasons -- related to the reason Yael suggested the simp_rw workaround -- so in the book I cheat by extending rel to special-case :
https://github.com/hrmacbeth/math2001/blob/main/Library/Tactic/Rel.lean

Jonatas Miguel (Aug 15 2024 at 01:01):

Aah, I see. I had wondered if that was the case or not. I think one way to make that clearer is to state that we shouldn't be using any of those lemmas instead of referring only to the ones that we'd essentially be reimplementing. I'll go back to those exercises and rewrite my solutions.

Heather Macbeth (Aug 15 2024 at 01:02):

I hadn't realised that there was a way of using them in this exercise! :)

Heather Macbeth (Aug 15 2024 at 01:09):

But now I think about it, here's how to take this idea to the extreme: :grinning:

import Mathlib

example (P : α  Prop) : ¬ ( x, P x)   x, ¬ P x := by
  calc ¬ ( x, P x)  ¬ ( x, ¬ ¬ P x) := by simp_rw [not_not]
    _  ¬ ¬ ( x, ¬ P x) := by simp_rw [not_exists]
    _   x, ¬ P x := by simp_rw [not_not]

(The simp_rw are standing in for rel on the math2001 repo, although I haven't tested it there.)

Jonatas Miguel (Aug 17 2024 at 23:16):

Ok, finally got some time and finished rewriting those two exercises in chapter 5.3 where we were supposed to avoid using the lemmas.

Exercise 5.3.6.2:

Exercise 5.3.6.3:

I think there are a few reasons why I chose to go the route I did originally:

  1. I assumed I would only need to use excluded middle once in each exercise, which led to
  2. I wasn't sure what selections I should be making for the excluded middle portions as nothing I tried was working, which made me think
  3. Well the exercises don't explicitly exclude the use of the other lemmas, and I can see a route where we can potentially solve them via mechanisms we've learned about related to equivalencies

When I have a tool that can achieve a result in a way that makes more sense to me, and requires less work to arrive at the desired result, I reach for that, lol. Eventually, when I understand something better, I'll try to use what I think is the more correct approach, even if it does require a bit more effort to achieve.

Part of my difficulties have been related to my inexperience in writing proofs, but, sometimes it's also my inexperience with lean. In some part it's also not being sure what some of the expectations are up front for some exercises and so I end up overcomplicating what I assume needs to be done.

I'm also curious if there are even more straightforward versions of these solutions. Are the ones I came up with sufficiently succinct? Or is there an even simpler solution given what has been presented so far?

Jonatas Miguel (Aug 17 2024 at 23:19):

Thanks everyone for your assistance! This was super helpful.

Timo Carlin-Burns (Aug 21 2024 at 23:17):

Jonatas Miguel said:

I'm also curious if there are even more straightforward versions of these solutions.

Here are some shorter solutions

Exercise 5.3.6.2

Exercise 5.3.6.3

Jonatas Miguel (Aug 24 2024 at 20:57):

Nice, I'll try to study these, hopefully what I learn from them will help unblock some of my intuitions in the future. Thanks for providing these!


Last updated: May 02 2025 at 03:31 UTC