Zulip Chat Archive

Stream: Is there code for X?

Topic: dealing with the Option monad in proofs


Paige Thomas (Jan 19 2025 at 20:07):

Is there a way to make goals like this easier to work with, for example by some tactic to automatically turn it into a bunch of if, then, else cases that I could do a split_ifs on? That is cases on whether or not the eval V F is a some val_phi or none?

 (¬∃ V,
      (do
          let val_phi  eval V F
          some ¬val_phi) =
        some True) 
   (V : PropValuation), eval V F = some True

Eric Wieser (Jan 19 2025 at 20:19):

cases h : eval V F?

Eric Wieser (Jan 19 2025 at 20:20):

(it might only work with cases')

Paige Thomas (Jan 19 2025 at 20:21):

Unfortunately I don't have the V to use.

Paige Thomas (Jan 19 2025 at 20:21):

That is, it is only quantified.

Edward van de Meent (Jan 19 2025 at 20:23):

in that case, can you first rewrite using not_exists, then apply something like forall_congr?

Edward van de Meent (Jan 19 2025 at 20:25):

at that point you should be able to use v, i think...

Paige Thomas (Jan 19 2025 at 20:29):

  ...
  rewrite [not_exists]
  simp
  congr!
  case _ V =>
    cases h : eval V F
    simp
case none
F : Formula_
V : PropValuation
h : eval V F = none
 False

Paige Thomas (Jan 19 2025 at 20:31):

The forall_congr wouldn't apply.

Paige Thomas (Jan 19 2025 at 20:38):

Not a MWE, but workable code:

import Lean
import Batteries.Tactic.Lint.Frontend
import Mathlib.Util.CompileInductive
import Mathlib.Tactic


set_option autoImplicit false


/--
  The type of formulas.
-/
inductive Formula_ : Type
  | false_ : Formula_
  | true_ : Formula_
  | atom_ : String  Formula_
  | not_ : Formula_  Formula_
  | and_ : Formula_  Formula_  Formula_
  | or_ : Formula_  Formula_  Formula_
  | imp_ : Formula_  Formula_  Formula_
  | iff_ : Formula_  Formula_  Formula_
  | forall_ : String  Formula_  Formula_
  | exists_ : String  Formula_  Formula_
  deriving Inhabited, DecidableEq, Repr

compile_inductive% Formula_

open Formula_

def atom_occurs_in
  (A : String) :
  Formula_  Prop
  | false_
  | true_ => False
  | atom_ X => A = X
  | not_ phi => atom_occurs_in A phi
  | and_ phi psi
  | or_ phi psi
  | imp_ phi psi
  | iff_ phi psi => atom_occurs_in A phi  atom_occurs_in A psi
  | forall_ _ phi
  | exists_ _ phi => atom_occurs_in A phi


def PropValuation : Type := String  Prop
  deriving Inhabited


def eval
  (V : PropValuation) :
  Formula_  Option Prop
  | false_ => some False
  | true_ => some True
  | atom_ X => some (V X)
  | not_ phi => do
    let val_phi  eval V phi
    ¬ val_phi
  | and_ phi psi => do
    let val_phi  eval V phi
    let val_psi  eval V psi
    val_phi  val_psi
  | or_ phi psi => do
    let val_phi  eval V phi
    let val_psi  eval V psi
    val_phi  val_psi
  | imp_ phi psi => do
    let val_phi  eval V phi
    let val_psi  eval V psi
    val_phi  val_psi
  | iff_ phi psi => do
    let val_phi  eval V phi
    let val_psi  eval V psi
    val_phi  val_psi
  | forall_ _ _
  | exists_ _ _ => none


def satisfies
  (V : PropValuation)
  (F : Formula_) :
  Prop :=
  eval V F = some True

def Formula_.is_tautology
  (F : Formula_) :
  Prop :=
   (V : PropValuation), satisfies V F

def Formula_.is_satisfiable
  (F : Formula_) :
  Prop :=
   (V : PropValuation), satisfies V F

def Formula_.is_unsatisfiable
  (F : Formula_) :
  Prop :=
  ¬  (V : PropValuation), satisfies V F


example
  (F : Formula_) :
  (not_ F).is_unsatisfiable  F.is_tautology :=
  by
  unfold is_tautology
  unfold is_unsatisfiable
  unfold satisfies
  simp only [eval]
  sorry

Edward van de Meent (Jan 19 2025 at 20:42):

add on these:

  rw [not_exists]
  rw [iff_eq_eq]
  apply forall_congr
  simp? says simp only [Option.bind_eq_bind, eq_iff_iff]
  intro V

Paige Thomas (Jan 19 2025 at 21:26):

I think maybe the cases isn't working in this proof.

Paige Thomas (Jan 19 2025 at 21:27):

Or I am applying it wrong.

Edward van de Meent (Jan 19 2025 at 21:32):

ah, maybe it's not true?

Edward van de Meent (Jan 19 2025 at 21:33):

due to how exists works, it seems there might be an issue?

Paige Thomas (Jan 19 2025 at 21:33):

I think it needs classical?

Paige Thomas (Jan 19 2025 at 21:35):

oh, hmm.

Edward van de Meent (Jan 19 2025 at 21:35):

no, the issue is that if your formula contains exists, satisfies V F will always be false

Paige Thomas (Jan 19 2025 at 21:36):

yeah, hmm

Edward van de Meent (Jan 19 2025 at 21:36):

meaning that F.is_unsatisfiable while it might be a tautology

Edward van de Meent (Jan 19 2025 at 21:37):

(looking at the code again, it looks like the same issue happens for forall

Paige Thomas (Jan 19 2025 at 21:37):

I need a different definition of satisfies that only holds if F is a proposition (does not have Forall and Exists)

Edward van de Meent (Jan 19 2025 at 21:38):

alternatively, you can create an F.is_proposition predicate, and have that as hypothesis for the theorem

Paige Thomas (Jan 19 2025 at 21:39):

yeah

Paige Thomas (Jan 19 2025 at 21:41):

I guess then I need to do an induction on F.

Paige Thomas (Jan 19 2025 at 21:48):

Thank you for finding that.


Last updated: May 02 2025 at 03:31 UTC