Zulip Chat Archive

Stream: new members

Topic: misunderstanding coe?


Alex Mathers (Mar 30 2020 at 18:04):

I currently have the following two lines of code

instance (R : Type*) [comm_ring R] {A : Type*} [comm_ring A] [algebra R A] : has_coe (subalgebra R A) (set A) := λ S, S.carrier
instance (R : Type*) [comm_ring R] {A : Type*} [comm_ring A] [algebra R A] (S : subalgebra R A) : is_subring S := S.subring

returning the error message

type mismatch at application
  is_subring S
term
  S
has type
  subalgebra R A : Type ?
but is expected to have type
  set ?m_1 : Type ?

am I misunderstanding how the coercion should be working?

Reid Barton (Mar 30 2020 at 18:20):

It doesn't know yet what S is supposed to be a subring of

Alex Mathers (Mar 30 2020 at 18:24):

How can I make it explicit? In the definition of is_subring the ambient ring is not explicit, i.e. it looks like

class is_subring {R : Type*} [ring R] (S : set R) extends is_add_subgroup S, is_submonoid S : Prop.

Reid Barton (Mar 30 2020 at 18:24):

I guess you could claim it should be able to infer it from the definition S.subring, but I think the coercion will not fire soon enough for that to work.

Reid Barton (Mar 30 2020 at 18:24):

Maybe is_subring (S : set A) for example.

Alex Mathers (Mar 30 2020 at 18:25):

I see. That fixes it!

Reid Barton (Mar 30 2020 at 18:25):

Just because you have written this first has_coe instance doesn't mean Lean has to use it.

Alex Mathers (Mar 30 2020 at 18:25):

is there a simple explanation of what Lean is doing for why it doesn't "use" it?

Reid Barton (Mar 30 2020 at 18:26):

It isn't doing anything because it has no way to know what the ?m_1 is in the error message.

Reid Barton (Mar 30 2020 at 18:28):

For example, someone else could add an instance : has_coe (subalgebra R A) (set R) (never mind that it would be nonsense) and then what do you expect to happen?

Alex Mathers (Mar 30 2020 at 18:29):

Ah, I see

Alex Mathers (Mar 30 2020 at 19:46):

I guess this is related to my previous question: my code

instance (R : Type*) [comm_ring R] {A : Type*} [integral_domain A] [algebra R A] :
integral_domain (integral_closure R A) := subring.domain ((integral_closure R A) : set A)

is giving the error message

failed to synthesize type class instance for
R : Type ?,
_inst_1 : comm_ring R,
A : Type ?,
_inst_2 : integral_domain A,
_inst_3 : algebra R A
⊢ is_subring (has_coe_t_aux.coe (set A) (has_coe_t_aux.coe (submodule R A) (integral_closure R A)))

while the code from the previous question is supposed to be giving the instance of (integral_closure R A) : subalgebra R A as a subring of A. How can I "remind" Lean that this does have an instance of is_subring?

Alex Mathers (Mar 30 2020 at 19:50):

also it seems from the error message that Lean isn't actually using the coercion I set up, rather I guess it's using the sequence of coercions subalgebra R A → submodule R A → set A. Is there a possibility that this is related to my issue?

Kevin Buzzard (Mar 30 2020 at 20:01):

What happens if you remove your coercion and then attempt to coerce anyway?

Kevin Buzzard (Mar 30 2020 at 20:02):

If it still works then you should trust that the people who set it up knew what they were doing and don't add the coercion

Alex Mathers (Mar 30 2020 at 20:02):

It has the same error message

Kevin Buzzard (Mar 30 2020 at 20:02):

Sure

Kevin Buzzard (Mar 30 2020 at 20:02):

But I'm asking just about whether the coercion succeeds

Kevin Buzzard (Mar 30 2020 at 20:03):

From subalgebra to set

Kevin Buzzard (Mar 30 2020 at 20:03):

My guess is that you shouldn't be creating that instance but this is not the answer to your problem

Kevin Buzzard (Mar 30 2020 at 20:05):

You should also see if the second instance is solved by by apply_instance

Kevin Buzzard (Mar 30 2020 at 20:05):

It would surprise me if there were important coercions which were not there already

