Zulip Chat Archive

Stream: lean4

Topic: error for theorem, expects function


Jared green (Feb 25 2024 at 12:44):

at lines 214 and 228

import Init.Data.List
import Std.Data.List
import Mathlib.Data.List.Dedup
import Mathlib.Data.List.Pairwise
import Mathlib.Data.List.Join
import Mathlib.Data.List.Basic
import Mathlib.Data.List.Defs
import Mathlib.Data.List.Infix
import Mathlib.Data.List.Lattice
import Mathlib.Data.List.Lemmas
import Mathlib.Data.Bool.AllAny
import Mathlib.Data.Bool.Basic

open Classical

variable {α : Type}[h : DecidableEq α]
inductive normalizable α (pred : α -> Prop)
  where
  | atom : α -> (normalizable α pred)
  | And : (normalizable α pred) -> (normalizable α pred) -> normalizable α pred
  | Or : (normalizable α pred) -> (normalizable α pred) -> normalizable α pred
  | Not : normalizable α pred -> normalizable α pred
deriving DecidableEq

namespace normalizable

@[reducible]
def toProp (n : normalizable α pred) : Prop :=
  match n with
  | atom a => pred a
  | And a b =>  toProp a  toProp b
  | Or a b => (toProp a)  toProp b
  | Not i => ¬(toProp i)

@[simp]
theorem toProp_not : toProp (Not n₁)  ¬ toProp n₁ := Iff.rfl

@[simp]
theorem toProp_and : toProp (And n₁ n₂)  toProp n₁  toProp n₂ := Iff.rfl

@[simp]
theorem toProp_or : toProp (Or n₁ n₂)  toProp n₁  toProp n₂ := Iff.rfl

@[simp]
theorem toProp_atom {a : α} : toProp (atom a : normalizable α pred)  pred a := Iff.rfl


def subnormalize (n : (normalizable α pred)) : List (List (List (normalizable α pred))) :=
  match n with
  | Or a b => [[a,n],[b,n],[Not a,Not b, Not n]] :: (List.append (subnormalize a) (subnormalize b))
  | And a b => [[a,b,n],[Not a,Not n],[Not b,Not n]] :: (List.append (subnormalize a) (subnormalize b))
  | Not i => [[n,Not i],[Not n, i]] :: (subnormalize i)
  | atom _ => [[[n],[Not n]]]

def normalize :  normalizable α pred -> List (List (List (normalizable α pred))) := fun o =>
  [[o]] :: (subnormalize o)

def nStrip (n : normalizable α pred) : Bool × normalizable α pred :=
  match n with
  | Not i => (false,i)
  | i => (true,i)

def booleanize (n : List (List (List (normalizable α pred)))) : List (List (List (Bool × normalizable α pred))) :=
  n.map (fun x => x.map (fun y => y.map (fun z => nStrip z)))

def normalizel (n : normalizable α pred) : List (List (List (Bool × normalizable α pred))) :=
  booleanize (normalize n)

def wToProp (w : Bool × normalizable α pred) : Prop :=
  if w.fst then toProp w.snd else ¬(toProp w.snd)

def sToProp (s : List (Bool × normalizable α pred)) : Prop :=
  s.all (fun x => wToProp x)

def gToProp (g : List (List (Bool × normalizable α pred))) : Prop :=
  g.any (fun x => sToProp x)

def nToProp (n : List (List (List (Bool × normalizable α pred)))) : Prop :=
  n.all (fun x => gToProp x)

def fToProp (n : List (List (List (normalizable α pred)))) : Prop :=
  n.all (fun x => x.any (fun y => y.all (fun z => toProp z)))

theorem nStrip_equiv :  n : normalizable α pred, toProp n <-> wToProp (nStrip n) :=
  by
  intro n
  unfold nStrip
  induction n
  simp
  unfold wToProp
  simp
  simp
  unfold wToProp
  simp
  unfold wToProp
  simp
  simp
  unfold wToProp
  simp

theorem booleanize_eqiv :  n : List (List (List (normalizable α pred))), fToProp n <-> nToProp (booleanize n) :=
  by
  intro n
  unfold nToProp
  simp
  unfold fToProp
  simp
  unfold booleanize
  simp
  unfold gToProp
  simp
  unfold sToProp
  simp
  simp [nStrip_equiv]

theorem andGateTaut : (¬ a  ¬(a  b))  (¬ b  ¬(a  b))  (a  b  (a  b)) :=
  by
  cases Classical.em a
  cases Classical.em b
  right
  right
  constructor
  assumption
  constructor
  assumption
  constructor
  assumption
  assumption
  right
  left
  constructor
  assumption
  push_neg
  intro
  assumption
  left
  constructor
  assumption
  rw [and_comm]
  push_neg
  intro
  assumption

theorem orGateTaut : (a  (a  b))  (b  (a  b))  ((¬ a)  (¬b)  ¬(a  b)) = true :=
  by
  simp
  cases Classical.em a
  left
  constructor
  assumption
  left
  assumption
  right
  cases Classical.em b
  left
  constructor
  assumption
  right
  assumption
  right
  constructor
  assumption
  constructor
  assumption
  push_neg
  constructor
  assumption
  assumption

theorem all_and : List.all ( a ++ b) c <-> List.all a c  List.all b c :=
  by
  simp
  constructor
  intro ha
  constructor
  intro b
  intro hb
  apply ha
  left
  exact hb
  intro c
  intro hc
  apply ha
  right
  exact hc
  intro ha
  intro b
  intro hb
  cases hb
  apply ha.left
  assumption
  apply ha.right
  assumption

