Zulip Chat Archive

Stream: general

Topic: dependent argument hell


Scott Morrison (Sep 12 2018 at 01:19):

I seem to have backed myself into a corner, and I don't understand how to escape. I would really appreciate some help, as it feels like this problem is an instance of one that will become more and more severe as we do more advanced maths.

Scott Morrison (Sep 12 2018 at 01:19):

I've been working on morphisms of presheaves.

Scott Morrison (Sep 12 2018 at 01:19):

These are "bundled" presheaves, so they consist of a topological space, along with a functor from the category of open sets (morphisms are subsets) to some other category.

Scott Morrison (Sep 12 2018 at 01:20):

A morphism of presheaves (X, O_X) \hom (Y, O_Y) consists of a pair: a function f : X \hom Y, which is just a continuous map, and

Scott Morrison (Sep 12 2018 at 01:21):

a "comorphism", which is a natural transformation from O_Y \to f_* O_X.

Scott Morrison (Sep 12 2018 at 01:22):

The point here is that you can push forward a presheaf on X to presheaf on Y, along a continuous map (take an open set of Y, pull it back via f, then evaluate the presheaf on it).

Scott Morrison (Sep 12 2018 at 01:26):

Now, I want to define the identity presheaf morphism, and I want to define compositions of presheaf morphisms, and check they satisfy the right properties.

Scott Morrison (Sep 12 2018 at 01:26):

Yesterday I managed to do this, but both the constructions and the proofs were very ugly.

Scott Morrison (Sep 12 2018 at 01:27):

Today I've made another attempt, where the constructions are quite a bit better, and the proofs look like they should be easy but get stuck at the last hurdle, when we should just be cancelling off identity morphisms and saying we're done.

Scott Morrison (Sep 12 2018 at 01:28):

The code is at <https://github.com/semorrison/lean-category-theory/blob/master/src/category_theory/V_pre.lean>.

Scott Morrison (Sep 12 2018 at 01:29):

The particular problem I reach is the proof of comp_id' in constructing instance : category (Presheaf.{u v} C) := ....

Scott Morrison (Sep 12 2018 at 01:30):

Just before the sorry, the goal is

C : Type u,
๐’ž : category C,
X Y : Presheaf C,
f : Presheaf_hom X Y,
X_1 : open_set ((Y.X).ฮฑ)
โŠข functor.map (Y.๐’ช) (๐Ÿ™ X_1) โ‰ซ
      โ‡‘(f.c) (โ‡‘(map_open_set (๐Ÿ™ (Y.X))) X_1) โ‰ซ
        functor.map (X.๐’ช) (functor.map (map_open_set (f.f)) (๐Ÿ™ (โ‡‘(map_open_set (๐Ÿ™ (Y.X))) X_1))) =
    โ‡‘(f.c) X_1

Scott Morrison (Sep 12 2018 at 01:31):

And this should be perfectly manageable. The left hand side is a composition of three morphisms, and we should begin by observing the first and third are actually identity morphisms, since they are explicitly some functor applied to some identity morphism.

Scott Morrison (Sep 12 2018 at 01:31):

In particular we should be able to rewrite functor.map (Y.๐’ช) (๐Ÿ™ X_1) into ๐Ÿ™ (Y.๐’ช X_1)

Scott Morrison (Sep 12 2018 at 01:32):

However simp fails.

Reid Barton (Sep 12 2018 at 01:32):

Yeah I've had this happen too. In that case the problem was some implicit argument was not X_1 but only something defeq to it, and simp didn't like that.

Reid Barton (Sep 12 2018 at 01:32):

In my case dsimp, simp worked, but it doesn't look like that will help you judging from the two preceding lines

Scott Morrison (Sep 12 2018 at 01:32):

Trying the rewrite by hand, with increasing desperation:

rw [category_theory.functor.map_id]
rw [category_theory.functor.map_id Y.๐’ช X_1]

Scott Morrison (Sep 12 2018 at 01:33):

rw [category_theory.functor.map_id Y.๐’ช X_1] {md:=semireducible}

Scott Morrison (Sep 12 2018 at 01:33):

all fail.

Reid Barton (Sep 12 2018 at 01:33):

erw?