Kevin Buzzard (Mar 30 2020 at 20:06):

The inbuilt coercions might have subtle priorities set, for example

Kevin Buzzard (Mar 30 2020 at 20:08):

And what happens if you just remove the explicit coercion to set A in your error? Mathlib might have solved all your problems already

Kevin Buzzard (Mar 30 2020 at 20:08):

I'll get to a computer and stop guessing in a sec

Kevin Buzzard (Mar 30 2020 at 20:21):

I'm still working out the imports :-(

Kevin Buzzard (Mar 30 2020 at 20:22):

I think we should have a bot which just flags all posted code which doesn't actually compile and either kicks the poster or suggests imports and opens which will fix it.

Kevin Buzzard (Mar 30 2020 at 20:24):

Right. This succeeds

import ring_theory.algebra ring_theory.subring

instance (R : Type*) [comm_ring R] {A : Type*} [comm_ring A] [algebra R A] :
has_coe (subalgebra R A) (set A) := by apply_instance

so don't add a new one.

Alex Mathers (Mar 30 2020 at 20:24):

sorry for the delay. These imports should be the necessary ones:

import ring_theory.integral_closure
import ring_theory.localization
import ring_theory.algebra
import ring_theory.subring

Patrick Massot (Mar 30 2020 at 20:24):

A more realistic idea would be to try someone who could write a web page explaining what is a MWE, so that we can paste a link to that web page each it's needed.

Kevin Buzzard (Mar 30 2020 at 20:25):

So do we not have bundled subrings?

Kevin Buzzard (Mar 30 2020 at 20:25):

Where are my undergraduates?

Alex Mathers (Mar 30 2020 at 20:27):

This is the only definition I see on the subring document:

class is_subring (S : set R) extends is_add_subgroup S, is_submonoid S : Prop.

Kevin Buzzard (Mar 30 2020 at 20:27):

Yeah, I think we don't have bundled subrings. Shame. I bet it would be easier with those.

Kevin Buzzard (Mar 30 2020 at 20:27):

And this doesn't work:

instance (R : Type*) [comm_ring R] {A : Type*} [integral_domain A] [algebra R A] :
integral_domain (integral_closure R A) := by apply_instance

Alex Mathers (Mar 30 2020 at 20:30):

Unfortunate :/

Kevin Buzzard (Mar 30 2020 at 20:32):

Did you see the Artin-Tate thread?

Alex Mathers (Mar 30 2020 at 20:32):

No I didn't

Kevin Buzzard (Mar 30 2020 at 20:32):

This whole algebra, subring thing drives me nuts

Alex Mathers (Mar 30 2020 at 20:33):

I saw a conversation about difficulties with "triangles" of rings in commutative algebra, not sure if that's the thread you mean but yeah it seems to be an annoying issue

Kevin Buzzard (Mar 30 2020 at 20:34):

import ring_theory.integral_closure
import ring_theory.localization
import ring_theory.algebra
import ring_theory.subring

instance foo (R : Type*) [comm_ring R] {A : Type*} [comm_ring A] [algebra R A] (S : subalgebra R A) :
  is_subring (S : set A) := S.subring

instance (R : Type*) [comm_ring R] {A : Type*} [integral_domain A] [algebra R A] :
integral_domain (integral_closure R A) := @subring.domain A _ _ (foo _ _)

works

Kevin Buzzard (Mar 30 2020 at 20:35):

i.e. I just feed it the things it can't find

Alex Mathers (Mar 30 2020 at 20:36):

Nice! what purpose does the @ character serve?

Kevin Buzzard (Mar 30 2020 at 20:36):

instance (R : Type*) [comm_ring R] {A : Type*} [integral_domain A] [algebra R A] :
integral_domain (integral_closure R A) := @subring.domain A _ (integral_closure R A) _

@ means "forget {} and [] and just tell me every input"

Alex Mathers (Mar 30 2020 at 20:37):

Ohh that makes sense

Kevin Buzzard (Mar 30 2020 at 20:37):

It's exactly the same problem as before. You want to prove integral_domain (integral_closure R A) and you want to use subring.domain.

