Zulip Chat Archive
Stream: new members
Topic: empty cone
Calle Sönne (Oct 23 2019 at 22:52):
I want to define the empty cone, given an object in a category C. I have tried to do as follows:
def empty_cone (X : C) : cone (functor.empty C) := { X := X, π := nat_trans (functor.empty C) ((functor.const pempty).obj X) }
by (trying to) mimic the way the constant functor is used in const.lean
I get the following error:
invalid field notation, type is not of the form (C ...) where C is a constant functor.const pempty has type Type ? → Type ?
If I remove the .obj X I instead get:
type mismatch at application nat_trans (functor.empty C) (functor.const pempty) term functor.const pempty has type Type ? → Type ? : Type (max (?+1) (?+1)) but is expected to have type pempty ⥤ C : Type (max v u) Additional information: /home/calle/lean/sheaves/src/zeroobject.lean:14:7: context: switched to simple application elaboration procedure because failed to use expected type to elaborate it, error message type mismatch, term nat_trans ?m_5 ?m_6 has type Type (max ? ?) : Type ((max ? ?)+1) but is expected to have type (functor.const pempty).obj X ⟶ functor.empty C : Type v
Reid Barton (Oct 23 2019 at 22:56):
π := nat_trans
is already wrong--π
needs to be a specific natural transformation, not the type of natural transformation between ... and ...
Is there something like nat_trans.empty
already? Otherwise, you can define it easily enough
Calle Sönne (Oct 23 2019 at 22:57):
I have not found anything like nat_trans.empty, so I will try to define it myself. Thank you.
Calle Sönne (Oct 23 2019 at 23:18):
Now that I have defined empty_trans I still get the same error:
def empty_cone (X : C) : cone (functor.empty C) := { X := X, π := empty_trans ((functor.const pempty).obj X) (functor.empty C) }
gives the error
invalid field notation, type is not of the form (C ...) where C is a constant functor.const pempty has type Type ? → Type ?
Im probably not referring to the constant functor correctly, I tried copying the way it was done in const.lean but apparently I am doing something wrong. Do I need to refer to C explictly somehow?
Calle Sönne (Oct 23 2019 at 23:19):
This is an example of how its used in const.lean:
@[simp] lemma obj_obj (X : C) (j : J) : ((const J).obj X).obj j = X := rfl
Reid Barton (Oct 23 2019 at 23:25):
oh
Reid Barton (Oct 23 2019 at 23:25):
You probably have category.functor.const
, not category_theory.functor.const
.
Reid Barton (Oct 23 2019 at 23:25):
It's super annoying.
Calle Sönne (Oct 23 2019 at 23:34):
Thank you! I think it works because now Im getting a different error, hopefully a somewhat easier one though.
Calle Sönne (Oct 23 2019 at 23:40):
What does this error mean?
type mismatch at application empty_trans ((functor.const pempty).obj X) term (functor.const pempty).obj X has type pempty ⥤ C : Type (max ? v ? u) but is expected to have type Type ? : Type (?+1) Additional information: /home/calle/lean/sheaves/src/zeroobject.lean:17:7: context: switched to simple application elaboration procedure because failed to use expected type to elaborate it, error message type mismatch, term empty_trans ?m_1 ?m_3 has type Π (G : pempty ⥤ ?m_1), nat_trans ?m_3 G : Type (max (max ? ? ? ?) ? ?) but is expected to have type (functor.const pempty).obj X ⟶ functor.empty C : Type v
This is my code:
def empty_trans (F G : pempty ⥤ C) : nat_trans F G := by tidy def empty_cone (X : C) : cone (functor.empty C) := { X := X, π := empty_trans ((category_theory.functor.const pempty).obj X) (functor.empty C) }
Calle Sönne (Oct 23 2019 at 23:41):
Why is it expecting Type ? : Type (?+1)? Is there some implicit argument to empty_trans that I am not providing?
Calle Sönne (Oct 23 2019 at 23:45):
I solved it, I just had to supply the category C to empty_trans as well
Kenny Lau (Oct 24 2019 at 00:09):
@Calle Sönne welcome back!
Kenny Lau (Oct 24 2019 at 00:18):
import category_theory.limits.cones category_theory.pempty universes v u namespace category_theory open limits variables {C : Type u} [𝒞 : category.{v} C] include 𝒞 def empty_trans {F G : pempty ⥤ C} : nat_trans F G := by tidy def empty_cone (X : C) : cone (functor.empty C) := { X := X, π := empty_trans } end category_theory
Scott Morrison (Oct 24 2019 at 01:29):
Looks like we should add these!
Calle Sönne (Oct 24 2019 at 07:31):
Thank you @Kenny Lau :)
Johan Commelin (Oct 24 2019 at 07:35):
Would it be safe to use clean
to clean up after tidy
in this case? I think it would be a lot of fun if we could use tactics for definitions.
Johan Commelin (Oct 24 2019 at 07:35):
@Kenny Lau Did you just define data using a tactic :rolling_on_the_floor_laughing: ?
Kenny Lau (Oct 24 2019 at 07:35):
I just copied his code for that part
Calle Sönne (Oct 24 2019 at 07:36):
In mathlib the empty functor is defined by tidy
Calle Sönne (Oct 24 2019 at 07:37):
def empty : pempty.{v+1} ⥤ C := by tidy
Kenny Lau (Oct 24 2019 at 07:38):
Kenny Lau Did you just define data using a tactic :rolling_on_the_floor_laughing: ?
when I tell people not to define data using a tactic, I always append "unless you know what you're doing" :P
Johan Commelin (Oct 24 2019 at 07:39):
Aah... I see what you're getting at (-;
Calle Sönne (Oct 24 2019 at 07:40):
Anyway I want to now define a zero object:
structure zero := (zero : C) (initial : is_limit (empty_cone zero) (terminal : is_colimit (empty_cocone zero)
but the line (initial : is_limit (empty_cone zero) gives the following error:
function expected at is_limit (empty_cone zero) term has type Type (max u ?)
I am still not that familiar with classes, structures etc. in lean, should this be a class instead (like has_terminal, has_initial)?
Kenny Lau (Oct 24 2019 at 07:42):
you're missing closing brackets
Calle Sönne (Oct 24 2019 at 07:52):
In terminal.lean they define terminal as:
class has_terminal := (has_limits_of_shape : has_limits_of_shape.{v} pempty C) ... abbreviation terminal [has_terminal.{v} C] : C := limit (functor.empty C)
Now using has_terminal makes it easy to say if any given category has a terminal object or not. Should I define a class has_zero similarly or is there a way to rephrase this using structures?
Johan Commelin (Oct 24 2019 at 07:54):
Isn't there a PR for zero object?
Johan Commelin (Oct 24 2019 at 07:54):
Maybe it's even merged already
Calle Sönne (Oct 24 2019 at 07:56):
I have not found anything, but it would be great if it exists. I want to eventually define an abelian category in lean
Johan Commelin (Oct 24 2019 at 07:59):
Have you talked with Scott?
Johan Commelin (Oct 24 2019 at 07:59):
https://github.com/leanprover-community/mathlib/pull/1445
Calle Sönne (Oct 24 2019 at 08:04):
No I have not talked with Scott, but this looks good! Kernels as well :o
Scott Morrison (Oct 24 2019 at 10:48):
I decided before I proceeded with zero objects and kernels I should go back and patch a few gaps in the API.
Scott Morrison (Oct 24 2019 at 10:50):
Particularly, for all the special shapes of limits a characterisation of an object being the limit, in the form \forall Y, (Y \hom X) \equiv ...
for an appropriate ...
.
Scott Morrison (Oct 24 2019 at 10:50):
And then actually proving a bunch of the basic lemmas about the shapes we have already.
Scott Morrison (Oct 24 2019 at 10:51):
e.g. equalisers are monomorphisms, equalisers are "commutative" and "associative", etc., etc., to test out the existing limits API a bit further. Reid is right to complain that there haven't been enough lemmas relative to definitions so far in category_theory/limits/shapes/
.
Calle Sönne (Oct 24 2019 at 11:22):
@Scott Morrison Is there anything you think I could help with?
Scott Morrison (Oct 24 2019 at 11:33):
@Calle Sönne, how about proving that equaliser f g \iso equaliser g f
, or that mono (equaliser.\iota f g)
?
In some sense the real problem is to explain what went wrong when you tried to implement your preferred pencil-and-paper proofs of these facts in Lean. The limits API still (...) needs work, and having people attempt to fill in some basic things like these and report back how it goes would be super useful.
Scott Morrison (Oct 24 2019 at 11:34):
(I have an idea of what I want to add to the limits API, which I think would make both of these questions easier, but I'm happy not to spoil it for you. :-)
Calle Sönne (Oct 24 2019 at 11:34):
Sounds good!
Calle Sönne (Oct 24 2019 at 12:42):
How do you use abbrevations? I have the following abbrevations:
abbreviation equalizer.ι : equalizer f g ⟶ X := limit.π (parallel_pair f g) zero @[simp, reassoc] lemma equalizer.condition : equalizer.ι f g ≫ f = equalizer.ι f g ≫ g := begin erw limit.w (parallel_pair f g) walking_parallel_pair_hom.left, erw limit.w (parallel_pair f g) walking_parallel_pair_hom.right end abbreviation equalizer.lift {W : C} (k : W ⟶ X) (h : k ≫ f = k ≫ g) : W ⟶ equalizer f g := limit.lift (parallel_pair f g) (fork.of_ι k h) end
I want to combine them as:
lean have H1 : equalizer f g ⟶ equalizer g f, exact ((equalizer g f).lift (equalizer f g).ι (equalizer f g).condition)
But this gives the error
invalid field notation, type is not of the form (C ...) where C is a constant limits.equalizer g f has type C
Johan Commelin (Oct 24 2019 at 12:48):
Unrelated: have
is for propositions. Your morphism is data, so you need let H1 : ...
Calle Sönne (Oct 24 2019 at 12:49):
Thank you
Johan Commelin (Oct 24 2019 at 12:50):
Next, (equalizer g f).lift
will try to see if (equalizer g f)
is a term of type equalizer _ _
Johan Commelin (Oct 24 2019 at 12:50):
But it is not.
Johan Commelin (Oct 24 2019 at 12:51):
So you should simply write equalizer.lift _ _
Calle Sönne (Oct 24 2019 at 12:58):
I see, thank you
Johan Commelin (Oct 24 2019 at 12:59):
Does it work now?
Calle Sönne (Oct 24 2019 at 13:08):
Yeah
Last updated: Dec 20 2023 at 11:08 UTC