Scott Morrison (Sep 12 2018 at 01:33):

erw is just the same as {md:=semireducible}

Scott Morrison (Sep 12 2018 at 01:33):

(I'd usually use erw but didn't want to scare anyone. :-)

Scott Morrison (Sep 12 2018 at 01:34):

Reid is exactly right that the problem is an implicit argument.

Scott Morrison (Sep 12 2018 at 01:34):

Let's look at that, turning on set_option pp.implict true and inspecting the goal again.

Scott Morrison (Sep 12 2018 at 01:35):

The whole thing is a bit long, but the bit that corresponds to functor.map (Y.๐’ช) (๐Ÿ™ X_1) is

@functor.map
        (@open_set (@bundled.ฮฑ topological_space (@Presheaf.X C ๐’ž Y))
           (examples.topological_space (@Presheaf.X C ๐’ž Y)))
        (@open_set.open_sets (@bundled.ฮฑ topological_space (@Presheaf.X C ๐’ž Y))
           (examples.topological_space (@Presheaf.X C ๐’ž Y)))
        C
        ๐’ž
        (@Presheaf.๐’ช C ๐’ž Y)
        X_1
        (โ‡‘(@map_open_set (@Presheaf.X C ๐’ž Y) (@Presheaf.X C ๐’ž Y) (๐Ÿ™ (@Presheaf.X C ๐’ž Y))) X_1)
        (๐Ÿ™ X_1)

Scott Morrison (Sep 12 2018 at 01:36):

We can see the problem at the end there: the last three arguments are meant to consist of two objects, and a hom between them.

Scott Morrison (Sep 12 2018 at 01:36):

However we've got X_1, (โ‡‘(@map_open_set (@Presheaf.X C ๐’ž Y) (@Presheaf.X C ๐’ž Y) (๐Ÿ™ (@Presheaf.X C ๐’ž Y))) X_1), and (๐Ÿ™ X_1).

Reid Barton (Sep 12 2018 at 01:37):

Something like id โปยน' X_1, I guess?

Scott Morrison (Sep 12 2018 at 01:37):

We really want that second object to just be X_1 again.

Reid Barton (Sep 12 2018 at 01:37):

is what that long thing is

Scott Morrison (Sep 12 2018 at 01:37):

If we dsimp [map_open_set] we see:

Scott Morrison (Sep 12 2018 at 01:39):

