Zulip Chat Archive
Stream: mathlib4
Topic: Matrix multiplication notation failed
nemo (Nov 01 2025 at 03:16):
I was trying to write something about matrices when I encounted the following error, where lean seems to have failed to parse the matrix multiplication notation under certain circumstances.
It is an unexpected bug or did I use the wrong way to write it?
import Mathlib
example [RCLike 𝕜] [Fintype m] [Fintype n] (A : Matrix m n 𝕜) (B : Matrix n n 𝕜) :
A * B = A := by
/-
failed to synthesize
CoeT (Matrix n n 𝕜) x (Matrix m n 𝕜)
(deterministic) timeout at `typeclass`, maximum number of heartbeats (20000) has been reached
Note: Use `set_option synthInstance.maxHeartbeats <num>` to set the limit.
Hint: Additional diagnostic information may be available using the `set_option diagnostics true` command.
Hint: Additional diagnostic information may be available using the `set_option diagnostics true` command.
-/
sorry
example [RCLike 𝕜] [Fintype m] [Fintype n] (A : Matrix m n 𝕜) (B : Matrix n n 𝕜) :
Matrix.instHMulOfFintypeOfMulOfAddCommMonoid.hMul A B = A := by
/-
Works well when I write the mul explicitly
-/
example [RCLike 𝕜] [Fintype m] (A : Matrix m m 𝕜) (B : Matrix m m 𝕜) :
A * B = A := by
/-
Also works if the matrix is square
-/
sorry
sorry
Notification Bot (Nov 01 2025 at 03:43):
This topic was moved here from #lean4 > Matrix multiplication notation failed by Yury G. Kudryashov.
Notification Bot (Nov 01 2025 at 03:47):
This topic was moved here from #new members > Matrix multiplication notation failed by Yury G. Kudryashov.
Yury G. Kudryashov (Nov 01 2025 at 03:48):
Sorry for moving twice. First I thought that you've made a typo, then I realized that I've misread your message. I guess, when the parser sees that the type of the first multiplier is the same as the type of the product, it tries to elaborate the second multiplier as the same type.
Yury G. Kudryashov (Nov 01 2025 at 03:50):
CC: @Eric Wieser
Yury G. Kudryashov (Nov 01 2025 at 03:58):
As a temporary workaround, you can use HMul.hMul A B. I know that it looks bad.
Robin Arnez (Nov 01 2025 at 10:13):
This looks like we have some terrible coercion instances, specifically:
import Mathlib
attribute [-instance] IsometryClass.instCoeOutIsometryEquiv
attribute [-instance] ContinuousMonoidHom.instCoeOutOfMonoidHomClassOfContinuousMapClass
attribute [-instance] ContinuousAddMonoidHom.instCoeOutOfAddMonoidHomClassOfContinuousMapClass
attribute [-instance] HomeomorphClass.instCoeOutHomeomorph
attribute [-instance] StarRingEquivClass.instCoeHead
attribute [-instance] CoalgEquivClass.instCoeToCoalgEquiv
attribute [-instance] PositiveLinearMapClass.instCoeToLinearMap
attribute [-instance] SemilinearEquivClass.instCoeToSemilinearEquiv
attribute [-instance] SemilinearMapClass.instCoeToSemilinearMap
attribute [-instance] BialgHomClass.instCoeToBialgHom
attribute [-instance] LinearMapClass.instCoeToLinearMap
attribute [-instance] NonUnitalStarRingHomClass.instCoeHeadNonUnitalStarRingHom
attribute [-instance] StarAlgEquivClass.instCoeHead
attribute [-instance] CompletelyPositiveMapClass.instCoeToCompletelyPositiveMap
attribute [-instance] CoalgHomClass.instCoeToCoalgHom
attribute [-instance] SignType.instCoeTail
example [RCLike 𝕜] [Fintype m] [Fintype n] (A : Matrix m n 𝕜) (B : Matrix n n 𝕜) :
A * B = A := by
sorry
works
Kenny Lau (Nov 01 2025 at 10:14):
wow, thanks for taking the time to diagnose all that!
Robin Arnez (Nov 01 2025 at 10:14):
Wait, actually
import Mathlib
attribute [-instance] SignType.instCoeTail
example [RCLike 𝕜] [Fintype m] [Fintype n] (A : Matrix m n 𝕜) (B : Matrix n n 𝕜) :
A * B = A := by
sorry
is enough?
Robin Arnez (Nov 01 2025 at 10:14):
Still I don't like all of these other ones firing for all coercions
Robin Arnez (Nov 01 2025 at 10:28):
Alright I'm officially confused;
import Mathlib
set_option trace.Meta.synthInstance true
variable [RCLike 𝕜] [Fintype m] [Fintype n] in
#synth CoeTail SignType (Matrix m n 𝕜)
is the problem but it takes less steps to resolve Zero (Matrix m n 𝕜), One (Matrix m n 𝕜) and Neg (Matrix m n 𝕜) combined?
Aaron Liu (Nov 01 2025 at 15:22):
Yury G. Kudryashov said:
I guess, when the parser sees that the type of the first multiplier is the same as the type of the product, it tries to elaborate the second multiplier as the same type.
I don't think the typeclass takes into account the type of the product at all, since it's an outParam.
Yury G. Kudryashov (Nov 01 2025 at 16:56):
Should we use docs#CoeHTCT ? I know that it's discouraged in the docstring.
Yury G. Kudryashov (Nov 01 2025 at 16:57):
Or should the coercion from SignType be a CoeHead?
Aaron Liu (Nov 01 2025 at 17:00):
Why is docs#SignType.cast even a coercion
Aaron Liu (Nov 01 2025 at 17:00):
is it even used that much
Aaron Liu (Nov 01 2025 at 17:00):
not like Nat.cast which is everywhere
Yury G. Kudryashov (Nov 01 2025 at 18:09):
I think it's convenient to have it as a coercion, but CoeHead may be better so that it applies only for coercions from SignType.
Robin Arnez (Nov 01 2025 at 19:34):
The right thing to do is CoeDep I believe
Robin Arnez (Nov 01 2025 at 19:35):
I don't think you can do CoeHead because there's no way to know what to coerce to with that
Robin Arnez (Nov 01 2025 at 20:19):
Alright, I opened #31168
Eric Wieser (Nov 01 2025 at 20:57):
It would be great to note in the docstring for CoeDep that it is useful in nondependent cases
Yury G. Kudryashov (Nov 02 2025 at 03:35):
BTW, why do we have a separate CoeDep, not just extra instances of CoeT?
Aaron Liu (Nov 02 2025 at 03:40):
they seems to serve different function
Aaron Liu (Nov 02 2025 at 03:42):
CoeDep is for dependent coercions specifically and CoeT is for all the coercions
Aaron Liu (Nov 02 2025 at 03:42):
that's my guess
Yury G. Kudryashov (Nov 02 2025 at 04:11):
They have the same signature. CoeT has instances coming from non-dependent coercions + an instance from CoeDep. I don't understand why not just use specific CoeT instances instead of having an extra class.
Robin Arnez (Nov 02 2025 at 08:10):
Alright I see there is a bit of a problem; we have a coercion diamond between docs#SemilinearMapClass.instCoeToSemilinearMap and docs#LinearEquiv.instCoeLinearMap
Robin Arnez (Nov 02 2025 at 08:13):
I see that there is also a theorem about this: docs#LinearEquiv.toLinearMap_eq_coe. Which of these is supposed to be the normal form then?
Yury G. Kudryashov (Nov 02 2025 at 13:55):
AFAIR, @Yaël Dillies mentioned that *Class.instCoe* instances are going to be removed, not sure about the details.
Anne Baanen (Nov 04 2025 at 09:39):
Yury G. Kudryashov said:
BTW, why do we have a separate
CoeDep, not just extra instances ofCoeT?
CoeT is an implementation detail that users should not implement directly. It's unlikely that this will get a large redesign in the nearby future, but I can certainly imagine that CoeT will be replaced someday.
(Similarly, we should really have dealt already with all the CoeTC instances still defined in Mathlib...)
Last updated: Dec 20 2025 at 21:32 UTC