Zulip Chat Archive
Stream: general
Topic: equivalence relation on wrong type
Kevin Buzzard (Aug 09 2018 at 23:22):
Luca defined an equivalence relation (homotopy equivalence) on path x y
, the paths from x to y in a topological space. He defined loop x
to be path x x
and then wanted to define pi_1
to be the equivalence classes. Lean seemed to obstinately refuse to put the equivalence relation on loop x
, insisting it was on path x x
. Here's some code that doesn't run, plus some commented out code which fixes the problem.
variable {α : Type*} def path : α → α → Type := sorry def comp_of_path {x y z : α} : path x y → path y z → path x z := sorry def is_homotopic_to (x y : α) : path x y → path x y → Prop := sorry definition is_equivalence (x y : α) : equivalence (is_homotopic_to x y) := sorry definition loop (x : α) := path x x /- -- This fixes the problem below -- is it safe to have both instances floating around? instance setoid_hom_path (x : α) : setoid (path x x) := setoid.mk (is_homotopic_to x x) (is_equivalence x x) instance setoid_hom_loop (x : α) : setoid (loop x) := by unfold loop; apply_instance -/ instance setoid_hom_loop (x : α) : setoid (loop x) := setoid.mk (is_homotopic_to x x : loop x → loop x → Prop) (is_equivalence x x : equivalence (is_homotopic_to x x : loop x → loop x → Prop)) def space_π_1 (x : α) := quotient (setoid_hom_loop x : setoid (loop x)) -- error here def mul {x : α} : space_π_1 x → space_π_1 x → space_π_1 x := quotient.lift₂ (λ f g : loop x, ⟦((comp_of_path (f : loop x) (g : loop x)) : loop x)⟧) sorry /- -- error is on ⟦ and it's failed to synthesize type class instance for α : Type u_1, x : α, f g : loop x ⊢ setoid (path x x) -/
I tell Lean so many times that we're talking about loop x
but the error seems to indicate that whilst I beg Lean to believe that comp_of_path f g
has type loop x
, it complains that path x x
is not a setoid.
So I found a fix -- instead of making one instance I make two -- I make an instance on path x x
and then deduce one on loop x
. I am not sure what's going on here and in some sense I'm now not even sure which of the equivalence relations I'm even using. Does it matter that I now have two instances? Why can't I just get away with my uncommented approach?
Simon Hudon (Aug 09 2018 at 23:41):
I think the problem is that ((comp_of_path (f : loop x) (g : loop x)) : loop x)
does not have type loop x
because comp_of_path
does not have type loop x
. The (_ : _)
notation does not change the type of the expression, it only provides hints to fill in gaps in the type information.
Simon Hudon (Aug 09 2018 at 23:43):
The only alternative I can see to the two instances solution is to create a coercion function. I think I like your solution better. You could make it only one instance (on path x x
if you made loop
reducible.
Chris Hughes (Aug 09 2018 at 23:46):
This also works
def mul {x : α} : space_π_1 x → space_π_1 x → space_π_1 x := quotient.lift₂ (λ f g, show space_π_1 x, from ⟦comp_of_path f g⟧) sorry
Simon Hudon (Aug 09 2018 at 23:49):
Ah! That's true! So this probably works as well:
(⟦(comp_of_path (f : loop x) (g : loop x))⟧ : space_π_1 x)
Chris Hughes (Aug 09 2018 at 23:50):
yes it does, much more sensible
Kevin Buzzard (Aug 10 2018 at 10:44):
But Luca would then have to write that all through his code, which kind of stinks -- I wanted him to use type class inference precisely because it was supposed to be making his life easier.
Last updated: Dec 20 2023 at 11:08 UTC