(@open_set.mk (@bundled.ฮฑ topological_space (@Presheaf.X C ๐’ž Y)) (examples.topological_space (@Presheaf.X C ๐’ž Y)) (@subtype.val (@bundled.ฮฑ topological_space (@Presheaf.X C ๐’ž Y) โ†’ @bundled.ฮฑ topological_space (@Presheaf.X C ๐’ž Y)) (@continuous (@bundled.ฮฑ topological_space (@Presheaf.X C ๐’ž Y)) (@bundled.ฮฑ topological_space (@Presheaf.X C ๐’ž Y)) (@bundled.str topological_space (@Presheaf.X C ๐’ž Y)) (@bundled.str topological_space (@Presheaf.X C ๐’ž Y))) (๐Ÿ™ (@Presheaf.X C ๐’ž Y)) โปยน' @open_set.s (@bundled.ฮฑ topological_space (@Presheaf.X C ๐’ž Y)) (examples.topological_space (@Presheaf.X C ๐’ž Y)) X_1) _)

Scott Morrison (Sep 12 2018 at 01:40):

Which sadly is not definitely equal to X_1, although we can prove it is equal.

Reid Barton (Sep 12 2018 at 01:40):

oh no

Scott Morrison (Sep 12 2018 at 01:40):

In fact, we have a lemma prepared just for this!

Reid Barton (Sep 12 2018 at 01:40):

wait then

Scott Morrison (Sep 12 2018 at 01:40):

@[simp] def map_open_set_id_obj (X : Top) (U : open_set X.ฮฑ) : map_open_set (๐Ÿ™ X) U = U :=
begin dsimp [map_open_set], cases U, congr, end

Scott Morrison (Sep 12 2018 at 01:41):

And rw [map_open_set_id_obj] says ...

Scott Morrison (Sep 12 2018 at 01:41):

failed

Reid Barton (Sep 12 2018 at 01:41):

I'm confused

Reid Barton (Sep 12 2018 at 01:41):

Doesn't this mean your goal is ill-typed?

Scott Morrison (Sep 12 2018 at 01:41):

(And erw is no better, nor does it seem that using conv to zoom in on it helps.)

Scott Morrison (Sep 12 2018 at 01:42):

That's what appears to be happening, I agree.

Scott Morrison (Sep 12 2018 at 01:42):

So how did Lean let me get this far?

Reid Barton (Sep 12 2018 at 01:42):

I had that happen too once, but I didn't understand how it happened, but it's almost certainly unrelated.

Scott Morrison (Sep 12 2018 at 01:43):

I do have a note a few lines earlier in my code It's hard to believe this typechecks!

Scott Morrison (Sep 12 2018 at 01:44):

structure Presheaf_hom (F G : Presheaf.{u v} C) :=
(f : F.X โŸถ G.X)
(c : G.๐’ช โŸน ((map_open_set f) โ‹™ F.๐’ช))

namespace Presheaf_hom
def id (F : Presheaf.{u v} C) : Presheaf_hom F F :=
{ f := ๐Ÿ™ F.X,
  c := begin apply nat_trans.vcomp, swap, apply whisker_on_right (map_open_set_id _).inv, apply (functor.id_comp _ _ _).inv end
}

def comp {F G H : Presheaf.{u v} C} (ฮฑ : Presheaf_hom F G) (ฮฒ : Presheaf_hom G H) : Presheaf_hom F H :=
{ f := ฮฑ.f โ‰ซ ฮฒ.f,
  c := ฮฒ.c โŠŸ (whisker_on_left (map_open_set ฮฒ.f) ฮฑ.c), -- It's hard to believe this typechecks!
}
end Presheaf_hom

Scott Morrison (Sep 12 2018 at 01:44):

In particular, I have to jump through some hoops to construct the natural transformation for id.

Scott Morrison (Sep 12 2018 at 01:45):

But Lean appears to be happy with me just writing the "obvious" answer for comp.

Reid Barton (Sep 12 2018 at 01:45):

I found composition/associativity things are often easier than identity/unitality things

Scott Morrison (Sep 12 2018 at 01:46):

(... in real life as well as Lean, for me!)

Scott Morrison (Sep 12 2018 at 01:46):

(identities are strange and confusing in higher dimensions!)

Reid Barton (Sep 12 2018 at 01:49):

how hard would it be to find the first place the goal becomes ill-typed?
Is the goal before the last simp comprehensible?

Scott Morrison (Sep 12 2018 at 01:49):

The only avenues I can work out are:
1) Go back and work out where this "ill-typed, or at least hard-to-see-its-well-typed" expression first appears, and then "do something different".
2) Work out how to "fix" implicit arguments.

Scott Morrison (Sep 12 2018 at 01:50):

(This is an example, by the way, of a situation it would be nice to have a good term inspector, where you can toggle on and off implicit arguments for subtrees.)

Reid Barton (Sep 12 2018 at 01:52):

Given that the implicit argument is not even defeq to the right thing, I think 2 isn't applicable in this case.
It looks to me like you hit a bug in Lean (which is probably not in the kernel, since it is only the goal which is ill-typed, but still very frustrating).

Scott Morrison (Sep 12 2018 at 01:53):

Oooh, I maybe found a way around it.

Scott Morrison (Sep 12 2018 at 01:53):

It's just a matter of dsimping expressions in a different order, so somehow it's not at all a principled solution.

Scott Morrison (Sep 12 2018 at 01:54):

Oh, no, the problem is there a step or two later. I was just doing something by hand that simp was doing anyway.

Scott Morrison (Sep 12 2018 at 01:54):

:-(

Reid Barton (Sep 12 2018 at 01:58):

I'm kind of surprised that the result of the tactic passes typechecking, even with sorry there

Scott Morrison (Sep 12 2018 at 02:00):

Shall I try for a proof of false? :-)

Reid Barton (Sep 12 2018 at 02:01):

Unfortunately I doubt you can prove false from a term which is ill-typed but only in that one of the type arguments is definitionally wrong (but propositionally correct)

