Skip to content

Commit c06bd6a

Browse files
committed
feat: to_additive can reorder arguments of generated declaration (#818)
* This allows `@[to_additive]` on lemmas about `Pow` without having to write the corresponding lemmas about SMul explicitly. * Add syntax `to_additive (reorder := ...)` that will automatically reorder the arguments in the additive declaration and will reorder the arguments in all future uses of `to_additive` * Deprecate `@[to_additive_reorder]` attribute. * We keep it for now, so that it can display a warning message when porting a file with the attribute * We allow `@[to_additive (reorder := ...)]` on declarations that are already additivized, so that we can give the `reorder` information to projections of structures. * Maybe at some point we can add a syntax to "doubly additivize" a declaration about `Pow`, so that it generates both the `SMul` and `VAdd` declarations.
1 parent 2aba564 commit c06bd6a

File tree

7 files changed

+158
-151
lines changed

7 files changed

+158
-151
lines changed

Mathlib/Algebra/Group/Defs.lean

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -81,26 +81,12 @@ infixl:65 " +ᵥ " => HVAdd.hVAdd
8181
infixl:65 " -ᵥ " => HasVsub.vsub
8282
infixr:73 " • " => HSMul.hSMul
8383

84-
attribute [to_additive] Mul
85-
attribute [to_additive] Div
86-
attribute [to_additive] HMul
87-
attribute [to_additive] instHMul
88-
attribute [to_additive] HDiv
89-
attribute [to_additive] instHDiv
90-
84+
attribute [to_additive] Mul Div HMul instHMul HDiv instHDiv instHSMul HSMul
9185
attribute [to_additive_relevant_arg 3] HMul HAdd HPow HSMul
9286
attribute [to_additive_relevant_arg 3] HAdd.hAdd HMul.hMul HPow.hPow HSMul.hSMul
93-
attribute [to_additive_reorder 1] HPow
94-
attribute [to_additive_reorder 1 5] HPow.hPow
95-
attribute [to_additive_reorder 1] Pow
96-
attribute [to_additive_reorder 1 4] Pow.pow
97-
attribute [to_additive] Pow
98-
attribute [to_additive_reorder 1] instHPow
99-
attribute [to_additive] instHPow
100-
attribute [to_additive] HPow
101-
102-
attribute [to_additive] instHSMul
103-
attribute [to_additive] HSMul
87+
attribute [to_additive (reorder := 1)] Pow instHPow HPow
88+
attribute [to_additive (reorder := 1 5)] HPow.hPow
89+
attribute [to_additive (reorder := 1 4)] Pow.pow
10490

10591
universe u
10692

Mathlib/Algebra/Group/OrderSynonym.lean

Lines changed: 21 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -32,20 +32,15 @@ instance [h : Inv α] : Inv αᵒᵈ := h
3232
@[to_additive]
3333
instance [h : Div α] : Div αᵒᵈ := h
3434

35-
@[to_additive]
36-
instance [h : SMul α β] : SMul α βᵒᵈ := h
37-
38-
@[to_additive]
39-
instance instSMulOrderDual' [h : SMul α β] : SMul αᵒᵈ β := h
40-
#align order_dual.has_smul' instSMulOrderDual'
41-
42-
@[to_additive]
35+
@[to_additive (reorder := 1)]
4336
instance [h : Pow α β] : Pow αᵒᵈ β := h
4437
#align order_dual.has_pow instPowOrderDual
38+
#align order_dual.has_smul instSMulOrderDual
4539

46-
@[to_additive]
40+
@[to_additive (reorder := 1)]
4741
instance instPowOrderDual' [h : Pow α β] : Pow α βᵒᵈ := h
4842
#align order_dual.has_pow' instPowOrderDual'
43+
#align order_dual.has_smul' instSMulOrderDual'
4944

5045
@[to_additive]
5146
instance [h : Semigroup α] : Semigroup αᵒᵈ := h
@@ -130,35 +125,19 @@ theorem toDual_div [Div α] (a b : α) : toDual (a / b) = toDual a / toDual b :=
130125
theorem ofDual_div [Div α] (a b : αᵒᵈ) : ofDual (a / b) = ofDual a / ofDual b := rfl
131126
#align of_dual_div ofDual_div
132127

133-
@[simp, to_additive]
134-
theorem toDual_smul [SMul α β] (a : α) (b : β) : toDual (a • b) = a • toDual b := rfl
135-
#align to_dual_smul toDual_smul
136-
137-
@[simp, to_additive]
138-
theorem ofDual_smul [SMul α β] (a : α) (b : βᵒᵈ) : ofDual (a • b) = a • ofDual b := rfl
139-
#align of_dual_smul ofDual_smul
140-
141-
@[simp, to_additive]
142-
theorem toDual_smul' [SMul α β] (a : α) (b : β) : toDual a • b = a • b := rfl
143-
#align to_dual_smul' toDual_smul'
144-
145-
@[simp, to_additive]
146-
theorem ofDual_smul' [SMul α β] (a : αᵒᵈ) (b : β) : ofDual a • b = a • b := rfl
147-
#align of_dual_smul' ofDual_smul'
148-
149-
@[simp, to_additive, to_additive_reorder 1 4]
128+
@[simp, to_additive (reorder := 1 4)]
150129
theorem toDual_pow [Pow α β] (a : α) (b : β) : toDual (a ^ b) = toDual a ^ b := rfl
151130
#align to_dual_pow toDual_pow
152131

153-
@[simp, to_additive, to_additive_reorder 1 4]
132+
@[simp, to_additive (reorder := 1 4)]
154133
theorem ofDual_pow [Pow α β] (a : αᵒᵈ) (b : β) : ofDual (a ^ b) = ofDual a ^ b := rfl
155134
#align of_dual_pow ofDual_pow
156135

157-
@[simp, to_additive toDual_smul', to_additive_reorder 1 4]
136+
@[simp, to_additive toDual_smul' (reorder := 1 4)]
158137
theorem pow_toDual [Pow α β] (a : α) (b : β) : a ^ toDual b = a ^ b := rfl
159138
#align pow_to_dual pow_toDual
160139

161-
@[simp, to_additive ofDual_smul', to_additive_reorder 1 4]
140+
@[simp, to_additive ofDual_smul' (reorder := 1 4)]
162141
theorem pow_ofDual [Pow α β] (a : α) (b : βᵒᵈ) : a ^ ofDual b = a ^ b := rfl
163142
#align pow_of_dual pow_ofDual
164143

@@ -177,20 +156,15 @@ instance [h : Inv α] : Inv (Lex α) := h
177156
@[to_additive]
178157
instance [h : Div α] : Div (Lex α) := h
179158

180-
@[to_additive]
181-
instance [h : SMul α β] : SMul α (Lex β) := h
182-
183-
@[to_additive]
184-
instance instSMulLex' [h : SMul α β] : SMul (Lex α) β := h
185-
#align lex.has_smul' instSMulLex'
186-
187-
@[to_additive]
159+
@[to_additive (reorder := 1)]
188160
instance [h : Pow α β] : Pow (Lex α) β := h
189161
#align lex.has_pow instPowLex
162+
#align lex.has_smul instSMulLex
190163

191-
@[to_additive]
164+
@[to_additive (reorder := 1)]
192165
instance instPowLex' [h : Pow α β] : Pow α (Lex β) := h
193166
#align lex.has_pow' instPowLex'
167+
#align lex.has_smul' instSMulLex'
194168

195169
@[to_additive]
196170
instance [h : Semigroup α] : Semigroup (Lex α) := h
@@ -275,34 +249,23 @@ theorem toLex_div [Div α] (a b : α) : toLex (a / b) = toLex a / toLex b := rfl
275249
theorem ofLex_div [Div α] (a b : Lex α) : ofLex (a / b) = ofLex a / ofLex b := rfl
276250
#align of_lex_div ofLex_div
277251

278-
@[simp, to_additive]
279-
theorem toLex_smul [SMul α β] (a : α) (b : β) : toLex (a • b) = a • toLex b := rfl
280-
#align to_lex_smul toLex_smul
281-
282-
@[simp, to_additive]
283-
theorem ofLex_smul [SMul α β] (a : α) (b : Lex β) : ofLex (a • b) = a • ofLex b := rfl
284-
#align of_lex_smul ofLex_smul
285-
286-
@[simp, to_additive]
287-
theorem toLex_smul' [SMul α β] (a : α) (b : β) : toLex a • b = a • b := rfl
288-
#align to_lex_smul' toLex_smul'
289-
290-
@[simp, to_additive]
291-
theorem ofLex_smul' [SMul α β] (a : Lex α) (b : β) : ofLex a • b = a • b := rfl
292-
#align of_lex_smul' ofLex_smul'
293-
294-
@[simp, to_additive, to_additive_reorder 1 4]
252+
@[simp, to_additive (reorder := 1 4)]
295253
theorem toLex_pow [Pow α β] (a : α) (b : β) : toLex (a ^ b) = toLex a ^ b := rfl
296254
#align to_lex_pow toLex_pow
297255

298-
@[simp, to_additive, to_additive_reorder 1 4]
256+
@[simp, to_additive (reorder := 1 4)]
299257
theorem ofLex_pow [Pow α β] (a : Lex α) (b : β) : ofLex (a ^ b) = ofLex a ^ b := rfl
300258
#align of_lex_pow ofLex_pow
301259

302-
@[simp, to_additive toLex_smul, to_additive_reorder 1 4]
260+
@[simp, to_additive toLex_smul' (reorder := 1 4)]
303261
theorem pow_toLex [Pow α β] (a : α) (b : β) : a ^ toLex b = a ^ b := rfl
304262
#align pow_to_lex pow_toLex
305263

306-
@[simp, to_additive ofLex_smul, to_additive_reorder 1 4]
264+
@[simp, to_additive ofLex_smul' (reorder := 1 4)]
307265
theorem pow_ofLex [Pow α β] (a : α) (b : Lex β) : a ^ ofLex b = a ^ b := rfl
308266
#align pow_of_lex pow_ofLex
267+
268+
attribute [to_additive] instSMulOrderDual instSMulOrderDual'
269+
toDual_smul ofDual_smul toDual_smul' ofDual_smul'
270+
instSMulLex instSMulLex'
271+
toLex_smul ofLex_smul toLex_smul' ofLex_smul'

Mathlib/Data/Pi/Algebra.lean

Lines changed: 6 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -93,43 +93,29 @@ instance instSMul [∀ i, SMul α <| f i] : SMul α (∀ i : I, f i) :=
9393
#align pi.has_smul Pi.instSMul
9494
#align pi.has_vadd Pi.instVAdd
9595

96-
@[simp, to_additive]
97-
theorem smul_apply [∀ i, SMul α <| f i] (s : α) (x : ∀ i, f i) (i : I) : (s • x) i = s • x i :=
98-
rfl
99-
100-
@[to_additive]
101-
theorem smul_def [∀ i, SMul α <| f i] (s : α) (x : ∀ i, f i) : s • x = fun i => s • x i :=
102-
rfl
103-
104-
@[simp, to_additive]
105-
theorem smul_const [SMul α β] (a : α) (b : β) : a • const I b = const I (a • b) :=
106-
rfl
107-
108-
@[to_additive]
109-
theorem smul_comp [SMul α γ] (a : α) (x : β → γ) (y : I → β) : (a • x) ∘ y = a • x ∘ y :=
110-
rfl
111-
11296
@[to_additive]
11397
instance instPow [∀ i, Pow (f i) β] : Pow (∀ i, f i) β :=
11498
fun x b i => x i ^ b⟩
11599

116-
@[simp, to_additive, to_additive_reorder 5]
100+
@[simp, to_additive (reorder := 5)]
117101
theorem pow_apply [∀ i, Pow (f i) β] (x : ∀ i, f i) (b : β) (i : I) : (x ^ b) i = x i ^ b :=
118102
rfl
119103

120-
@[to_additive, to_additive_reorder 5]
104+
@[to_additive (reorder := 5)]
121105
theorem pow_def [∀ i, Pow (f i) β] (x : ∀ i, f i) (b : β) : x ^ b = fun i => x i ^ b :=
122106
rfl
123107

124108
-- `to_additive` generates bad output if we take `Pow α β`.
125-
@[simp, to_additive smul_const, to_additive_reorder 5]
109+
@[simp, to_additive smul_const (reorder := 5)]
126110
theorem const_pow [Pow β α] (b : β) (a : α) : const I b ^ a = const I (b ^ a) :=
127111
rfl
128112

129-
@[to_additive, to_additive_reorder 6]
113+
@[to_additive (reorder := 6)]
130114
theorem pow_comp [Pow γ α] (x : β → γ) (a : α) (y : I → β) : (x ^ a) ∘ y = x ∘ y ^ a :=
131115
rfl
132116

117+
attribute [to_additive] smul_apply smul_def smul_const smul_comp
118+
133119
/-!
134120
Porting note: `bit0` and `bit1` are deprecated. This section can be removed entirely
135121
(without replacement?).

Mathlib/Lean/Expr/Basic.lean

Lines changed: 29 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -77,40 +77,49 @@ end Name
7777

7878
namespace ConstantInfo
7979

80+
/-- Checks whether this `ConstantInfo` is a definition, -/
8081
def isDef : ConstantInfo → Bool
8182
| defnInfo _ => true
8283
| _ => false
8384

85+
/-- Checks whether this `ConstantInfo` is a theorem, -/
8486
def isThm : ConstantInfo → Bool
8587
| thmInfo _ => true
8688
| _ => false
8789

88-
def updateName : ConstantInfo → Name → ConstantInfo
89-
| defnInfo info, n => defnInfo {info with name := n}
90-
| axiomInfo info, n => axiomInfo {info with name := n}
91-
| thmInfo info, n => thmInfo {info with name := n}
92-
| opaqueInfo info, n => opaqueInfo {info with name := n}
93-
| quotInfo info, n => quotInfo {info with name := n}
94-
| inductInfo info, n => inductInfo {info with name := n}
95-
| ctorInfo info, n => ctorInfo {info with name := n}
96-
| recInfo info, n => recInfo {info with name := n}
97-
98-
def updateType : ConstantInfo → Expr → ConstantInfo
99-
| defnInfo info, y => defnInfo {info with type := y}
100-
| axiomInfo info, y => axiomInfo {info with type := y}
101-
| thmInfo info, y => thmInfo {info with type := y}
102-
| opaqueInfo info, y => opaqueInfo {info with type := y}
103-
| quotInfo info, y => quotInfo {info with type := y}
104-
| inductInfo info, y => inductInfo {info with type := y}
105-
| ctorInfo info, y => ctorInfo {info with type := y}
106-
| recInfo info, y => recInfo {info with type := y}
107-
90+
/-- Update `ConstantVal` (the data common to all constructors of `ConstantInfo`)
91+
in a `ConstantInfo`. -/
92+
def updateConstantVal : ConstantInfo → ConstantVal → ConstantInfo
93+
| defnInfo info, v => defnInfo {info with toConstantVal := v}
94+
| axiomInfo info, v => axiomInfo {info with toConstantVal := v}
95+
| thmInfo info, v => thmInfo {info with toConstantVal := v}
96+
| opaqueInfo info, v => opaqueInfo {info with toConstantVal := v}
97+
| quotInfo info, v => quotInfo {info with toConstantVal := v}
98+
| inductInfo info, v => inductInfo {info with toConstantVal := v}
99+
| ctorInfo info, v => ctorInfo {info with toConstantVal := v}
100+
| recInfo info, v => recInfo {info with toConstantVal := v}
101+
102+
/-- Update the name of a `ConstantInfo`. -/
103+
def updateName (c : ConstantInfo) (name : Name) : ConstantInfo :=
104+
c.updateConstantVal {c.toConstantVal with name}
105+
106+
/-- Update the type of a `ConstantInfo`. -/
107+
def updateType (c : ConstantInfo) (type : Expr) : ConstantInfo :=
108+
c.updateConstantVal {c.toConstantVal with type}
109+
110+
/-- Update the level parameters of a `ConstantInfo`. -/
111+
def updateLevelParams (c : ConstantInfo) (levelParams : List Name) :
112+
ConstantInfo :=
113+
c.updateConstantVal {c.toConstantVal with levelParams}
114+
115+
/-- Update the value of a `ConstantInfo`, if it has one. -/
108116
def updateValue : ConstantInfo → Expr → ConstantInfo
109117
| defnInfo info, v => defnInfo {info with value := v}
110118
| thmInfo info, v => thmInfo {info with value := v}
111119
| opaqueInfo info, v => opaqueInfo {info with value := v}
112120
| d, _ => d
113121

122+
/-- Turn a `ConstantInfo` into a declaration. -/
114123
def toDeclaration! : ConstantInfo → Declaration
115124
| defnInfo info => Declaration.defnDecl info
116125
| thmInfo info => Declaration.thmDecl info

Mathlib/Tactic/Simps/Basic.lean

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -837,7 +837,10 @@ def simpsAddProjection (declName : Name) (type lhs rhs : Expr) (args : Array Exp
837837
if let some tgt := cfg.addAdditive then
838838
ToAdditive.addToAdditiveAttr declName
839839
-- tracing seems to fail
840-
false, (← getOptions) |>.getBool `trace.to_additive, tgt, none, true, ref⟩
840+
{ trace := (← getOptions) |>.getBool `trace.to_additive,
841+
allowAutoName := true
842+
tgt
843+
ref }
841844

842845
/--
843846
Perform head-structure-eta-reduction on expression `e`. That is, if `e` is of the form

0 commit comments

Comments
 (0)