Zulip Chat Archive

Stream: new members

Topic: Defining instances using several implicit arguments


Jakob Scholbach (Mar 05 2021 at 22:43):

Another newbie syntax question: why does this not work (the definition of the class does work, but the instance does not, it says failed to synthesize type class instance for.... If I omit the parts [q : ℕ] [char_p F q] (both in the class and the instance), it does work.

import data.polynomial.basic
import algebra.char_p
import field_theory.separable

class my_has_separable_contraction (F : Type) [field F] [q : ] [char_p F q]
  (f : polynomial F) : Prop :=
  (has_separable_contraction' [] :  m : ,  g : polynomial F,
  g.separable  polynomial.expand F (3^m) g = f)

instance my_irreducible_has_separable_contraction
  (F : Type) [field F] [q : ] [char_p F q]
  (f : polynomial F) (irred : irreducible f) (fn : f  0):
  my_has_separable_contraction F f :=
begin
  sorry
end

Adam Topaz (Mar 05 2021 at 22:46):

What are your imports?

Adam Topaz (Mar 05 2021 at 22:48):

Oh, you need to use (q : \nat)

Adam Topaz (Mar 05 2021 at 22:48):

But I can't know for sure without a #mwe

Jakob Scholbach (Mar 05 2021 at 22:49):

yes, sorry, I forgot to include the imports.

Adam Topaz (Mar 05 2021 at 22:49):

import data.polynomial.basic
import algebra.char_p
import field_theory.separable

class my_has_separable_contraction (F : Type) [field F] (q : ) [char_p F q]
  (f : polynomial F) : Prop :=
  (has_separable_contraction' [] :  m : ,  g : polynomial F,
  g.separable  polynomial.expand F (3^m) g = f)

instance my_irreducible_has_separable_contraction
  (F : Type) [field F] (q : ) [char_p F q]
  (f : polynomial F) (irred : irreducible f) (fn : f  0):
  my_has_separable_contraction F q f :=
begin
  sorry
end

Adam Topaz (Mar 05 2021 at 22:49):

[ .. ] is only used for classes.

Jakob Scholbach (Mar 05 2021 at 22:50):

OK -- is it possible to leave the q implicit by other means?

Adam Topaz (Mar 05 2021 at 22:50):

yeah, one sec.

Alex J. Best (Mar 05 2021 at 22:50):

Use {} instead

Jakob Scholbach (Mar 05 2021 at 22:50):

{ q : \N } ?

Adam Topaz (Mar 05 2021 at 22:51):

but he wants the field to have characteristic q

Adam Topaz (Mar 05 2021 at 22:51):

I would do this:

import data.polynomial.basic
import algebra.char_p
import field_theory.separable

class my_has_separable_contraction (F : Type) [field F] (f : polynomial F) : Prop :=
  (has_separable_contraction' [] :  (q : ) [char_p F q],  m : ,  g : polynomial F,
  g.separable  polynomial.expand F (3^m) g = f)

instance my_irreducible_has_separable_contraction
  (F : Type) [field F] (f : polynomial F) (irred : irreducible f) (fn : f  0):
  my_has_separable_contraction F  f :=
begin
  sorry
end

Jakob Scholbach (Mar 05 2021 at 22:52):

OK, what is the general rule? If I use { q ... } I cannot refer to it in any later [...] ?

import data.polynomial.basic
import algebra.char_p
import field_theory.separable

class my_has_separable_contraction (F : Type) [field F] {q : } [char_p F q]
  (f : polynomial F) : Prop :=
  (has_separable_contraction' [] :  m : ,  g : polynomial F,
  g.separable  polynomial.expand F (3^m) g = f)

instance my_irreducible_has_separable_contraction
  (F : Type) [field F] {q : } [char_p F q]
  (f : polynomial F) (irred : irreducible f) (fn : f  0):
  my_has_separable_contraction F f :=
begin
  sorry
end

does not work, with the same error message.

Adam Topaz (Mar 05 2021 at 22:53):

What's the name of the function which returns the characteristic of a ring?

Jakob Scholbach (Mar 05 2021 at 22:53):

char_ring

Jakob Scholbach (Mar 05 2021 at 22:54):

I believe

Adam Topaz (Mar 05 2021 at 22:54):

Wait, q doesn't appear at all after the : in your class, right?

Adam Topaz (Mar 05 2021 at 22:54):

Why do you need it at all?

Jakob Scholbach (Mar 05 2021 at 22:56):

Oh, for the purpose of testing I replaced q^m by 3^m. Sorry about this glitch in posting it, but I do need it in the definition of the class.

Adam Topaz (Mar 05 2021 at 22:56):

Oh I see.

Adam Topaz (Mar 05 2021 at 22:56):

So you could do something like this:

import data.polynomial.basic
import algebra.char_p
import field_theory.separable

class my_has_separable_contraction (F : Type) [field F] (f : polynomial F) : Prop :=
  (has_separable_contraction' [] :  m : ,  g : polynomial F,
  g.separable  polynomial.expand F ((ring_char F)^m) g = f)

instance my_irreducible_has_separable_contraction
  (F : Type) [field F] (f : polynomial F) (irred : irreducible f) (fn : f  0):
  my_has_separable_contraction F f :=
begin
  sorry
end

Adam Topaz (Mar 05 2021 at 22:57):

Note this works;

example {F : Type*} [field F] : char_p F (ring_char F) := by apply_instance

Adam Topaz (Mar 05 2021 at 22:58):

Which means that the typeclass system will automatically know that F has characteristic ring_char F (as it should be!)

Jakob Scholbach (Mar 05 2021 at 23:00):

OK, I see, thanks. This works in this special case; for the purpose of having a mwe, I also simplified the code in another respect. I have defined a class exp_char F p (which otherwise is identical to char_p, but it is about the exponential characteristic). I guess I could also adapt the definition of ring_char to this situation and produce a function like ring_exp_char. This would allow me to use your solution. But is there no other general smooth way of invoking [some_class some_structure some_natural_number] without this detour (or the detour with the forall q : that you also kindly suggested)?

Adam Topaz (Mar 05 2021 at 23:02):

The other option is to make q explicit, meaning that your class says "This is a polynomial which is a contraction of a separable polynomial, but you are only allowed to use it for fields of characteristic qq".

Adam Topaz (Mar 05 2021 at 23:02):

I.e. the class itself will depend on qq.

Jakob Scholbach (Mar 05 2021 at 23:04):

Yes, but it feels (to me newbie!) somehow unnatural: I leave the existence & assumption (concerning the characteristic) on the field implicit, but need to explicitly feed in the natural number.

Adam Topaz (Mar 05 2021 at 23:05):

Well, it's a theorem that a field has a unique characteristic :)

Jakob Scholbach (Mar 05 2021 at 23:08):

Yes, sure, I won't argue with you on that! :) , and of course all your solutions do work. Just to understand it also in general, let me ask one last time: is it not possible to have implicit assumptions involving an implicitly present natural number?

Adam Topaz (Mar 05 2021 at 23:09):

Oh, it's certainly possible in cases where lean can infer what that natural number must be from context.

Adam Topaz (Mar 05 2021 at 23:12):

The issue is that lean had no way of inferring what qq was supposed to be in my_has_separable_contraction, just because you declare [char_p F q as an assumption for my_irreducible_has_separable_contraction. That's the point I was trying to make above -- you can perfectly legally write
{F : Type} [field F] [char_p F 5] [char_p F 3]

Adam Topaz (Mar 05 2021 at 23:12):

How would lean know whether the characteristic of FF is 33 or 55?

Adam Topaz (Mar 05 2021 at 23:13):

(of course you can prove false with these assumptions, but that's another point altogether.)

Jakob Scholbach (Mar 05 2021 at 23:14):

OK, I understand your point. In some sense I would like to put [q : \N] both in the class, and also in the instance (prior to the char_p, so that this clause does know about the q). If I understand you correctly, the (only?) thing that makes this fail is the fact that a number is not a structure, so I guess I would like to find a syntax that overcome this hurdle.

Adam Topaz (Mar 05 2021 at 23:15):

Not quite. It's the fact that a number is not a typeclass. Typeclasses are things like field, ring, etc.

Adam Topaz (Mar 05 2021 at 23:15):

You can very well have a class that's a plain proposition (just like the one you made).

Jakob Scholbach (Mar 05 2021 at 23:16):

OK, yes. So: can I turn a number into a typeclass (and otherwise keep its nature as is)?

Adam Topaz (Mar 05 2021 at 23:17):

And you can make a class that is just a number, like this:

class foo :=
(n : )

example [foo] :  := foo.n

Adam Topaz (Mar 05 2021 at 23:18):

This is a bit silly, but you can do this:

import algebra.char_p

class foo := (n : )

class bar (F : Type*) [field F] [foo] extends char_p F foo.n

example {F : Type*} [field F] [foo] [bar F] : char_p F foo.n := by apply_instance

Jakob Scholbach (Mar 05 2021 at 23:21):

OK, I see. Thank you very much for your advice -- I appreciate it! Just to record it for later readers: this solution would read like so:

import data.polynomial.basic
import algebra.char_p
import field_theory.separable

class foo :=
(n : )

class my_has_separable_contraction (F : Type) [field F] [foo] [char_p F foo.n]
  (f : polynomial F) : Prop :=
  (has_separable_contraction' [] :  m : ,  g : polynomial F,
  g.separable  polynomial.expand F (foo.n^m) g = f)

instance my_irreducible_has_separable_contraction
  (F : Type) [field F] [foo] [char_p F foo.n]
  (f : polynomial F) (irred : irreducible f) (fn : f  0):
  my_has_separable_contraction F f :=
begin
  sorry
end

Adam Topaz (Mar 06 2021 at 00:49):

Maybe it's worth mentioning that such a hack should not be done in practice.


Last updated: Dec 20 2023 at 11:08 UTC