Zulip Chat Archive
Stream: general
Topic: I dont know what to do with universe constraints
deepest recursion (May 27 2025 at 12:06):
Hello! Ive put together a tiny piece of code for whichlean says it cant do its universe level stuff. Could someone please take a look?
Andrew Yang (May 27 2025 at 12:10):
I will advise against Sort _ and instead declare universe u and write Sort u and at some point you will find out where things went differently from your mental model.
Andrew Yang (May 27 2025 at 12:11):
In particular you might discover that the output universe of Either (you can see it by #print Either) might not be what you imagined.
deepest recursion (May 28 2025 at 00:45):
Ive #printed the Either and it was shown to be Either.{u_1, u_2} (A : Sort u_1) (B : Sort u_2) : Sort (max (max 1 u_1) u_2). I read it as for any instatiation of the Either with arbitrarty types the resulting level should be the greates of two and + 1 because lean wants it for some reason
I cant figure out this one tho
inductive Either (A:Sort _) (B:Sort _) where
| inl (_:A)
| inr (_:B)
inductive U : Sort _ -> Sort _ where
| either (A:Sort _)(B:Sort _) (_:U A) (_: U B) : U (Either A B)
| pair (A B:Sort _)(_:U A) (_: U B): U (PProd A B)
| empty : U PEmpty
| unit : U PUnit
universe l3
def Closed /-{l3}-/ (F:Sort l1 -> Sort l2):Sort ((max l1 (max l2 (max l3 1)))) := ∀ (T:Sort l3), (U T) -> (F T)
Any salvation for this one?
I see the levels as a hindrance tbh. Is there a way to disable em?
Andrew Yang (May 28 2025 at 01:31):
If you don't want to deal with these issues then I suggest you use Type u everywhere for a fixed universe, or even just stick with Type.
Andrew Yang (May 28 2025 at 01:37):
This is what you get if you fill in all the underscores with the right universes:
universe u₁ u₂ u u'
inductive Either (A : Sort u₁) (B : Sort u₂) : Sort (max 1 u₁ u₂) where
| inl (_:A)
| inr (_:B)
inductive U : Sort (max 1 u) -> Type (max 1 u) where
| either (A B : Sort (max 1 u)) (_ : U A) (_ : U B) : U (Either A B)
| pair (A B : Sort (max 1 u)) (_ : U A) (_ : U B): U (PProd A B)
| empty : U PEmpty
| unit : U PUnit
def Closed (F: Sort (max 1 u) -> Sort u') := ∀ T, (U T) -> (F T)
Andrew Yang (May 28 2025 at 01:38):
Or you can just stick in one universe:
inductive Either (A : Type u) (B : Type u) : Type u where
| inl (_:A)
| inr (_:B)
inductive U : Type u -> Type (u + 1) where
| either (A : Type u) (B : Type u) (_ : U A) (_ : U B) : U (Either A B)
| pair (A B : Type u) (_ : U A) (_ : U B): U (PProd A B)
| empty : U PEmpty
| unit : U PUnit
def Closed (F: Type u -> Type u) := ∀ T, (U T) -> (F T)
deepest recursion (May 28 2025 at 04:00):
I ve tried your solution with Sorts and it still trips lean in the same way as my original code. The second piece with Type works, although Ive tweaked one piece a bit.
def Closed (F: Sort _ -> Sort _) := ∀ T, (U T) -> (F T)
example : Closed (fun T => (a b:List T) -> a = b) := by
admit
This universe stuff is still confusing.
Thanks for writing this out, anyhow.
Andrew Yang (May 28 2025 at 04:34):
I think you should work with Type instead of Sort.
Kevin Buzzard (May 28 2025 at 04:55):
The max 1 u in your original code means "Lean is telling you that the output is a Type and not a Sort" and your examples of PEmpty and PUnit are types so why not just use types? The max 1 u isn't "adding 1" as you say, it's more accurate to say it's "turning the output into a type".
Kevin Buzzard (May 28 2025 at 04:58):
If you look at docs#Sum for example, which is core Lean's way of doing Either, it uses types.
Last updated: Dec 20 2025 at 21:32 UTC