Zulip Chat Archive
Stream: new members
Topic: Creating instance and is_commutative
Joao Bregunci (Mar 08 2021 at 22:17):
My goal here is given a set Prop
, let's say {s1,s2,⋯,sn}
to create a Prop
s1 ∧ s2 ∧ ⋯ ∧ sn
, so to do this I wanted to use:
def finset.fold {α : Type u_1} {β : Type u_2} (op : β → β → β)
[hc : is_commutative β op] [ha : is_associative β op] (b : β) (f : α → β) (s : finset α) :
So as far as I understand, I need to make two instances for is_commutative
and is_associative
for the and
operator. So I tried the following:
instance my_and_comm (A : Prop) :
@is_commutative Prop and := ⟨ and.comm ⟩
Where I got the following:
type mismatch at application
{comm := and.comm ?m_2}
term
and.comm
has type
?m_1 ∧ ?m_2 ↔ ?m_2 ∧ ?m_1
but is expected to have type
∀ (a b : Prop), (a ∧ b) = (b ∧ a)
Is there any way which I can turn this ↔
into an equality? Or I won't be able to use finset.fold
.
Bryan Gin-ge Chen (Mar 08 2021 at 22:20):
This works:
instance my_and_comm (A : Prop) :
@is_commutative Prop and := ⟨λ a b, by rw [and.comm]⟩
Joao Bregunci (Mar 08 2021 at 22:26):
Fantastic Bryan, sorry but can you shine a light on this lambda expression? This rw [and.comm]
is creating the equality how?
Bryan Gin-ge Chen (Mar 08 2021 at 22:28):
I'm not sure of all the details here, but the by
keyword enters tactic mode, and then I use the rw
tactic, which apparently is able to do some extra cleanup when rewriting with and.comm
.
Edit: tactic#show_term shows the term that's created by the tactic:
import tactic
instance my_and_comm (A : Prop) :
@is_commutative Prop and := ⟨λ a b, by show_term {rw [and.comm]}⟩
/-
Try this: exact (id (eq.rec (eq.refl ((a ∧ b) = (b ∧ a))) (propext and.comm))).mpr (eq.refl (b ∧ a))
-/
Bryan Gin-ge Chen (Mar 08 2021 at 22:32):
Ah, I see, this is simpler:
instance my_and_comm (A : Prop) :
@is_commutative Prop and := ⟨λ a b, propext $ and.comm⟩
So rw
(and simp
) apply propext
when necessary to close goals.
Kyle Miller (Mar 09 2021 at 00:31):
It turns out that (∧)
(which is and
but using its notation; this is the "section" of the operator, giving a function of two arguments) already has an is_commutative
instance somehow through docs#inf_is_commutative. I can't say I fully understand how this works.
Bryan Gin-ge Chen (Mar 09 2021 at 00:33):
Ah, I bet it's from the boolean_algebra
structure on Prop
: docs#boolean_algebra_Prop
Mario Carneiro (Mar 09 2021 at 05:34):
@Joao Bregunci The simplest way to make a conjunction out of an arbitrary set of propositions, not necessarily even finite, is using forall: \forall p \in s, p
Joao Bregunci (Mar 09 2021 at 14:04):
Thanks Mario, I was overcomplicating thinks, but I at least learned a few little things :)
. I have a tendency to always think like functional programming, so whenever I see a problem I try to put map
, fold
, filter
, zip
everywhere... This aspect of Lean, so far in most tutorials that I've seen, are a little bit disappointing to say, at least in my view.
Kevin Buzzard (Mar 09 2021 at 14:31):
The definitions are the same as in Haskell and the theorems about the definitions are typically proved directly after the definitions in the source code. I agree that they don't come up much in the docs! These kinds of constructions come up much more in things like program verification. I am about to finish 16 hours of lectures on mathematics in lean this week and I never mentioned fold or filter or zip once, but we did talk about things like filter.map (but never list.map).
Last updated: Dec 20 2023 at 11:08 UTC