Scott Morrison (Sep 12 2018 at 02:01):

Okay... this is bizarre, but cases X_1 seems to break the impasse.

Reid Barton (Sep 12 2018 at 02:01):

that's not surprising

Scott Morrison (Sep 12 2018 at 02:01):

Why is that?

Reid Barton (Sep 12 2018 at 02:02):

same reason why you used cases U to prove map_open_set_id_obj

Reid Barton (Sep 12 2018 at 02:02):

basically you have an equality that looks like <x.1, _> = x

Scott Morrison (Sep 12 2018 at 02:02):

Okay, and there's a (horrible) proof:

  comp_id' := ฮป X Y f, --sorry,
    begin
      ext,
      -- we check the functions first
      dsimp [Presheaf_hom.id, Presheaf_hom.comp],
      simp,
      -- and now the comorphisms
      dsimp [Presheaf_hom.id, Presheaf_hom.comp],
      simp,
      ext,
      dsimp [whisker_on_right, whiskering_on_right, whisker_on_left, whiskering_on_left],
      dsimp [map_open_set],
      simp,
      erw [category_theory.functor.map_id],
      simp,
      cases X_1,
      simp,
      apply congr_fun,
      simp,
    end,

Reid Barton (Sep 12 2018 at 02:03):

where x is a variable, and so they can never be definitionally equal. Buf after cases x, it's okay

Scott Morrison (Sep 12 2018 at 02:03):

I see.

Reid Barton (Sep 12 2018 at 02:03):

when you do comp, both sides look like <_, _>

Reid Barton (Sep 12 2018 at 02:03):

and that's why comp is easier

Reid Barton (Sep 12 2018 at 02:04):

This still feels weird to me, but I've seen it a few times

Scott Morrison (Sep 12 2018 at 02:04):

So maybe the summary from today is:

avoid cases when constructing stuff, because then you'll have horrible X.rec expressions to deal with later, but
remember to try cases when an implicit argument looks wrong!

Reid Barton (Sep 12 2018 at 02:06):

Well, in general when you need to prove (blah.mk _ _) = X, it will require doing cases on X

Reid Barton (Sep 12 2018 at 02:06):

I still think something very fishy is going on with your original code

Scott Morrison (Sep 12 2018 at 02:07):

Sure. The problem here was that it wasn't at all obvious to me that this was what was going on.

Mario Carneiro (Sep 12 2018 at 02:09):

The file you linked references category_theory.examples.topological_spaces but I can't find it in the repo

Scott Morrison (Sep 12 2018 at 02:09):

That's in mathlib

Scott Morrison (Sep 12 2018 at 02:09):

:-)

Reid Barton (Sep 12 2018 at 02:10):

I just finished building your repo locally so I can take a look

Scott Morrison (Sep 12 2018 at 02:10):

And just to confound you, Mario, lean-category-theory is currently pointing at a branch of mathlib on community, in which that file has been modified. :-)

Reid Barton (Sep 12 2018 at 02:11):

Anyways the situation you were in ought to have been impossible. If x : t and x : t' then t and t' should be definitionally equal. Not just propositionally equal.

Reid Barton (Sep 12 2018 at 02:11):

At least, as far as I understand.

Scott Morrison (Sep 12 2018 at 02:11):

yes.

Mario Carneiro (Sep 12 2018 at 02:11):

oh wow, mathlib category theory has grown quite a bit since I last checked

Mario Carneiro (Sep 12 2018 at 02:17):

-- Do I dare define `open_set` as a functor from Top to CAT? I don't like CAT.

def map_open_set
  {X Y : Top} (f : X โŸถ Y) : open_set Y.ฮฑ โฅค open_set X.ฮฑ :=

Why is it a functor to CAT? It looks like open_set should be a (contravariant) functor from Top to Type

Scott Morrison (Sep 12 2018 at 02:18):

For each topological space X, we get the category of open sets and inclusions.

Reid Barton (Sep 12 2018 at 02:18):

The ill-typed goal I encountered involved Lean getting confused about the difference between quot and quotient, and so I had a goal involving some types of the form quot s a where s was a setoid, which I had trouble producing

Mario Carneiro (Sep 12 2018 at 02:21):

