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 x just sugar for converges top l x though?

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: Dec 20 2023 at 11:08 UTC