#check @subring.domain
/-
subring.domain :
  Π {D : Type u_1} [_inst_3 : integral_domain D] (S : set D) [_inst_4 : is_subring S], integral_domain ↥S
-/

Kevin Buzzard (Mar 30 2020 at 20:39):

Lean asks you for S which is in your case some kind of coercion of integral_closure R A to a set, i.e. to a term of type set D for some D, but Lean doesn't have a clue what D is.

Kevin Buzzard (Mar 30 2020 at 20:39):

If it knew it had to find a coercion to set A it could do it (indeed, my second solution is doing just that).

Kevin Buzzard (Mar 30 2020 at 20:41):

But until you tell it it's looking for a coercion to set ?m_1 and it can't find one for some reason.

Alex Mathers (Mar 30 2020 at 20:42):

I see. so by using @ you are allowed to enter the first implicit argument A which I guess basically tells Lean that we are meant to consider integral_closure R A as an element of set A, then it finds the previously defined coercion to do this on its own

Kevin Buzzard (Mar 30 2020 at 20:45):

Exactly. And using my new toy

set_option trace.type_context.is_def_eq true
set_option trace.type_context.is_def_eq_detail true

instance (R : Type*) [comm_ring R] {A : Type*} [integral_domain A] [algebra R A] :
integral_domain (integral_closure R A) := subring.domain (integral_closure R A) -- fails

we can see from the debugging output that indeed the unifier is failing to find the coercion when the metavariable is in place:

[type_context.is_def_eq_detail] [1]: subalgebra R A =?= set ?m_1
[type_context.is_def_eq_detail] unfold right: set
[type_context.is_def_eq_detail] [2]: subalgebra R A =?= ?m_1 → Prop
[type_context.is_def_eq_detail] on failure: subalgebra R A =?= ?m_1 → Prop
[type_context.is_def_eq] subalgebra R A =?= set ?m_1 ... failed  (approximate mode)

Reid Barton (Mar 30 2020 at 20:47):

Is that failing to find a coercion or simply checking that the two sides are not defeq (without a coercion)?

Kevin Buzzard (Mar 30 2020 at 20:48):

Oh man, looking at this debugging output it even seems to get so close!

[type_context.is_def_eq_detail] [7]: has_coe_to_sort.coe (has_coe_t_aux.coe (set A) (has_coe_t_aux.coe (submodule R A) (integral_closure R A))) =?= {x // x ∈ ?m_2}
[type_context.is_def_eq_detail] [8]: (λ (s : set A), {x // x ∈ s}) (has_coe_t_aux.coe (set A) (has_coe_t_aux.coe (submodule R A) (integral_closure R A))) =?= {x // x ∈ ?m_2}
[type_context.is_def_eq_detail] after whnf_core: {x // x ∈ has_coe_t_aux.coe (set A) (has_coe_t_aux.coe (submodule R A) (integral_closure R A))} =?= {x // x ∈ ?m_2}
[type_context.is_def_eq_detail] process_assignment ?m_1 := A
[type_context.is_def_eq_detail] assign: ?m_1 := A
[type_context.is_def_eq_detail] [9]: x ∈ has_coe_t_aux.coe (set A) (has_coe_t_aux.coe (submodule R A) (integral_closure R A)) =?= x ∈ ?m_2
[type_context.is_def_eq_detail] process_assignment ?m_1 := has_coe_t_aux.coe (set A) (has_coe_t_aux.coe (submodule R A) (integral_closure R A))
[type_context.is_def_eq_detail] [10]: set ?m_1 =?= set A
[type_context.is_def_eq_detail] assign: ?m_1 := has_coe_t_aux.coe (set A) (has_coe_t_aux.coe (submodule R A) (integral_closure R A))
[type_context.is_def_eq] integral_domain ↥(integral_closure R A) =?= integral_domain ↥?m_2 ... success  (approximate mode)

Kevin Buzzard (Mar 30 2020 at 20:49):

I don't know how to read these logs, I only started looking at them today.

Kevin Buzzard (Mar 30 2020 at 20:51):

https://gist.github.com/kbuzzard/b8c86cfd46b5253c4888979078ba1f00


Last updated: Dec 20 2023 at 11:08 UTC