Zulip Chat Archive
Stream: general
Topic: Universe issues
Kevin Buzzard (Apr 06 2018 at 19:28):
I seem to not understand universes properly, or more precisely how to use them properly. I ran into the following issue with some code:
Kevin Buzzard (Apr 06 2018 at 19:28):
definition foo (X : Type*) := ∀ (β : Type*), true theorem baz (X : Type*) (bar: foo X) (β : Type*) : true := begin have H := bar β, -- error admit, end
Kevin Buzzard (Apr 06 2018 at 19:28):
The error was
Kevin Buzzard (Apr 06 2018 at 19:28):
type mismatch at application bar β term β has type Type u_3 : Type (u_3+1) but is expected to have type Type u_2 : Type (u_2+1) state: X : Type u_1, bar : foo X, β : Type u_3 ⊢ true
Kevin Buzzard (Apr 06 2018 at 19:29):
I figured I'd investigate more, so I next wrote this:
Kevin Buzzard (Apr 06 2018 at 19:30):
universes u v w x set_option pp.universes true definition foo' (X : Type u) := ∀ (β : Type v), true theorem baz' (X : Type w) (bar' : foo' X) (β : Type x) : true := begin have H := bar' β, -- error admit, end
Kevin Buzzard (Apr 06 2018 at 19:30):
and this time I got
Kevin Buzzard (Apr 06 2018 at 19:30):
type mismatch at application bar' β term β has type Type x : Type (x+1) but is expected to have type Type u_1 : Type (u_1+1) state: X : Type w, bar' : foo'.{w u_1} X, β : Type x ⊢ true
Kevin Buzzard (Apr 06 2018 at 19:31):
This made me realise that I didn't understand what was going on, because there is still this universe u_1
mentioned, even though I thought I'd just explicitly written down what universe everything was in.
Kevin Buzzard (Apr 06 2018 at 19:31):
In particular, bar'
seems to mention this universe u_1
and I'm not sure where this universe got involved.
Kevin Buzzard (Apr 06 2018 at 19:32):
Some experimentation led me to something which worked:
Kevin Buzzard (Apr 06 2018 at 19:32):
definition foo'' (X : Type u) := ∀ (β : Type u), true theorem baz'' (X : Type v) (bar'' : foo'' X) (β : Type v) : true := begin have H := bar'' β, -- works exact H end
Kevin Buzzard (Apr 06 2018 at 19:32):
i.e. "keep X and beta in the same universe and you'll be fine"
Kevin Buzzard (Apr 06 2018 at 19:32):
But this raises two questions for me:
Kevin Buzzard (Apr 06 2018 at 19:33):
1) why wasn't I fine before?
Kevin Buzzard (Apr 06 2018 at 19:33):
2) Will this fix cause me problems later?
Kevin Buzzard (Apr 06 2018 at 19:34):
In reality, X is a topological space and it is covered by open sets U i
where each i
has type beta
Kevin Buzzard (Apr 06 2018 at 19:34):
that is, U : beta -> set X
Kevin Buzzard (Apr 06 2018 at 19:36):
My instinct is always to just let everything live in different universes because who cares about universes anyway, that's the joy of type theory
Kevin Buzzard (Apr 06 2018 at 19:36):
In ZFC I would just let X and beta be in Type
Kevin Buzzard (Apr 06 2018 at 19:36):
but that might be a bridge too far
Mario Carneiro (Apr 06 2018 at 19:36):
When you defined foo
, it had two universe parameters, corresponding to the two Type*
instances
Kevin Buzzard (Apr 06 2018 at 19:37):
what does that even mean
Kevin Buzzard (Apr 06 2018 at 19:37):
foo is a thing
Kevin Buzzard (Apr 06 2018 at 19:37):
and it has a type
Kevin Buzzard (Apr 06 2018 at 19:37):
which lives in a universe
Mario Carneiro (Apr 06 2018 at 19:37):
it is universe polymorphic
Mario Carneiro (Apr 06 2018 at 19:38):
Think of it as being implicitly a forall over the universe variables
Mario Carneiro (Apr 06 2018 at 19:38):
except that lean has no universe variable binders, so it's all just free variables and substitution
Kevin Buzzard (Apr 06 2018 at 19:38):
foo'
mentions a universe I don't even see
Kevin Buzzard (Apr 06 2018 at 19:39):
or at least something mentions this universe
Mario Carneiro (Apr 06 2018 at 19:39):
foo
and foo'
are the same
Kevin Buzzard (Apr 06 2018 at 19:39):
wait
Kevin Buzzard (Apr 06 2018 at 19:39):
are they exactly the same?
Mario Carneiro (Apr 06 2018 at 19:39):
except foo'
is more explicit about the two universe variables, u
and v
Kevin Buzzard (Apr 06 2018 at 19:39):
Should I think that foo'
is really "for all universes u, ..."
Mario Carneiro (Apr 06 2018 at 19:39):
yes, they are exactly the same as far as lean is concerned
Mario Carneiro (Apr 06 2018 at 19:40):
yes. All universe polymorphic functions are like this
Kevin Buzzard (Apr 06 2018 at 19:40):
like when I make variables and then secretly I am writing "for all v..."
Mario Carneiro (Apr 06 2018 at 19:40):
exactly
Kevin Buzzard (Apr 06 2018 at 19:40):
But where is this u_1
coming from?
Kevin Buzzard (Apr 06 2018 at 19:40):
Didn't I name all my universes with foo'
?
Mario Carneiro (Apr 06 2018 at 19:41):
foo'
has two universe variables, named u
and v
in the definition, but since it's like a forall, whenever you use it these variables can be substituted for other things
Kevin Buzzard (Apr 06 2018 at 19:41):
gotcha
Kevin Buzzard (Apr 06 2018 at 19:42):
So foo'
is for all universes u and v, [what I wrote]
Kevin Buzzard (Apr 06 2018 at 19:42):
so why do I get a problem?
Kevin Buzzard (Apr 06 2018 at 19:42):
why can't we just do universe unification or something?
Mario Carneiro (Apr 06 2018 at 19:42):
u_1
is the name of a universe variable in baz'
, since you reference foo' X
which only fixes its first parameter by unification, lean invents a second variable u_1
so it becomes bar' : foo'.{w u_1} X
Kevin Buzzard (Apr 06 2018 at 19:43):
aah
Kevin Buzzard (Apr 06 2018 at 19:43):
yes I just independently realised this
Kevin Buzzard (Apr 06 2018 at 19:43):
But now bar'
should be "for all universes u_1, ..."
Mario Carneiro (Apr 06 2018 at 19:44):
it is
Mario Carneiro (Apr 06 2018 at 19:44):
bar'.{w x u_1}
has type forall (X : Type w) (bar' : foo'.{w u_1} X) (β : Type x), true
Mario Carneiro (Apr 06 2018 at 19:45):
And since u_1
and x
are separate universe variables being generalized, inside the proof you can't assume they are equal
Mario Carneiro (Apr 06 2018 at 19:45):
so bar' β
is a type error since bar'
accepts a Type u_1
Kevin Buzzard (Apr 06 2018 at 19:46):
OK so you have convinced me that the underlying way that universes work mean that my initial attempts should not work.
Kevin Buzzard (Apr 06 2018 at 19:46):
So now the question is should I try to re-arrange things to make them work?
Mario Carneiro (Apr 06 2018 at 19:47):
just write foo'.{w x}
instead of foo'
in the type of bar'
Kevin Buzzard (Apr 06 2018 at 19:47):
Or should I go down the "might bite me later and I have no understanding as to whether it will" route of letting all universes be u
Kevin Buzzard (Apr 06 2018 at 19:47):
aah, oh great, so I can do what I want to do.
Mario Carneiro (Apr 06 2018 at 19:48):
In general, I try to avoid types with "internal universe variables" like foo'
here, which has a forall whose universe is not constrained by the input parameters
Kevin Buzzard (Apr 06 2018 at 19:48):
definition foo' (X : Type u) := ∀ (β : Type v), true theorem baz' (X : Type w) (β : Type x) (bar' : foo'.{w x} X) : true := begin have H := bar' β, -- works :-) exact H, end
Kevin Buzzard (Apr 06 2018 at 19:48):
I need to think about the last thing you said
Mario Carneiro (Apr 06 2018 at 19:49):
that means to prefer def foo' (X : Type u) := ∀ (β : Type u), true
over def foo' (X : Type u) := ∀ (β : Type v), true
Kevin Buzzard (Apr 06 2018 at 19:49):
because this is a massively minimised thing and in reality I will have to decide whether I can try to avoid the thing you want me to avoid
Kevin Buzzard (Apr 06 2018 at 19:49):
Thanks a lot for the fix and the advice though.
Kevin Buzzard (Apr 06 2018 at 19:51):
How do I know whether the thing you prefer will be safe for me?
Kevin Buzzard (Apr 06 2018 at 19:51):
hmm, I need to go and feed children
Kevin Buzzard (Apr 06 2018 at 19:51):
thanks
Mario Carneiro (Apr 06 2018 at 19:54):
It is slightly less universe parametric (it requires that two variables be the same), so you may need extra ulift
s around, which may or may not be better than the often required .{w x}
stuff that arises with this approach
Mario Carneiro (Apr 06 2018 at 19:56):
Generally you will have to be "universe conscious" when working with definitions with internal universe variables - lots of things will require annotation. cardinal
, ordinal
, and Set
(the ZFC sets) are like this
Mario Carneiro (Apr 06 2018 at 19:56):
category
may also be, this exact thing was a point of discussion with Scott a few weeks ago
Kevin Buzzard (May 22 2018 at 20:14):
What is happening here:
Kevin Buzzard (May 22 2018 at 20:14):
universe u structure scheme := (β : Type u) theorem scheme_of_affine_scheme (R : Type u) : scheme := { β := R -- universe issue } /- type mismatch at field 'β' R has type Type u : Type (u+1) but is expected to have type Type u_1 : Type (u_1+1) -/
Kevin Buzzard (May 22 2018 at 20:14):
Seems to me that scheme has decided that it wants to live in a different universe to beta and R
Kevin Buzzard (May 22 2018 at 20:14):
oh
Kevin Buzzard (May 22 2018 at 20:14):
heh
Kevin Buzzard (May 22 2018 at 20:15):
ignore the irrelevant names
Kevin Buzzard (May 22 2018 at 20:15):
If I change theorem to definition, it works
Kevin Buzzard (May 22 2018 at 20:15):
And this works too:
Kevin Buzzard (May 22 2018 at 20:16):
theorem scheme_of_affine_scheme (R : Type u) : scheme.{u} := { β := R -- works }
Kevin Buzzard (May 22 2018 at 20:16):
OK so maybe the answer is simply "don't use theorem to define something which isn't a Prop"
Kevin Buzzard (May 22 2018 at 20:19):
definition scheme_of_affine_scheme (R : Type u) : scheme := { β := R -- works }
Kevin Buzzard (May 22 2018 at 20:19):
I guess I don't understand what's going on, but on the other hand I can see I was doing something dumb.
Chris Hughes (May 22 2018 at 20:22):
This gives some small insight.
set_option pp.universes true def scheme_of_affine_scheme (R : Type u) : scheme := begin -- R : Type u -- ⊢ scheme.{?l_1} end lemma scheme_of_affine_scheme (R : Type u) : scheme := begin -- R : Type u -- ⊢ scheme.{u_1} end
Kevin Buzzard (May 22 2018 at 20:28):
Aah so in the first case scheme is in some universe and Lean isn't too fussed, it will decide later
Kevin Buzzard (May 22 2018 at 20:28):
but in the second case Lean decided to go for it and make a decision
Kevin Buzzard (May 22 2018 at 20:28):
because it's a lemma so the universe is supposed to be Prop
Kevin Buzzard (May 22 2018 at 20:28):
and it wasn't Prop so Lean panicked
Chris Hughes (Jun 01 2018 at 08:52):
The lemma card_univ
below does not work without the .{u}
in the fintype
instance
import data.set.finite open set fintype universe u def equiv_univ (α : Type u) : α ≃ (set.univ : set α) := { to_fun := λ a, ⟨a, mem_univ _⟩, inv_fun := λ a, a.1, left_inv := λ a, rfl, right_inv := λ ⟨a, ha⟩, rfl } @[simp] lemma card_univ {α : Type u} [fintype α] [fintype.{u} (set.univ : set α)]: @fintype.card (set.univ : set α) _ = fintype.card α := eq.symm (@card_congr α (set.univ : set α) _ _ (equiv_univ α))
The following do not work.
set_option pp.universes true @[simp] lemma card_univ {α : Type u} [fintype α] [fintype (set.univ : set α)]: fintype.card (set.univ : set α) = fintype.card α := eq.symm (card_congr (equiv_univ α))
Gives the error
failed to synthesize type class instance for α : Type u, _inst_1 : fintype.{u} α, _inst_2 : fintype.{?l_1} ↥univ.{u} ⊢ fintype.{u} ↥univ.{u}
and
set_option pp.universes true @[simp] lemma card_univ {α : Type u} [fintype α] [f : fintype (set.univ : set α)]: @fintype.card (set.univ : set α) f = fintype.card α := eq.symm (@card_congr α (set.univ : set α) _ f (equiv_univ α))
Gives the error
type mismatch at application card_congr.{u u_1} (equiv_univ.{u} α) term equiv_univ.{u} α has type equiv.{u+1 (max 1 (u+1))} α (@coe_sort.{(max (u+1) 1) (max 1 (u+1))+1} (set.{u} α) (@set.has_coe_to_sort.{u} α) (@set.univ.{u} α)) : Type u but is expected to have type equiv.{u+1 u_1+1} α (@coe_sort.{(max (u+1) 1) (max 1 (u+1))+1} (set.{u} α) (@set.has_coe_to_sort.{u} α) (@set.univ.{u} α)) : Type (max (max u u_1) u_1 u)
What's going on here? And will the .{u}
in the fintype instance make the lemma more difficult to use. It worked in my application, but will it always work?
Gabriel Ebner (Jun 01 2018 at 09:01):
And will the .{u} in the fintype instance make the lemma more difficult to use.
No, not at all. It is the only possible choice, the elaborator just can't figure it out for whatever reason.
Gabriel Ebner (Jun 01 2018 at 09:03):
(The universe parameter .{u}
is always there, whether you write it explicitly or not.)
Last updated: Dec 20 2023 at 11:08 UTC