Zulip Chat Archive

Stream: new members

Topic: apply_instance for defs


Apurva Nakade (Jul 19 2020 at 15:45):

In the following code

import data.complex.basic
import linear_algebra.finite_dimensional
import tactic

universes u
variables {n : Type u} [fintype n]

instance hn_fd : finite_dimensional  (n  ) :=
begin
  apply_instance,
end

def V := (n  )

instance hn_fd' : finite_dimensional  V :=
begin
  apply_instance,
end

Apurva Nakade (Jul 19 2020 at 15:46):

The first instance works but the second gives an error

Apurva Nakade (Jul 19 2020 at 15:47):

Is def doing something more than just setting V definitionally equal to (n → ℂ)?

Johan Commelin (Jul 19 2020 at 15:47):

delta V, apply_instance

Johan Commelin (Jul 19 2020 at 15:48):

You need to tell Lean to "open the box" and look inside the definition. That's what the delta does.

Apurva Nakade (Jul 19 2020 at 15:49):

I tried this

instance hn_fd' : finite_dimensional  V :=
begin
  delta V, --similar error with unfold
  apply_instance,
end

but I'm still getting

tactic.mk_instance failed to generate instance for
  finite_dimensional  (?m_1  )
state:
 finite_dimensional  (?m_1  )

Apurva Nakade (Jul 19 2020 at 15:50):

looks like Lean is forgetting that n is fintype

Sebastien Gouezel (Jul 19 2020 at 15:54):

If I copy your code block, I get an error even earlier, in the statement of the lemma. Do you also get it, and do you understand what it means?

Apurva Nakade (Jul 19 2020 at 16:00):

Ah, I totally missed that, thanks! This is what I'm seeing

don't know how to synthesize placeholder
context:
 Type ?

Apurva Nakade (Jul 19 2020 at 16:01):

I think Lean is unable to infer what n is

Apurva Nakade (Jul 19 2020 at 16:05):

This is very interesting. I thought that using variables {n : Type u} [fintype n] will pass n as an implicit variable to all the definitions and theorems in the namespace. I don't think I know how to fix this.

Bryan Gin-ge Chen (Jul 19 2020 at 16:07):

Maybe you need to use include n?

Apurva Nakade (Jul 19 2020 at 16:09):

