Zulip Chat Archive
Stream: lean4
Topic: calculational proof of equivalence of two propositions
Bulhwi Cha (Feb 09 2023 at 07:04):
import Mathlib.Logic.Basic
example (p q r : Prop)
: (p ∧ q ∧ ¬r) ∨ (p ∧ ¬q ∧ r) ∨ (¬p ∧ q ∧ r) ∨ (p ∧ q ∧ r)
↔ (p ∧ q) ∨ (p ∧ r) ∨ (q ∧ r) := calc
(p ∧ q ∧ ¬r) ∨ (p ∧ ¬q ∧ r) ∨ (¬p ∧ q ∧ r) ∨ (p ∧ q ∧ r)
↔ (p ∧ q ∧ ¬r) ∨ (p ∧ ¬q ∧ r) ∨ (¬p ∧ q ∧ r) ∨
(p ∧ q ∧ r) ∨ (p ∧ q ∧ r) ∨ ( p ∧ q ∧ r) := by repeat rw [or_self]
_ ↔ ((p ∧ q ∧ ¬r) ∨ (p ∧ q ∧ r)) ∨
((p ∧ ¬q ∧ r) ∨ (p ∧ q ∧ r)) ∨
((¬p ∧ q ∧ r) ∨ (p ∧ q ∧ r)) :=
by rw [← @or_assoc (¬p ∧ q ∧ r), @or_comm ((¬p ∧ q ∧ r) ∨ (p ∧ q ∧ r)),
← @or_assoc (p ∧ ¬q ∧ r), ← @or_assoc (p ∧ ¬q ∧ r),
@or_comm ((p ∧ ¬q ∧ r) ∨ (p ∧ q ∧ r)), ← @or_assoc (p ∧ q ∧ ¬r),
← @or_assoc (p ∧ q ∧ ¬r), or_assoc]
_ ↔ (( p ∧ q) ∧ (¬r ∨ r)) ∨
(( p ∧ r) ∧ (¬q ∨ q)) ∨
((¬p ∨ p) ∧ q ∧ r) := by conv =>
lhs
congr
. simp [← and_assoc, ← and_or_left]
. congr
. simp [@and_comm _ r, ← and_assoc, ← and_or_left]; rw [@and_comm r]
. rw [← or_and_right]
_ ↔ (p ∧ q) ∨ (p ∧ r) ∨ (q ∧ r) := by conv =>
lhs
congr
. rw [eq_true (em' r), and_true]
. congr
. rw [eq_true (em' q), and_true]
. rw [eq_true (em' p), true_and]
Bulhwi Cha (Feb 09 2023 at 07:04):
Is there any way to write a calculational proof shorter than mine?
Mario Carneiro (Feb 09 2023 at 07:40):
does by tauto
count?
Mario Carneiro (Feb 09 2023 at 07:41):
can confirm this works
import Mathlib.Tactic.Tauto
example (p q r : Prop)
: (p ∧ q ∧ ¬r) ∨ (p ∧ ¬q ∧ r) ∨ (¬p ∧ q ∧ r) ∨ (p ∧ q ∧ r)
↔ (p ∧ q) ∨ (p ∧ r) ∨ (q ∧ r) := by tauto
Bulhwi Cha (Feb 09 2023 at 08:03):
Oh, thanks! Now I'm blaming myself for not having thought about using the tauto
tactic.
Bulhwi Cha (Feb 09 2023 at 08:04):
But is it the only way to shorten my proof?
Mario Carneiro (Feb 09 2023 at 08:18):
here's another brute-force-ish proof:
example (p q r : Prop)
: (p ∧ q ∧ ¬r) ∨ (p ∧ ¬q ∧ r) ∨ (¬p ∧ q ∧ r) ∨ (p ∧ q ∧ r)
↔ (p ∧ q) ∨ (p ∧ r) ∨ (q ∧ r) := by
by_cases p <;> by_cases q <;> by_cases r <;> simp [*]
Bulhwi Cha (Feb 09 2023 at 08:24):
I should take a closer look at Lean's tactics.
Mario Carneiro (Feb 09 2023 at 08:24):
and here's a more "conceptual" proof most similar to your calc proof:
import Mathlib.Logic.Basic
example (p q r : Prop)
: (p ∧ q ∧ ¬r) ∨ (p ∧ ¬q ∧ r) ∨ (¬p ∧ q ∧ r) ∨ (p ∧ q ∧ r)
↔ (p ∧ q) ∨ (p ∧ r) ∨ (q ∧ r) :=
calc
(p ∧ q ∧ ¬r) ∨ (p ∧ ¬q ∧ r) ∨ (¬p ∧ q ∧ r) ∨ (p ∧ q ∧ r)
↔ (p ∧ q ∧ ¬r ∨ p ∧ q ∧ r) ∨ (p ∧ ¬q ∧ r ∨ p ∧ q ∧ r) ∨ ¬p ∧ q ∧ r ∨ p ∧ q ∧ r :=
by simp only [or_assoc, or_left_comm, or_self]
_ ↔ (p ∧ q ∧ (¬r ∨ r)) ∨ (p ∧ (¬q ∨ q) ∧ r) ∨ ((¬p ∨ p) ∧ q ∧ r) :=
by simp only [or_and_right, and_or_left]
_ ↔ (p ∧ q) ∨ (p ∧ r) ∨ (q ∧ r) := by simp only [em', and_true, true_and]
Bulhwi Cha (Feb 09 2023 at 09:11):
Thanks again. Your last proof gave me some lessons:
- Don't forget to use left and right commutativity.
- Use parentheses carefully.
- Get a better understanding of how tactics work under the hood.
Last updated: Dec 20 2023 at 11:08 UTC