Okay, I think I'm starting to piece this together. There is an unnamed function comap f U (where f is a bundled continuous function and U is an open_set) which is the object part of map_open_set

Mario Carneiro (Sep 12 2018 at 02:21):

And what is true is that map_open_set (๐Ÿ™ X) U = comap (๐Ÿ™ X) U, which is isomorphic to U

Mario Carneiro (Sep 12 2018 at 02:22):

so you have a classic two-category problem

Scott Morrison (Sep 12 2018 at 02:23):

I don't know this classic. :-)

Reid Barton (Sep 12 2018 at 02:23):

I think Mario means 2-category?

Mario Carneiro (Sep 12 2018 at 02:23):

You have to worry about coherences since it's not an equality

Scott Morrison (Sep 12 2018 at 02:24):

Oh, okay! :-)

Scott Morrison (Sep 12 2018 at 02:24):

Yes.

Reid Barton (Sep 12 2018 at 02:24):

Like, the Top -> Cat thing could be only a pseudofunctor

Mario Carneiro (Sep 12 2018 at 02:24):

As Kevin learned a while ago, a propositional equality should not ever be treated as equality in a category, only isomorphism

Mario Carneiro (Sep 12 2018 at 02:24):

objects are either defeq or isomorphic

Scott Morrison (Sep 12 2018 at 02:24):

but where am I abusing that here?

Mario Carneiro (Sep 12 2018 at 02:25):

-- These next two are desperate attempts to solve problems below.
@[simp] def map_open_set_id_obj (X : Top) (U : open_set X.ฮฑ) : map_open_set (๐Ÿ™ X) U = U :=
begin dsimp [map_open_set], cases U, congr, end
@[simp] def map_open_set_id (X : Top) : map_open_set (๐Ÿ™ X) โ‰… functor.id (open_set X.ฮฑ) :=

this is bad news

Mario Carneiro (Sep 12 2018 at 02:25):

this equality should be turned into an iso, given a name, and explicitly reasoned with

Scott Morrison (Sep 12 2018 at 02:25):

It's the first one that is evil

Scott Morrison (Sep 12 2018 at 02:25):

and I don't use it

Scott Morrison (Sep 12 2018 at 02:26):

the second one is fine, isn't it?

Reid Barton (Sep 12 2018 at 02:27):

the type looks fine, but now I am confused about the implementation

Mario Carneiro (Sep 12 2018 at 02:27):

I think? I can't parse it

Scott Morrison (Sep 12 2018 at 02:27):

I just pushed an update

Mario Carneiro (Sep 12 2018 at 02:27):

map_open_set (๐Ÿ™ X) is a functor, so what does โ‰… mean here?

Scott Morrison (Sep 12 2018 at 02:27):

that has the working proof, and doesn't have the evil map_open_set_id_obj

Scott Morrison (Sep 12 2018 at 02:28):

iso is automatically natural isomorphism

Scott Morrison (Sep 12 2018 at 02:28):

sweet sweet typeclass magic finds the category of functors between two fixed categories

Reid Barton (Sep 12 2018 at 02:28):

isomorphism in the functor category

Scott Morrison (Sep 12 2018 at 02:28):

and correctly interprets iso

Mario Carneiro (Sep 12 2018 at 02:28):

and that doesn't have any 2-category mess in it?

Scott Morrison (Sep 12 2018 at 02:29):

no -- for a fixed pair of categories C and D

Scott Morrison (Sep 12 2018 at 02:29):

functors and natural transformations between them are a perfectly honest 1-category

Scott Morrison (Sep 12 2018 at 02:29):

(indeed, the prototypical example)

Reid Barton (Sep 12 2018 at 02:32):

Oh man this is confusing.

Mario Carneiro (Sep 12 2018 at 02:32):

so where did you get that bad application from? functor.map (Y.๐’ช) (๐Ÿ™ X_1)

Reid Barton (Sep 12 2018 at 02:32):

I noticed that both of these worked, and was confused.

  { app := ฮป U, show map_open_set (๐Ÿ™ X) U โŸถ U, from ๐Ÿ™ U },
  { app := ฮป U, show U โŸถ U, from ๐Ÿ™ U },

Reid Barton (Sep 12 2018 at 02:33):

