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