Zulip Chat Archive
Stream: new members
Topic: Subtypes for provably equal sets
Heather Macbeth (Sep 04 2020 at 16:30):
I would like to identify the subtypes coming from two sets which I can prove are equal:
import order.filter.at_top_bot
variables {α : Type*} [decidable_linear_order α]
open set filter
-- works
example {a b : α} : @Ioo (order_dual α) _ b a = @Ioo α _ a b := dual_Ioo
-- fails
example {a b : α} : @at_bot (Ioo a b) _ = @at_top (@Ioo (order_dual α) _ b a) _ := sorry
I get the following error: "type mismatch at application at_bot = at_top
, term at_top
has type filter ↥(Ioo b a)
but is expected to have type filter ↥(Ioo a b)
".
This makes sense, but how do I fix it? (Is this similar to the questions @Peter Nelson was asking the other day?)
Kevin Buzzard (Sep 04 2020 at 16:38):
You can prove the sets are equal, but equality of types is an unpleasant notion. One way of "fixing" it would be to give a name to the "identity" map between the types, and then compare one filter with the pullback of the other.
Heather Macbeth (Sep 04 2020 at 16:45):
Thanks! This typechecks, is it what you had in mind?
import order.filter.at_top_bot
variables {α : Type*} [decidable_linear_order α]
open set filter
def order_id (a b : α) : @Ioo (order_dual α) _ b a → @Ioo α _ a b :=
λ x, ⟨(x : order_dual α), begin
have : @Ioo (order_dual α) _ b a = @Ioo α _ a b := dual_Ioo,
rw ← this,
exact x.2,
end⟩
example {a b : α} :
comap (order_id a b) (@at_bot (@Ioo α _ a b) _) = @at_top (@Ioo (order_dual α) _ b a) _ :=
sorry
Kevin Buzzard (Sep 04 2020 at 16:45):
Yes! Here's my definition of order_id:
variables (a b : α)
def X := @Ioo α _ a b
def Y := @Ioo (order_dual α) _ b a
def to_dual : α → order_dual α := id -- do we have this map?
def f : X a b → Y a b := λ x, ⟨to_dual x.1, x.2.2, x.2.1⟩
Heather Macbeth (Sep 04 2020 at 16:47):
Looks great. Have to go teach now, but I look forward to filling in my sorry using this trick.
Kevin Buzzard (Sep 04 2020 at 16:53):
In Lean we have groups and add_groups, and sometimes this is great and sometimes it's not great. There is this to_additive
story, which moves from one situation to the other: if (G : Type) [group G]
then additive G
is the add_group
with group law +
which is defined to be G
's *
. But the definition of additive G
is just additive G := G
. Similarly if A
is an add_group then multiplicative A
is the group. There are named maps called things like additive.of_multiplicative
or something, which move you between these two structures -- this is why I defined to_dual
. However some proofs in mathlib completely abuse the fact that these maps from G
to additive G
are just the identity function. This might work fine for groups, but you're doing the dual order and here what is a bit scary is that you will now have < on alpha and a different < on order_dual alpha
and if you are not principled about these things then it will be easy to get confused. It is not hard to get Lean to accept "theoretically ill-defined" terms, e.g. of the form "x < y" where x : alpha
and y : order_dual alpha
, and then you can't guess what <
will mean (and in the days before widgets this was a royal pain). So I guess I would recommend the principled approach, using to_dual
rather than "abusing" the fact that order_dual α := α
.
Kevin Buzzard (Sep 04 2020 at 17:04):
I should say however that this idea of defining to_dual
is my own crazy notion and it's not already in mathlib which might mean that it's for some reason a bad idea.
Reid Barton (Sep 04 2020 at 17:07):
For opposite categories (which are basically the same thing) we have docs#opposite which is an even more locked down version of this. Your to_dual
is called op
Kevin Buzzard (Sep 04 2020 at 17:09):
@[irreducible]
def opposite : Sort u → Sort u :=
λ (α : Sort u), α
Because it's irreducible, it's much easier to be principled about these things. I made with_zero
and with_one
irreducible recently because it stopped the simplifier simplifying x : with_zero X
to x : option X
, something which is sometimes a great idea but sometimes not so great (it's not the correct path to go down if you want to actually use properties of zero which none
doesn't have).
Heather Macbeth (Sep 04 2020 at 19:05):
Reid, was your comment intended as something that is ready-to-go on current mathlib, or something that would be nice to add? I just tried taking it literally, by trying to write
import order.filter.at_top_bot
variables {α : Type*} [decidable_linear_order α]
open opposite
example : (order_dual α) → α := @unop α
but it seems that αᵒᵖ
and order_dual α
are not the same thing on current mathlib (I get "type mismatch, term unop
has type αᵒᵖ → α
but is expected to have type order_dual α → α
", unsurprisingly)
Reid Barton (Sep 04 2020 at 19:10):
Right, opposite
and order_dual
are not the same (though perhaps the opposite
for categories should unmerge somehow with the opposite
for *
, and merge with order_dual
instead).
Heather Macbeth (Sep 04 2020 at 19:18):
Do you happen to know if there is an analogue of the map op
in the order_dual
situation? I checked the library but didn't see it.
Reid Barton (Sep 04 2020 at 19:44):
I don't know--my guess is if you didn't find it then it doesn't exist.
Last updated: Dec 20 2023 at 11:08 UTC