Even though we know map_open_set (๐Ÿ™ X) U = U is not a definitional equality

Mario Carneiro (Sep 12 2018 at 02:33):

hah, it's because the hom destructs it

Reid Barton (Sep 12 2018 at 02:33):

right

Scott Morrison (Sep 12 2018 at 02:33):

Yeah, and I think this is where the "bad" application is coming from.

Scott Morrison (Sep 12 2018 at 02:34):

Can you explain what "the hom destructs it" means?

Reid Barton (Sep 12 2018 at 02:35):

instance : has_subset (open_set ฮฑ) :=
{ subset := ฮป U V, U.s โŠ† V.s }

Reid Barton (Sep 12 2018 at 02:35):

this is what defines the partial order, and therefore the hom types

Scott Morrison (Sep 12 2018 at 02:35):

oh ...

Reid Barton (Sep 12 2018 at 02:36):

it's not true that map_open_set (๐Ÿ™ X) U = U definitionally, but it is true that (map_open_set (๐Ÿ™ X) U).s = U.s because (contrary to my initial guess) preimage id is definitionally the identity

Scott Morrison (Sep 12 2018 at 02:36):

I see.

Reid Barton (Sep 12 2018 at 02:36):

Oh, wait...

Reid Barton (Sep 12 2018 at 02:37):

So maybe that weird goal was correctly typed, after all

Scott Morrison (Sep 12 2018 at 02:37):

Yeah.

Scott Morrison (Sep 12 2018 at 02:37):

And I could have replaced my evil lemma with

Scott Morrison (Sep 12 2018 at 02:38):

@[simp] def map_open_set_id_obj (X : Top) (U : open_set X.ฮฑ) : (map_open_set (๐Ÿ™ X) U).s = U.s := rfl

Scott Morrison (Sep 12 2018 at 02:38):

and perhaps had it work...

Scott Morrison (Sep 12 2018 at 02:39):

Hmm,. you can indeed prove that via rfl, but I can't get it to help.

Scott Morrison (Sep 12 2018 at 02:40):

ah, I have to remove the dsimp [map_open_set], perhaps

Mario Carneiro (Sep 12 2018 at 02:40):

Scott, I'm trying to get your repo. How do you update everything with leanpkg?

Scott Morrison (Sep 12 2018 at 02:40):

leanpkg build?

Scott Morrison (Sep 12 2018 at 02:40):

It should notice if you don't have the right dependencies already in _target.

Mario Carneiro (Sep 12 2018 at 02:41):

I get version mismatch error

Scott Morrison (Sep 12 2018 at 02:41):

ah... Is your lean provided by elan?

Scott Morrison (Sep 12 2018 at 02:41):

This repo is set to use nightly-2018-06-21

Scott Morrison (Sep 12 2018 at 02:41):

but I think it should be safe to change that in leanpkg.toml file

Scott Morrison (Sep 12 2018 at 02:42):

What is the "official recommendation" these days?

Mario Carneiro (Sep 12 2018 at 02:42):

I've been using 3.4.1 even though a few bugfixes have come in

Scott Morrison (Sep 12 2018 at 02:43):

Since my student Keeley started forking Lean I've switched to using elan and don't notice these problems. :-)

Mario Carneiro (Sep 12 2018 at 02:43):

that's good to hear. You should write a tutorial :)

Reid Barton (Sep 12 2018 at 02:44):

for elan?

Scott Morrison (Sep 12 2018 at 02:44):

I really should borrow a windows machine, and write a tutorial for running elan on windows.

Scott Morrison (Sep 12 2018 at 02:49):

Ducking out for lunch. Thanks very much for the discussion today!

Mario Carneiro (Sep 12 2018 at 02:53):

Aha, I found some 2-categoricity:

structure Presheaf_hom (F G : Presheaf.{u v} C) :=
(f : F.X โŸถ G.X)
(c : G.๐’ช โŸน ((map_open_set f) โ‹™ F.๐’ช))

Since Presheaf_hom has a component which is a functor, proving equality of homs is going to involve equality of objects

Mario Carneiro (Sep 12 2018 at 02:59):

