@@ -295,6 +295,7 @@ recommended_spelling "PProd" for "×'" in [PProd, «term_×'_»]
295295@[inherit_doc] prefix :75 "-" => Neg.neg
296296@[inherit_doc] prefix :100 "~~~" => Complement.complement
297297@[inherit_doc] postfix :max "⁻¹" => Inv.inv
298+ @[inherit_doc] infixr :73 " • " => HSMul.hSMul
298299
299300/-!
300301 Remark: the infix commands above ensure a delaborator is generated for each relations.
@@ -312,6 +313,40 @@ macro_rules | `($x % $y) => `(binop% HMod.hMod $x $y)
312313macro_rules | `($x ^ $y) => `(rightact% HPow.hPow $x $y)
313314macro_rules | `($x ++ $y) => `(binop% HAppend.hAppend $x $y)
314315macro_rules | `(- $x) => `(unop% Neg.neg $x)
316+ /-!
317+ We have a macro to make `x • y` notation participate in the expression tree elaborator,
318+ like other arithmetic expressions such as `+`, `*`, `/`, `^`, `=`, inequalities, etc.
319+ The macro is using the `leftact%` elaborator introduced in
320+ [ this RFC ] (https://github.com/leanprover/lean4/issues/2854).
321+
322+ As a concrete example of the effect of this macro, consider
323+ ```lean
324+ variable [Ring R] [AddCommMonoid M] [Module R M] (r : R) (N : Submodule R M) (m : M) (n : N)
325+ #check m + r • n
326+ ```
327+ Without the macro, the expression would elaborate as `m + ↑(r • n : ↑N) : M`.
328+ With the macro, the expression elaborates as `m + r • (↑n : M) : M`.
329+ To get the first interpretation, one can write `m + (r • n :)`.
330+
331+ Here is a quick review of the expression tree elaborator:
332+ 1. It builds up an expression tree of all the immediately accessible operations
333+ that are marked with `binop%`, `unop%`, `leftact%`, `rightact%`, `binrel%`, etc.
334+ 2. It elaborates every leaf term of this tree
335+ (without an expected type, so as if it were temporarily wrapped in `(... :)`).
336+ 3. Using the types of each elaborated leaf, it computes a supremum type they can all be
337+ coerced to, if such a supremum exists.
338+ 4. It inserts coercions around leaf terms wherever needed.
339+
340+ The hypothesis is that individual expression trees tend to be calculations with respect
341+ to a single algebraic structure.
342+
343+ Note(kmill): If we were to remove `HSMul` and switch to using `SMul` directly,
344+ then the expression tree elaborator would not be able to insert coercions within the right operand;
345+ they would likely appear as `↑(x • y)` rather than `x • ↑y`, unlike other arithmetic operations.
346+ -/
347+
348+ @[inherit_doc HSMul.hSMul]
349+ macro_rules | `($x • $y) => `(leftact% HSMul.hSMul $x $y)
315350
316351recommended_spelling "or" for "|||" in [HOr.hOr, «term_|||_ »]
317352recommended_spelling "xor" for "^^^" in [HXor.hXor, «term_^^^_ »]
@@ -323,6 +358,7 @@ recommended_spelling "mul" for "*" in [HMul.hMul, «term_*_»]
323358recommended_spelling "div" for "/" in [HDiv.hDiv, «term_/_ »]
324359recommended_spelling "mod" for "%" in [HMod.hMod, «term_%_ »]
325360recommended_spelling "pow" for "^" in [HPow.hPow, «term_^_ »]
361+ recommended_spelling "smul" for "•" in [HSMul.hSMul, «term_•_ »]
326362recommended_spelling "append" for "++" in [HAppend.hAppend, «term_++_ »]
327363/-- when used as a unary operator -/
328364recommended_spelling "neg" for "-" in [Neg.neg, «term-_ »]
0 commit comments