Zulip Chat Archive

Stream: mathlib4

Topic: equivalence relations are symmetric


Kevin Buzzard (Nov 05 2022 at 11:56):

In core Init.Core we have

structure Equivalence {α : Sort u} (r : α  α  Prop) : Prop where
  /-- An equivalence relation is reflexive: `x ~ x` -/
  refl  :  x, r x x
  /-- An equivalence relation is symmetric: `x ~ y` implies `y ~ x` -/
  symm  :  {x y}, r x y  r y x
  /-- An equivalence relation is transitive: `x ~ y` and `y ~ z` implies `x ~ z` -/
  trans :  {x y z}, r x y  r y z  r x z

and in Mathlib.Init.Logic we have

def Symmetric :=  x y⦄, x  y  y  x

Now this doesn't work:

import Mathlib.Init.Logic

variable (h : Equivalence r) -- autoImplicit is sometimes v cool

#check (h.symm : Symmetric r)
/-
type mismatch
  Equivalence.symm h
has type
  r ?m.52 ?m.53 → r ?m.53 ?m.52 : Prop
but is expected to have type
  Symmetric r : Prop
-/

Is it because of the {x y} vs ⦃x y⦄ clash? Should I write a function from Equivalence r to Symmetric r called Equivalence.Symmetric or something?

def Equivalence.Symmetric (h : Equivalence r) : Symmetric r :=
λ _ _ => h.symm

(and same question for trans -- and the coercion does work with refl but should Equivalence.Reflexive be written too?)

Mario Carneiro (Nov 05 2022 at 12:06):

Sure

Mario Carneiro (Nov 05 2022 at 12:07):

how about Equivalence.symmetric et al? (lowercase because it's a proof)

Kevin Buzzard (Nov 05 2022 at 12:18):

I could just do this:

import Mathlib.Init.Logic
import Mathlib.Init.Function

section Comap

variable {r : β  β  Prop}

infixl:2  " on " => Function.on_fun

theorem Reflexive.comap (h : Reflexive r) (f : α  β) : Reflexive (r on f) := fun a => h (f a)

theorem Symmetric.comap (h : Symmetric r) (f : α  β) : Symmetric (r on f) := fun _ _ hab => h hab

theorem Transitive.comap (h : Transitive r) (f : α  β) : Transitive (r on f) := fun _ _ _ hab hbc => h hab hbc

-- works fine
theorem Equivalence.comap (h : Equivalence r) (f : α  β) : Equivalence (r on f) :=
  fun a => h.refl (f a), fun hab => h.symm hab, fun hab hbc => h.trans hab hbc

-- Lean 3 proof nicer though:
-- ⟨h.1.comap f, h.2.1.comap f, h.2.2.comap f⟩

Actually I can't even get Equivalence.symmetric to work:

def Equivalence.symmetric (h : Equivalence r) : Symmetric r :=
  λ _ _ => h.symm

theorem Equivalence.comap' (h : Equivalence r) (f : α  β) : Equivalence (r on f) :=
  Reflexive.comap h.refl f, Symmetric.comap h.symmetric f, sorry
/-
type mismatch
  Symmetric.comap (symmetric h) f
has type
  Symmetric (r on f) : Prop
but is expected to have type
  Function.on_fun r f x✝ y✝ → Function.on_fun r f y✝ x✝ : Prop
the following variables have been introduced by the implicit lambda feature
  x✝ : ?m.657
  y✝ : ?m.657
you can disable implict lambdas using `@` or writing a lambda expression with `{}` or `[]` binder annotations.
-/

Mario Carneiro (Nov 05 2022 at 12:20):

try @(Symmetric.comap h.symmetric f)?

Mario Carneiro (Nov 05 2022 at 12:20):

or Symmetric.comap h.symmetric f ..

Kevin Buzzard (Nov 05 2022 at 12:25):

I can't get the dots one working but the @ is the trick I was missing: thanks! In fact dot notation also works: I've got this compiling

theorem Equivalence.comap' (h : Equivalence r) (f : α  β) : Equivalence (r on f) :=
  h.reflexive.comap f, @(h.symmetric.comap f), @(h.transitive.comap f)⟩

which I think is fine.


Last updated: Dec 20 2023 at 11:08 UTC