Zulip Chat Archive
Stream: new members
Topic: Basic logic by splitting truth cases
Valentin Vinoles (Oct 29 2023 at 10:36):
Hello
I am trying to prove some basic logic results with Lean. Currently I am working on P ↔ ¬¬P
. I managed to prove it coming back to the definition of the negation (i.e ¬Q
is defined to be Q → False
). I want to know if it is possible to prove P ↔ ¬¬P
by splitting cases like this :
- Assume is true. Then is false. Then is true.
- Assume is false Then is true. Then is false.
I am interested for something like that because it would be closer to what an undergraduate student would do. More generally, I would like to know if this approach "splitting truth cases" is doable in Lean to prove some basic logic results.
Thanks !
Yaël Dillies (Oct 29 2023 at 10:38):
by_cases hp : p
will do the case split you're looking for.
Valentin Vinoles (Oct 29 2023 at 11:29):
Thanks ! But I am not sure how to do it. I would start like this :
example (P : Prop) : P ↔ ¬¬P := by
by_cases h_P : P
· sorry
· sorry
In the first case, the goal is ⊢ P ↔ ¬¬P
, I am not sure what I have gained here ?
Yaël Dillies (Oct 29 2023 at 11:41):
This time you have h_P : P
in context
Ruben Van de Velde (Oct 29 2023 at 11:54):
Next step could be apply iff_of_true
Valentin Vinoles (Oct 29 2023 at 14:09):
Thanks to you two, I manage to do some progress !
Another question, I am now working on . I alreay did the direct implication part and I would like to use this direct implication to and to conclude:
example (P : Prop)(Q : Prop) : (P → Q) ↔ (¬Q → ¬P) := by
constructor
· sorry -- proof of (P → Q) → (¬Q → ¬P) (already done)
· intro h
-- here I would like to apply the first case to ¬Q and ¬P
How can I reuse the first case?
Luigi Massacci (Oct 29 2023 at 14:33):
If I understood correctly you want to do something like this:
theorem contrap1 (P Q : Prop) : (P → Q) → (¬Q → ¬P) := fun pq nq p ↦ nq (pq p)
example (P : Prop)(Q : Prop) : (P → Q) ↔ (¬Q → ¬P) := by
constructor
· apply contrap1
-- alternatively:
-- exact contrap1 P Q
-- or even let it instantiate the quantifiers on its own:
-- exact contrap1 _ _
· intro h
have h₁ := contrap1 (¬Q) (¬P) h -- this adds the hypothesis h₁ : ¬¬P → ¬¬Q
-- like above, you could do contrap1 _ _ h
Notification Bot (Oct 29 2023 at 18:29):
Valentin Vinoles has marked this topic as resolved.
Valentin Vinoles (Oct 29 2023 at 18:29):
thanks !
Notification Bot (Oct 29 2023 at 20:29):
Valentin Vinoles has marked this topic as unresolved.
Valentin Vinoles (Oct 29 2023 at 20:47):
Sorry for my very naive questions but I have trouble to find answers online.
During a proof involving two propositions P
and Q
, I have a proof h
of P ∧ Q
and a proof h'
of ¬ P
. I would like to apply h'
to P
but apply h' at h.left
do not work, I don't understand why.
Maybe I need to declare explicitly a proof h_P
of P
and write apply h' at h_P
but I do not know how...
Lessness (Oct 29 2023 at 20:55):
variable (P Q: Prop)
variable (h: P ∧ Q)
variable (h': ¬ P)
#check (h' h.left)
Inside the proof with tactics you can write set F := h' h.left
.
Lessness (Oct 29 2023 at 20:57):
I believe there's no way to apply
at something that's not a goal. (I may be wrong.)
Valentin Vinoles (Oct 29 2023 at 21:17):
Thanks a lot, it works with set
!
Ruben Van de Velde (Oct 29 2023 at 22:08):
There's some work on using apply
with hypotheses, though I don't know if it landed yet. It would never work in this case, though
Valentin Vinoles (Oct 30 2023 at 09:08):
Another question :sweat_smile:
I am playing around with False.elim
. If h : False
and P : Prop
, how can I deduce a proof of P
. I can do the following:
example (P : Prop) : False → P := by
intro h -- h : False
apply False.elim at h
but the issue is that h
is now a proof of ?C
(I am not sure what it is...). How can I change it to make a proof of P
?
Damiano Testa (Oct 30 2023 at 09:13):
You can do
change P at h
While this works, I find this way of arguing a little unusual, though!
Damiano Testa (Oct 30 2023 at 09:14):
The ?C
that you see is a metavariable and with change P at h
you tell Lean that you want it to unify with P
.
Valentin Vinoles (Oct 30 2023 at 09:29):
Thank you it works !
I know it is unusual, it is just playing around to understand how things work. I do not plan to use it in "real" proofs.
Is there a way to do it in one line, something like apply False.elim P at h
(this does not work).
Damiano Testa (Oct 30 2023 at 09:35):
After intro h
, you can do exact?
. Alternatively, also cases h
works. Or even, the whole proof could be rintro ⟨⟩
.
Valentin Vinoles (Oct 30 2023 at 09:38):
I mean a one line to merge
apply False.elim at h
change P at h
Notification Bot (Oct 30 2023 at 09:38):
A message was moved here from #new members > CompactIccSpace for unitInterval by Valentin Vinoles.
Ruben Van de Velde (Oct 30 2023 at 09:45):
Either of these would make more sense than using apply
here:
example (P : Prop) : False → P := by
intro h -- h : False
have : P := False.elim h
exact False.elim h
You don't need to use the apply
tactic in every situation where you're use the verb "apply" in mathematical English
Damiano Testa (Oct 30 2023 at 09:47):
In fact, I would say that almost always the tactic apply
is translated to it suffices
.
You can though do this
apply False.elim (C := P) at h
as well.
Valentin Vinoles (Oct 30 2023 at 10:02):
Thank to you two. I already write a lof of stuffs with apply
everywhere... I guess I need to rework all of these. The learning curve is quite stiff !
Valentin Vinoles (Oct 30 2023 at 10:06):
I guess this is bad ?
theorem not_not_direct (P : Prop) : P → ¬¬P := by
intro h -- h : P
apply Not.intro -- goal becomes ¬P → False
intro h_notP -- h : ¬P (i.e. h : P → False)
apply h_notP at h -- h : False
exact h
Luigi Massacci (Oct 30 2023 at 10:12):
I’m not an authority, but I would have written
theorem not_not_direct (P : Prop) : P → ¬¬P := by
intro p np
exact np p
or if you really want to use apply:
theorem not_not_direct (P : Prop) : P → ¬¬P := by
intro p np
apply np
exact p
Kevin Buzzard (Oct 30 2023 at 11:54):
Ruben Van de Velde said:
There's some work on using
apply
with hypotheses, though I don't know if it landed yet. It would never work in this case, though
Right. I think that apply at
has now landed, but you cannot apply a hypothesis to h.left
and expect only h.left
to change. You need to do cases
on h
first, extract the left component as h_1
and then apply
h'
to h_1
.
Kevin Buzzard (Oct 30 2023 at 11:56):
Valentin Vinoles said:
I mean a one line to merge
apply False.elim at h change P at h
import Mathlib.Tactic
example (P : Prop) : False → P := by
rintro ⟨⟩
Kevin Buzzard (Oct 30 2023 at 11:57):
Valentin Vinoles said:
I guess this is bad ?
theorem not_not_direct (P : Prop) : P → ¬¬P := by intro h -- h : P apply Not.intro -- goal becomes ¬P → False intro h_notP -- h : ¬P (i.e. h : P → False) apply h_notP at h -- h : False exact h
How about
theorem not_not_direct (P : Prop) : P → ¬¬P := fun h h1 ↦ h1 h
Last updated: Dec 20 2023 at 11:08 UTC