I guess that can't really be avoided, but since G.๐’ช is a functor out of a skeletal category (a partial order category), it suffices to prove isomorphism instead of equality

Mario Carneiro (Sep 12 2018 at 03:02):

@[extensionality] lemma ext {F G : Presheaf.{u v} C} (ฮฑ ฮฒ : Presheaf_hom F G)
  (w : ฮฑ.f = ฮฒ.f) (h : ฮฑ.c == ฮฒ.c)
  : ฮฑ = ฮฒ :=

the heq here is evil. You should state some kind of composite equality here

Scott Morrison (Sep 12 2018 at 03:11):

Hi @Mario Carneiro, actually that component Preasheaf_hom.c is a natural transformation, not a functor, so equality is non-evil.

Scott Morrison (Sep 12 2018 at 03:12):

I agree that the ext lemma is evil. I will replace that.

Mario Carneiro (Sep 12 2018 at 03:12):

equality of natural transformations is not evil, equality of natural transformations in different categories is

Scott Morrison (Sep 12 2018 at 03:12):

Oh, so you're saying specifically the heq is evil.

Scott Morrison (Sep 12 2018 at 03:13):

I don't think we'll ever to to say anything about equalities of objects, however.

Mario Carneiro (Sep 12 2018 at 03:15):

I think I found the culprit. map_open_sets is a 2-categorical thing, since it takes homs to functors. This means that congruence says that equality of homs maps to natural iso of functors

Mario Carneiro (Sep 12 2018 at 03:15):

And this is the iso you should reference in the definition of ext

Scott Morrison (Sep 12 2018 at 03:15):

I'm filling in

def map_open_set_iso {X Y : Top} (f g : X โŸถ Y) (h : f = g) : map_open_set f โ‰… map_open_set g := {

}

Scott Morrison (Sep 12 2018 at 03:15):

right now

Kevin Buzzard (Sep 12 2018 at 06:37):

This is a terrifying thread to wake up to. It reminds me of when I couldn't prove anything about real numbers because there was no norm_num. But instead of a beginner struggling to prove math-trivial things because of a lack of tools, it's experts and tool-makers having problems with something that looks math-trivial

Kevin Buzzard (Sep 12 2018 at 06:44):

I actually stopped thinking about pushing the perfectoid repo forward towards the definition of an adic space because this funky category showed up, Patrick was doing completions (which were also needed) and I knew someone had to do integral closures (which were also needed) so I went back to those and thought I'd wait a bit to see what the category experts thought about this category V_pre which had shown up "in the wild". I want to argue that we don't need V_pre, it's just a convenient container and I thought it would be a good test case. I could instead just make a new structure modelling the objects and muddle on from there and it would no doubt be fine at least as far as the ultimate goal is concerned, which is a definition.

Mario Carneiro (Sep 12 2018 at 06:48):

I think this thread is Scott having an epiphany similar to the one that prompted that blog post https://mathematicswithoutapologies.wordpress.com/2018/09/11/guest-post-by-kevin-buzzard/

Mario Carneiro (Sep 12 2018 at 06:49):

I think it boils down to "equalities of types are evil"

Kevin Buzzard (Sep 12 2018 at 07:57):

As I'm sure you realise, that comment (it was only supposed to be a comment!) was very much informed by the comments you made when I was having that big meltdown about equality a few months ago ("Kevin, stop trolling!").

Kevin Buzzard (Sep 12 2018 at 08:01):

A summer student, Ned Summers, was doing some 4th year category theory example sheet questions (using Scott's library as a dependency) and ran into these sorts of problems, and this time I was better equipped. Chris (who freely admits he knows nothing about category theory) had suggested some casts which had caused trouble for Ned, and I diagnosed the problem as exactly the same sort of thing: Ned had two objects X and Y and a proof that they were equal, and was doing exactly what a mathematican would do -- treating Hom(X,Z) as equal to Hom(Y,Z) etc etc. Equality in type theory is more delicate than that. Of course this doesn't change the fact that we are right, and your definition is rubbish -- but it's what we've got to work with ;-)

Kenny Lau (Sep 12 2018 at 08:01):

A summer student, Ned Summers

Kevin Buzzard (Sep 12 2018 at 08:02):

