Zulip Chat Archive

Stream: metaprogramming / tactics

Topic: Specializing function at unknown point (and univese issues)


Calle Sönne (Aug 22 2024 at 09:59):

I have a term of type ∀ ..., η = θ, where the ... is an unknown amount of arguments. I want to specialize this function at a specific argument, but I don't know in general at what point this argument appears. However, I should be able to find it by analysing the equality η = θ. Here is my specific situation: the equality η = θ will be an equality of 2-morphisms in some bicategory B. This bicategory B will be an argument to the function, and I want to specialize B to the bicategory Cat. However, there may be multiple bicategories appearing as arguments to the function, so I have to find B by looking at the equality η = θ. Here is an example of a type for which I want to do this:

( {B : Type u₁} [inst : Bicategory B] {C : Type u₂} [inst_1 : Bicategory C] (F : Pseudofunctor B C) {a b c d : B}
    (f : a  b) (g : b  c) (h : c  d),
    (F.mapComp f (g  h)).hom  F.map f  (F.mapComp g h).hom =
      F.map₂ (α_ f g h).inv 
        (F.mapComp (f  g) h).hom  (F.mapComp f g).hom  F.map h  (α_ (F.map f) (F.map g) (F.map h)).hom)

In this case I want to specialize C to Cat(which is where the equality is taking place).

I have almost managed to do this, modulo some universe issues which I would like help with. I am also new to metaprogramming, so I am also happy to receive suggestions for completely different approaches to this problem.

To do this specialization I have been using forallMetaTelescope (and then I construct my new, specialized, term using mkLambdaFVars at the end). Say my original term was called e, then I write:

let (args, _, conclusion)  forallMetaTelescope ( inferType e)

After this, I have successfully extracted the metavariable I want to specialize to Cat (I called it CAT) and assigned it Cat using Qq in the following way:

let u  Meta.mkFreshLevelMVar
let v  Meta.mkFreshLevelMVar
CAT.assign q(Cat.{v, u})

I also specialize the bicategory instance [Bicategory B] to Bicategory.{max v u, max v u} Cat.{v u}.

I then update the list of metavariables args to obtain args2. This seems to replace C with Cat, just like I wanted. It also seems to correctly replace occurrences of C in the other types that depend on C by Cat (such as F in the example above). However, it does not seem to do this for universes. This is my problem. So in the example above, F gets updated to have type Pseudofunctor B Cat, but Pseudofunctor B Cat still says it has type Type (max (max (max (max (max u₁ u₂) v₁) v₂) w₁) w₂). Here u₂, v₂, w₂ appear, and they are the old universe parameter for C and [Bicategory C]. How would I go about updating these types so that they get the correct universes (depending on the new universe metavariables u and v)?

Jannis Limperg (Aug 22 2024 at 11:13):

Instead of doing this specialisation by hand, can you apply the expression of the given type to the correct arguments (here (B := Cat))? Then you can infer the type of the partially applied expression. This should correctly specialise everything.

Calle Sönne (Aug 22 2024 at 11:32):

What function would allow me to do this? In general I do not know that the argument will be called B, but I guess I could maybe use forallMetaTelescope to find the index of the argument, and then maybe there is some function which applies the expression with the nth argument being Cat?

Jannis Limperg (Aug 22 2024 at 12:12):

I was going to say docs#Lean.Meta.mkAppOptM or docs#Lean.Meta.mkAppOptM', but both of these try to infer all instance arguments, which may or may not be a problem for you. It would be possible to make a variant that doesn't do this, and maybe someone has already done this in Batteries or Mathlib.

Calle Sönne (Aug 23 2024 at 08:29):

I am trying to make this work now (but I also think that I will run into the instance issue later), but I am still stuck with a similar universe issue as before.

Now I still use forallMetaTelescope, I get my list of (metavariable) arguments, instantiate C to Cat.{v, u}, and [Bicategory C] to Bicategory.{max v u, max v u} Cat.{v u}. Here I still define u, v as

let u  Meta.mkFreshLevelMVar
let v  Meta.mkFreshLevelMVar

Then I replace all arguments still containing metavariables with none, so I get a list of arguments [none, .., Cat, Category Cat, none, ..., none].

Then I run into the issue that mkAppOptM' complains that Cat does not have the right Type when I try to apply the above list to the function (because of universes).

In the example from the original post it expects Cat to have type Type u₂, but it has type Type ... where ... is some complicated expression involving the level metavariables u, v. Is there any way I can instantiate u, v so that this works (or specialize u₂ somehow)?

Calle Sönne (Aug 23 2024 at 08:34):

I guess one thing I don't quite understand is that when using forallMetaTelescope, it does not seem like the universes get turned into metavariables, so I am not sure how to deal with them.

Jannis Limperg (Aug 23 2024 at 10:07):

Could you make a branch with your code? Then I can take a closer look.

Calle Sönne (Aug 23 2024 at 10:20):

Thanks a lot! I have it on the branch tactic-toCat.

What I'm trying to do on that branch is to make an attribute which specializes a lemma as described above, then applies NatTrans.app to the equality and then simplifies it with some basic Cat lemmas. Everything is in Tactic/CategoryTheory/ToApp.lean, but I am testing the attribute in Tactic/CategoryTheory/TEST.lean (otherwise I am not sure how to get the exact right input). The function that I have been talking about above, and need help with, is to_appExpr. Also most of the code apart from to_appExpr is more or less copied from reassoc.

Let me know if you need to know anything else.

Jannis Limperg (Aug 23 2024 at 11:51):

I made some progress by replacing the theorem's original universe parameters with universe mvars. But now I need to stop procrastinating writing my paper. :sweat_smile:

Calle Sönne (Aug 23 2024 at 11:54):

Good luck with the paper, and thanks a lot already!!

Jannis Limperg (Aug 23 2024 at 11:58):

Thanks! I pushed a final commit just now that fixes a wrong refactoring.

Calle Sönne (Aug 23 2024 at 18:18):

Thanks a lot for the help again, I managed to get the attribute working now!

Jannis Limperg (Aug 26 2024 at 15:19):

Nice, very happy to hear that!


Last updated: May 02 2025 at 03:31 UTC