Zulip Chat Archive
Stream: general
Topic: dot notation not working with top
Bernd Losert (Dec 17 2021 at 19:42):
I have the following:
import tactic
import order.filter.partial
noncomputable theory
open set filter classical
open_locale classical filter
open has_sup has_top
variable a : Type*
class convergence_space (a : Type*) :=
(converges : filter a -> a -> Prop)
open convergence_space
instance : has_top (convergence_space a) := {
top := {
converges := fun l x, l <= pure x,
}
}
def discrete_convergence_space (a : Type*) : convergence_space a := {
converges := fun l x, top.converges l x,
}
but I get an error error: invalid field notation, type is not of the form (C ...) where C is a constant. Even if I write converges top l x, I still get an error. In order to pacify Lean I have to write @converges a top l x. What is the problem here? Is it because top is not a "constant"?
Johan Commelin (Dec 17 2021 at 19:44):
Does it work if you write (⊤ : convergence_space a).converges?
Johan Commelin (Dec 17 2021 at 19:45):
Aah, (foo : convergence_space a) is not an explicit argument of convergence_space.convergence (You can #check it to see the type signature). So it will not work.
Bernd Losert (Dec 17 2021 at 19:47):
If I switch to a structure, then converges top l x works.
Bernd Losert (Dec 17 2021 at 19:48):
But top.converges still doesn't work.
Adam Topaz (Dec 17 2021 at 19:49):
Lean has no way of knowing the type of top just by itself
Adam Topaz (Dec 17 2021 at 19:55):
Many types have a has_top instance. Even better, in you case convergence_space A has a has_top instance for every A, so how should lean know what A is if you only write top.converges?
Adam Topaz (Dec 17 2021 at 19:56):
The reason converges top l x works is because lean is able to infer A from l and/or x.
Bernd Losert (Dec 17 2021 at 19:57):
Isn't top.converges l x just sugar for converges top l x though?
Bernd Losert (Dec 17 2021 at 19:57):
In my mind, they should behave the same since it's just syntax sugar.
Adam Topaz (Dec 17 2021 at 19:58):
import tactic
import order.filter.partial
noncomputable theory
open set filter classical
open_locale classical filter
open has_sup has_top
variable a : Type*
class convergence_space (a : Type*) :=
(converges : filter a -> a -> Prop)
open convergence_space
instance : has_top (convergence_space a) := {
top := {
converges := fun l x, l <= pure x,
}
}
def discrete_convergence_space (a : Type*) : convergence_space a := {
converges := fun l x, by letI : convergence_space a := ⊤; exact converges l x,
}
Adam Topaz (Dec 17 2021 at 19:59):
Take a look at the type of converges by using #check converges
Bernd Losert (Dec 17 2021 at 20:01):
I'm using structure convergence_space now and #check says converges : convergence_space ?M_1 → filter ?M_1 → ?M_1 → Prop.
Johan Commelin (Dec 17 2021 at 20:04):
Bernd Losert said:
Isn't
top.converges l xjust sugar forconverges top l xthough?
Too a first approximation X.converges l x is sugar for <the type of X>.converges X l x. (In fact, X doesn't need to be the first explicit argument, in general.)
Johan Commelin (Dec 17 2021 at 20:04):
So Lean needs to know the type of X before it can find the right declaration.
Johan Commelin (Dec 17 2021 at 20:05):
If you have definitions foo.quux and bar.quux, and you write X.quux, what does it mean? It depends on the type of X...
Johan Commelin (Dec 17 2021 at 20:06):
In theory, Lean cannot use l and x to figure this out, because it doesn't yet know to which declaration it is feeding them.
Bernd Losert (Dec 17 2021 at 20:11):
I guess this is another gotcha that I have to keep in mind. Thanks guys.
Last updated: May 02 2025 at 03:31 UTC