They've almost all gone now. Ned stopped on Friday. Only about three left. I am going to spend all day writing documentation and basic questions. Yesterday I said "we want ten basic examples and ten basic questions about metaprogramming" -- today I'm (hopefully) going to write ten basic examples and ten basic questions about set membership.

Kevin Buzzard (Sep 12 2018 at 08:04):

I asked a question on this chat probably last Wed or Thurs about how to generate "the identity morphism" between two objects which were provably equal, and Reid answered very quickly with some function called something like iso_of_eq which generated the data from the proof; it was because of my schemes meltdown that I had understood that this was what was missing.

Chris Hughes (Sep 12 2018 at 08:57):

I didn't suggest the use of eq.rec. My instinct would be that eq.rec for data should be avoided if at all possible

Kevin Buzzard (Sep 12 2018 at 09:55):

Maybe I got the wrong impression from Ned :-)

Scott Morrison (Sep 12 2018 at 12:16):

Thanks to some help from Mario and Reid, it is well sorted out now!

Scott Morrison (Sep 12 2018 at 12:18):

While I agree that I was making mistakes (being "evil") when I shouldn't have been, and the code is nicer as a result of today's exorcism, the fundamental cause of being stuck was something a bit different. I really need to catch up on sleep now, so I won't explain it now. :-)

Scott Morrison (Sep 12 2018 at 12:19):

The upshot is that <https://github.com/semorrison/lean-category-theory/blob/master/src/category_theory/presheaves.lean> contains the definition of bundled presheaves (i.e. a topological space and a presheaf on it), and the right notion of morphisms between these, and indeed the category structure.

Scott Morrison (Sep 12 2018 at 12:19):

It's certainly not all of V_pre, but it's the categorical theoretic core.

Patrick Massot (Sep 12 2018 at 12:19):

Yeah, "Lean does no magic" โ„ข but sometimes a good exorcism session is needed

Scott Morrison (Sep 12 2018 at 12:20):

Hopefully from this point on it is just adding bells and whistles (that stalk needs to be local, these valuations need to be jiggered by the whatsit).

Scott Morrison (Sep 12 2018 at 12:21):

Happily, the category of presheaves is actually pretty easy to PR now. I only have one dependency, about whiskering, and that looks easy to clean up. So this may be in mathlib soon.

Kenny Lau (Sep 12 2018 at 19:12):

to reduce an eq.rec you need the major premise to become refl somehow

that usually means finding the appropriate equality in the context and generalizing it until one side is a variable, and then subst, which is to say use eq.rec in the proof term

Mario Carneiro, 16/04/2018 04:39:04 (UTC)

Kenny Lau (Sep 12 2018 at 19:13):

underrated comment

Kenny Lau (Sep 12 2018 at 20:45):

wow I had an eq.rec in my goal and it took me nearly 2 hours to destruct it

Reid Barton (Sep 12 2018 at 21:32):

sounds about right

Scott Morrison (Sep 13 2018 at 01:39):

I feel like eq.rec is such a disaster that we need special VS Code plugin support: a little zulip box that pops up, with a message: "Help me, Mario!" ready to be sent...

Kenny Lau (Sep 13 2018 at 07:16):

ok so eq.rec isn't really the problem. The problem is sometimes you can't just rewrite something with an equality a = b because that something depends on a and b being those expressions. And the solution is to generalize a in all places in which that expression occurs, and then subst that equality

Kenny Lau (Sep 13 2018 at 07:17):

sometimes you can't just generalize a, but you have to generalize a lot of things

Kenny Lau (Sep 13 2018 at 07:17):

a strategy is to generalize all proofs first (set_option pp.proofs true), because that will always work because of proof irrelevance

Scott Morrison (Sep 14 2018 at 12:11):

Slowly making progress here. This now compiles:

def stalks_local (F : Presheaf.{u+1 u} TopRing) : Type u :=
ฮ  x : F, local_ring (((TopRing.forget_to_CommRing).map_presheaf F).stalk_at x)

def V_pre_pre := ฮฃ (F : Presheaf.{u+1 u} TopRing), stalks_local F

example : category.{u+1 u} V_pre_pre := by unfold V_pre_pre; apply_instance

Last updated: Dec 20 2023 at 11:08 UTC