theorem subnormal :  n : normalizable α pred, fToProp (subnormalize n) :=
  by
  intro n
  induction' n with a b c d e f g i j k l
  unfold subnormalize
  unfold fToProp
  simp
  unfold toProp
  apply Classical.em
  unfold subnormalize
  simp
  unfold fToProp
  rw [List.all_cons]
  simp only [List.any_cons, List.all_cons, List.all_nil, Bool.and_true, List.any_nil,
    Bool.or_false, Bool.and_eq_true, Bool.or_eq_true, decide_eq_true_eq,
    List.mem_append, List.any_eq_true]
  constructor
  rw [toProp_not]
  rw [toProp_and]
  exact andGateTaut (toProp b) (toProp c) --function expected...
  rw [all_and]
  constructor
  assumption
  assumption
  unfold fToProp
  unfold subnormalize
  rw [List.all_cons]
  simp only [List.any_cons, List.all_cons, toProp_or, List.all_nil, Bool.and_true, toProp_not,
    List.any_nil, Bool.or_false, List.append_eq, Bool.and_eq_true, Bool.or_eq_true,
    decide_eq_true_eq, List.mem_append, List.any_eq_true]
  constructor
  rw [toProp_not]
  rw [toProp_or]
  exact orGateTaut (toProp f) (toProp g) --function expected...
  rw [all_and]
  constructor
  assumption
  assumption
  unfold fToProp
  unfold subnormalize
  rw [List.all_cons]
  simp only [List.any_cons, List.all_cons, toProp_not, List.all_nil, Bool.and_true, Bool.and_self,
    not_not, List.any_nil, Bool.or_false, Bool.and_eq_true, Bool.or_eq_true, decide_eq_true_eq,
     List.any_eq_true]
  constructor
  cases Classical.em (toProp k)
  right
  assumption
  left
  assumption
  unfold fToProp at l
  exact l

Kevin Buzzard (Feb 25 2024 at 13:03):

normalizable.andGateTaut {a b : Prop} : ¬a ∧ ¬(a ∧ b) ∨ ¬b ∧ ¬(a ∧ b) ∨ a ∧ b ∧ a ∧ b. Do you understand what the {a b : Prop} brackets mean? Take a look at the "implicit arguments" section in Chapter 2 of #tpil

Jared green (Feb 25 2024 at 13:07):

placing underscores gets the same message.

Jared green (Feb 25 2024 at 13:09):

it does close the goal, so i wonder if the messages can be ignored.

Kevin Buzzard (Feb 25 2024 at 13:10):

Did you take a look at the section I mentioned above yet?

Kevin Buzzard (Feb 25 2024 at 13:10):

You can never ignore errors btw. Any message (such as "no goals") after an error is meaningless.

Jared green (Feb 25 2024 at 13:11):

i read it.

Kevin Buzzard (Feb 25 2024 at 13:11):

So you understand the error now?

Jared green (Feb 25 2024 at 13:11):

no

Kevin Buzzard (Feb 25 2024 at 13:12):

Your definition of andGateTaut makes the inputs implicit. You are attempting to give them explicitly.

Jared green (Feb 25 2024 at 13:12):

what should the line look like?

Jared green (Feb 25 2024 at 13:13):

not giving them results in a type mismatch.

Kevin Buzzard (Feb 25 2024 at 13:13):

Well you have two choices. Either you change the definition of andGateTaut to make the inputs explicit, or you don't give the inputs at all and hope that lean can infer them.

Kevin Buzzard (Feb 25 2024 at 13:14):

Oh there's a third choice: you use the (a := toProp b) syntax

Kevin Buzzard (Feb 25 2024 at 13:18):

To better understand what's going on, I recommend that you set_option autoImplicit false and also the other one whose name I don't remember -- something like set_option weakAutoImplicit false. These are options which default to true but I have a mountain of evidence that they're very confusing for beginners. Once you do this your code will break because all the times you've used a variable without declaring it you'll now get an error, forcing you to add lines like variable (a : Prop). When you add these lines you'll be forced to think about brackets, and this will help you understand what's going on

Kevin Buzzard (Feb 25 2024 at 13:33):

Jared green said:

not giving them results in a type mismatch.

This probably means that your proof is incorrect.

  exact andGateTaut (a := toProp b) (b := toProp c)

(which is my understanding of what you're trying to say) gives the error

type mismatch
  andGateTaut
has type
  ¬toProp b  ¬(toProp b  toProp c) 
    ¬toProp c  ¬(toProp b  toProp c)  toProp b  toProp c  toProp b  toProp c : Prop
but is expected to have type
  toProp b  toProp c  toProp b  toProp c 
    ¬toProp b  toProp (Not (And b c))  toProp (Not c)  toProp (Not (And b c)) : Prop

so as well as your issue with implicit/explicit functions, you have this problem too (in fact my impression is that this is your main problem).

Jared green (Feb 25 2024 at 13:49):

so it turns out clause order matters... problem solved.

Damiano Testa (Feb 25 2024 at 20:19):

Jared green said:

it does close the goal, so i wonder if the messages can be ignored.

Kevin Buzzard said:

You can never ignore errors btw. Any message (such as "no goals") after an error is meaningless.

When lean encounters an error, it liberally introduces sorry for the sake of "let's try to keep parsing this". This does mean that you can sometimes catch more than one error. However, any type checking claim (e.g. No goals) is meaningless.


Last updated: May 02 2025 at 03:31 UTC