Zulip Chat Archive
Stream: new members
Topic: has_coe
Alex Zhang (Jul 10 2021 at 09:16):
Why does #check reports the errorinvalid field notation, function 'has_coe.coe' does not have explicit argument with type (has_coe ...)?
import data.matrix.basic
namespace matrix
variables {α I J : Type*} [fintype I] [fintype J] [non_unital_non_assoc_semiring α]
instance to_mul_vec : has_coe (matrix I J α) ((J → α) → (I → α)) :=
⟨λ M v, M.mul_vec v⟩
variable (A : matrix I J α)
#check matrix.to_mul_vec.coe A
end matrix
Alex Zhang (Jul 10 2021 at 09:17):
Btw, #check matrix.to_mul_vec.coe gives has_coe.coe : matrix ?M_1 ?M_2 ?M_5 → (?M_2 → ?M_5) → ?M_1 → ?M_5.
Mario Carneiro (Jul 10 2021 at 09:19):
has_coe.coe is usually written \u, why are you using projection notation for it?
Mario Carneiro (Jul 10 2021 at 09:21):
it has an argument of type has_coe but it's a typeclass argument, so it isn't supposed to work with projection notation. (It does in some circumstances due to a bug that no one has cared to fix.)
Alex Zhang (Jul 10 2021 at 09:25):
Mario Carneiro said:
has_coe.coeis usually written\u, why are you using projection notation for it?
Because I am not sure how to properly use \u in this case. I would like #check ↑A to print ↑A : (J → α) → I → α but it prints ↑A : ?M_1. @Mario Carneiro
Mario Carneiro (Jul 10 2021 at 09:26):
it needs to know what it is coercing to as well. #check (↑A : (J → α) → I → α ) should work
Mario Carneiro (Jul 10 2021 at 09:27):
I think in this example it would be better to have a coe_fun instance instead, so that you can write A v for mul_vec
Alex Zhang (Jul 10 2021 at 09:28):
(deleted)
Alex Zhang (Jul 10 2021 at 09:29):
Mario Carneiro said:
it needs to know what it is coercing to as well.
#check (↑A : (J → α) → I → α )should work
Yeah, Mario. I know this should work. I was using the projection notation for another reason.
Mario Carneiro (Jul 10 2021 at 09:29):
if you are just exploring and noticed the oddity with matrix.to_mul_vec.coe, that's just a bug
Alex Zhang (Jul 10 2021 at 09:29):
import data.matrix.basic
namespace matrix
variables {α I J : Type*} [fintype I] [fintype J] [non_unital_non_assoc_semiring α]
instance to_mul_vec : has_coe (matrix I J α) ((J → α) → (I → α)) :=
⟨λ M v, M.mul_vec v⟩
instance to_vec_mul : has_coe (matrix I J α) ((I → α) → (J → α)) :=
⟨λ M v, M.vec_mul v⟩
variable (A : matrix I I α)
#check (↑A : (I → α) → (I → α))
end matrix
Alex Zhang (Jul 10 2021 at 09:30):
In the above case, if I use \u, I think I am unable to pick which one of to_mul_vec to_vec_mul I am using. That is the other reason I was not using \u before.
Mario Carneiro (Jul 10 2021 at 09:31):
yeah that looks like a bad notation
Mario Carneiro (Jul 10 2021 at 09:32):
I would do something like A *> v and v <* A
Alex Zhang (Jul 10 2021 at 09:34):
@Mario Carneiro Mario, do you have a way to pick a particular coercion?
I don't quite understand your last reply, could you please give more explanation?
Alex Zhang (Jul 10 2021 at 09:35):
btw, #check A.to_mul_vec.coe also reports an error.
Mario Carneiro (Jul 10 2021 at 09:36):
The notation is ambiguous about a mathematically relevant distinction, so even if lean worked perfectly here I wouldn't recommend it
Mario Carneiro (Jul 10 2021 at 09:37):
you shouldn't use A v to mean both A*v and v*A
Eric Wieser (Jul 10 2021 at 09:37):
Because if you did, it would be ambiguous when I = J
Mario Carneiro (Jul 10 2021 at 09:38):
even if one of them is type incorrect and so lean knows what you are talking about, readers will be confused
Eric Wieser (Jul 10 2021 at 09:39):
Not just readers, people trying to prove things about your definition will get ambiguous goal states they have to hover over to interpret.
Alex Zhang (Jul 10 2021 at 09:47):
Mario Carneiro said:
I would do something like
A *> vandv <* A
As I noticed \u A and A v are ambiguous in the (A : matrix I I α) case , I attempted to use the dot notation. Then Mario pointed out to me that there is a bug.
*> and <* have already been used to mean has_seq_right and has_seq_left(, of which I don't quite understand the purpose).
What I am not sure is if you mean to use has_seq_right and has_seq_left or just overload of notations?
Eric Wieser (Jul 10 2021 at 09:57):
Have you considered A • v as a spelling?
Eric Wieser (Jul 10 2021 at 09:59):
Oh, I guess that only works for square matrices
Alex Zhang (Jul 10 2021 at 10:04):
No. • is used for scalar multiplication. I am not sophisticated in playing around with abused notations.
Eric Wieser (Jul 10 2021 at 10:08):
I'd argue that for square matrices A • v is actually the right syntax, since it satisfies module (matrix n n R) (n → R). Lean 4's heterogenous multiplication would help a lot here
Alex Zhang (Jul 10 2021 at 10:13):
Maybe this is a little bit far away from my original question. As #check (↑A : (I → α) → (I → α)) is ambiguous, is there a way to invoke to_mul_vec or to_vec_mul manually?
Eric Wieser (Jul 10 2021 at 10:22):
Yes, you can use @has_coe.coe _ _ to_vec_mul A
Eric Wieser (Jul 10 2021 at 10:23):
But this is an #xy problem, if your notation is ambiguous then you shouldn't have defined it in the first place.
Alex Zhang (Jul 10 2021 at 11:20):
Thanks and good point! I was exploiting things in Lean.
Last updated: May 02 2025 at 03:31 UTC