Still getting error in the statement of the lemma :(

Apurva Nakade (Jul 19 2020 at 16:09):

Although the error has slightly changed now

don't know how to synthesize placeholder
context:
n : Type u,
_inst_1 : fintype n
 Type ?

Reid Barton (Jul 19 2020 at 16:09):

It basically just means {n : Type u} [fintype n] is implictly in all your definitions (actually, only the ones which mention n).

Reid Barton (Jul 19 2020 at 16:10):

This isn't what you want, for the reason you are discovering.

Apurva Nakade (Jul 19 2020 at 16:13):

I honestly don't know what to do. My guess is that def V := (n → ℂ) is not the right way to ask Lean to treat V as a placeholder for (n → ℂ)

Reid Barton (Jul 19 2020 at 16:14):

variables (n : Type u) is the easiest

Apurva Nakade (Jul 19 2020 at 16:16):

This is giving me

type mismatch at application
  finite_dimensional  V
term
  V
has type
  Π (n : Type ?) [_inst_1 : fintype n], Type ? : Type (max (?+1) ? (?+1) 1)
but is expected to have type
  Type ? : Type (?+1)

Wow, this is turning out to be more complicated than I expected!

Bryan Gin-ge Chen (Jul 19 2020 at 16:17):

This is because V now requires an explicit argument for n.

Bryan Gin-ge Chen (Jul 19 2020 at 16:18):

instance hn_fd' : finite_dimensional  (V n) :=
begin
  apply_instance,
end

Now Lean complains that it can't find an add_comm_group instance on V n.

Apurva Nakade (Jul 19 2020 at 16:25):

Hmm... it seems to me that Lean does not like hiding the variable n in V.
For now, I'll just stick to using (n → ℂ) everywhere.
I'm a bit sad though that there is no straightforward way in Lean to simply rename a term like (n → ℂ)

Apurva Nakade (Jul 19 2020 at 16:28):

Although, in math, it is common to write statements like "In this section, we will let V decode ℂ^n." It would be good to know what the Lean variant of this is.

Reid Barton (Jul 19 2020 at 16:29):

parameter, but I wouldn't recommend using it unless you first know how to use variable

Reid Barton (Jul 19 2020 at 16:29):

You would still need to copy the instances you want anyways.

Reid Barton (Jul 19 2020 at 16:30):

Another option is local notation.

Apurva Nakade (Jul 19 2020 at 16:32):

Yess! This works, thanks so much!!

Yakov Pechersky (Jul 19 2020 at 16:33):

What's the issue with using delta? That's the Lean variant you asked for. When we say that V will encode, delta is the decoding step.

Yakov Pechersky (Jul 19 2020 at 16:33):

Although local notation is very easy too.

Apurva Nakade (Jul 19 2020 at 16:33):

delta did not work

Apurva Nakade (Jul 19 2020 at 16:33):

there was an error in the theorem statement itself

Bryan Gin-ge Chen (Jul 19 2020 at 16:36):

Well, this works, but this is worse than just using n → ℂ everywhere:

def V := (n  )

instance hn_fd' : @finite_dimensional  (V n) _ (by { delta V, apply_instance }) (by { delta V, apply_instance }) :=
begin
  delta V,
  apply_instance,
end

Yakov Pechersky (Jul 19 2020 at 16:36):

def V n :=...

Reid Barton (Jul 19 2020 at 16:42):

@[derive add_comm_group, derive (vector_space ), derive (finite_dimensional )]
def V (n : Type u) [fintype n] := (n  )

I don't know if it's possible to get [fintype n] on only the finite_dimensional instance

Reid Barton (Jul 19 2020 at 16:42):

or to avoid repeating derive

Rob Lewis (Jul 19 2020 at 16:50):

Reid Barton said:

or to avoid repeating derive

This yes, @[derive [..., ...]]. The other probably not.

Bryan Gin-ge Chen (Jul 19 2020 at 16:50):

We should really have a doc entry on derive here. Does anyone want to volunteer?

Bryan Gin-ge Chen (Jul 19 2020 at 17:03):

(I'll do it if someone gives me some pointers on how it works...)

Utensil Song (Jul 27 2020 at 06:35):

I also wonder how derive works. Some search (by git blaming the related tests) got me leanprover-community/mathlib#1475 then this Zulip chat and https://github.com/leanprover-community/lean/blob/master/library/init/meta/derive.lean .

I can't immediately tell how it works (from the source), only knowing that there's such a mechanism to register derive handlers and there're a few such handlers available in mathlib, each targeting a specific scenario.

By a few I mean two of them (found by searching derive_handler: inhabited_instance and delta_instance) and they seem to be well documented by themselves, it's just not easy for anyone to find the doc by just seeing @[derive ...].

P.S. Is it possible to make VSCode display the doc when hover @[derive ...] or make it clickable? I don't know where's related code in VSCode plugin.

Bryan Gin-ge Chen (Jul 27 2020 at 06:39):

Utensil Song said:

P.S. Is it possible to make VSCode display the doc when hover @[derive ...] or make it clickable? I don't know where's related code in VSCode plugin.

Most likely not without making changes to Lean itself. I don't know how hard it would be.

Utensil Song (Jul 27 2020 at 07:33):

Seems possible to address the hover part by modifying https://github.com/leanprover/vscode-lean/blob/master/src/hover.ts by manually write some doc in json and provide them to hover. To avoid becoming out of sync with the source, it could be just a link to an HTML doc generated from Lean /Mathlib. This would be enough for most users I guess.

As for the clickable part, modifying https://github.com/leanprover/vscode-lean/blob/master/src/definition.ts with the same naive manual approach would not work since the location has to be provided by Lean language server and there's no such an API to literal specify the symbol (out of context) to locate.

Bryan Gin-ge Chen (Jul 27 2020 at 07:39):

I think it'd be better overall to have the Lean server return the doc string and location from the attribute declaration. That would allow Emacs users to view such docstrings as well.

Utensil Song (Jul 27 2020 at 07:43):

Sure.

Utensil Song (Jul 28 2020 at 03:32):

#mwe

import algebra.category.Module.monoidal
import algebra.category.CommRing.basic

import tactic.delta_instance

open category_theory

variables {C : Type*} [category C] [monoidal_category C]

def tensor_power (X : C) :   C
| 0 := 𝟙_ C
| (n+1) := X  tensor_power n

example {R : CommRing} (M : Module R) : Module R := tensor_power M 17

-- And if you want to do this with unbundled objects:

universes u

variables (R : Type u) [comm_ring R] (M : Type u) [add_comm_group M] [module R M]

def foo : Type u :=
  (tensor_power (Module.of R M) 17 : Module R)

-- WORKS
-- instance : add_comm_group (foo R M) := by { delta foo, apply_instance, }
-- instance : module R (foo R M) := by { delta foo, apply_instance, }

-- WORKS
-- instance : add_comm_group (foo R M) := by delta_instance foo
-- instance : module R (foo R M) :=  by delta_instance foo

namespace foo

/-
tactic.mk_instance failed to generate instance for
  add_comm_group (foo R M)
-/
@[derive add_comm_group]
def to_add_comm_group := foo R M

/-
failed to synthesize type class instance for
R : Type u,
_inst_3 : comm_ring R,
M : Type u,
_inst_4 : add_comm_group M,
_inst_5 : module R M
⊢ add_comm_group (to_module R M)
-/
@[derive module R]
def to_module := foo R M

end foo

Utensil Song (Jul 28 2020 at 03:33):

I don't understand why derive doesn't work here.

Utensil Song (Jul 28 2020 at 03:34):

https://github.com/leanprover-community/mathlib/blob/master/src/linear_algebra/dual.lean#L39 is similar but works:

@[derive [add_comm_group, module R]] def dual := M [R] R

Scott Morrison (Jul 28 2020 at 04:04):

This doesn't work because derive only unfolds the current definition (i.e. to_add_comm_group in your example). It would need to _also_ unfold foo before it could find the instance.

Scott Morrison (Jul 28 2020 at 04:04):

If you put another @[derive] on foo it should work.

Utensil Song (Jul 28 2020 at 04:13):

Oh, moving derive to where foo is defined works:

@[derive [add_comm_group, module R]]
def foo : Type u :=
  (tensor_power (Module.of R M) 17 : Module R)

Utensil Song (Jul 28 2020 at 04:14):

So does attribute [derive [add_comm_group, module R]] foo


Last updated: Dec 20 2023 at 11:08 UTC