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