Zulip Chat Archive
Stream: lean4
Topic: boolean true = true is Prop True?
Hannah Santos (Oct 13 2023 at 19:33):
I've been trying to prove some things for this ListNat type, to practice, and I've been having this problem with having to prove (true = true) = True
, and also with ¬(false = true) = True
every time I want to use an if-then-else. It would be most helpful if one could point me in the right direction here. :sweat_smile:
inductive ListNat where
| nil
| cons : Nat → ListNat → ListNat
deriving Repr
open ListNat
open Nat
def filter : (Nat → Bool) → ListNat → ListNat
| _, nil => nil
| function, cons n l => if function n = True then cons n (filter function l) else filter function l
def append : Nat → ListNat → ListNat
| n, nil => cons n nil
| n, cons m l => cons m (append n l)
def reverse : ListNat → ListNat
| nil => nil
| cons n l => append n (reverse l)
theorem false_not_true :
false ≠ true :=
by
intro H
cases H
theorem filter_reverse (n : Nat) (ns : ListNat) (p : Nat → Bool):
filter p (append n (reverse ns)) = (if p n then append n (filter p (reverse ns)) else (filter p (reverse ns))) :=
by
induction ns with
| nil =>
rw [reverse, filter, append, filter, filter]
cases p n
rw [if_neg, if_neg false_not_true]
intro H
exact false_not_true H
/-case nil.true
l: ListNat
n: Nat
p: Nat → Bool
⊢ (if (true = true) = True then cons n nil else nil) = if true = true then cons n nil else nil
Expected type
Messages (1)
lean:413:25
application type mismatch
false_not_true H
argument
H
has type
(false = true) = True : Prop
but is expected to have type
false = true : Prop
-/
Alex Keizer (Oct 13 2023 at 19:38):
The simp
tactic should be able to prove that for you.
example : (true = true) = True := by
simp only
Hannah Santos (Oct 13 2023 at 19:51):
But what is it doing behind the scenes?
Timo Carlin-Burns (Oct 13 2023 at 19:58):
It looks like the main thing it's using is docs#eq_true_of_decide
import Mathlib.Tactic
example : (true = true) = True := by
show_term simp only
-- Try this: exact of_eq_true (eq_true_of_decide (Eq.refl true))
Timo Carlin-Burns (Oct 13 2023 at 20:01):
The decide
tactic also works
example : (true = true) = True := by decide
Hannah Santos (Oct 13 2023 at 20:05):
And what would work for the other case ¬(false = true) = True
?
Timo Carlin-Burns (Oct 13 2023 at 20:06):
example : ¬(false = true) = True := by
decide
Timo Carlin-Burns (Oct 13 2023 at 20:08):
(simp
/simp only
would work as well. By default simp
uses decide
automatically, so anything decide
can prove simp
can prove too.)
Kevin Buzzard (Oct 13 2023 at 20:09):
If you're trying to prove things rather than compute things, then why not use Prop
instead of bool
? It's far more proof-friendly. It's quite rare to see bool
in mathlib, for example.
Hannah Santos (Oct 13 2023 at 20:09):
(I like to avoid simp because I like to write every part of the proof myself, when I put simp I feel like I have no clue as to what solved it)
Hannah Santos (Oct 13 2023 at 20:11):
It's a part of a homework I got, so it was supposed to be in bool
. (Even though making it on Lean is a part of my desire to suffer, it seems)
Ruben Van de Velde (Oct 13 2023 at 20:13):
I think (part of) the cause may be the if function n = True
in your filter
, where function n
returns a Bool
but True
is a Prop
. Try replacing that by = true
, perhaps
Hannah Santos (Oct 13 2023 at 20:14):
Oh!
Hannah Santos (Oct 13 2023 at 20:14):
I did that again!
Hannah Santos (Oct 13 2023 at 20:14):
Thanks.
Thomas Murrills (Oct 13 2023 at 20:25):
By the way, there are other ways to show this equality! One is by decide
, but you can turn decide
off in simp
and it still works:
theorem foo : (true = true) = True := by
simp (config := {decide := false}) only
#print foo
The main ingredient in this method (which imo is more "sensible") is propext
, turning a ↔︎ b
into a = b
; and we can prove a ↔︎ b
directly when a
and b
are true (in the sense that h1 : a
and h2 : b
) by just providing those proofs for each direction. So this bottoms out to rfl : true = true
and trivial : True
; see eq_self
and eq_true
(which perform this proof) for details. (Actually this particular simp
does some unnecessary stuff as well, so it's not the best example, but you can still find sensible things by digging through the term and command-clicking.)
You might be aware of these already, but just in case it's helpful for discovery: simp?
, is useful in seeing what lemmas simp
uses behind the scenes (I think you might need to import Std
?), and if you don't have access to that, there's always set_option trace.Meta.Tactic.simp true
. (And, ofc, #print <theoremName>
after the fact to see what the term is! :) )
Kevin Buzzard (Oct 13 2023 at 20:45):
Classically Prop and bool are the same thing. I'm a bit unclear about the homework claim. If the homework wasn't "do this in lean" then you could argue that Prop = {True, False} just like bool = {true, false} and surely it's very difficult to tell them apart
Last updated: Dec 20 2023 at 11:08 UTC