Skip to content

Commit 01cc327

Browse files
grunwegadomani
andcommitted
refactor(Tactic/Translate): document name translation a bit more (#39988)
I found the code a bit hard to read: the following commits each improve the code slightly. Also add a test exercising the "name matches the auto-generated name" code path. #39962 will tweak the naming algorithm slightly. Co-authored-by: damiano <adomani@gmail.com>
1 parent 05f0af5 commit 01cc327

3 files changed

Lines changed: 34 additions & 20 deletions

File tree

Mathlib/Tactic/Translate/Core.lean

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -310,8 +310,9 @@ structure Config : Type where
310310
/-- View the trace of the translation procedure.
311311
Equivalent to `set_option trace.translate true`. -/
312312
trace : Bool := false
313-
/-- The given name of the target. -/
314-
tgt : Name := Name.anonymous
313+
/-- The given name of the target: an anonymous name means no explicit name was provided,
314+
and the translate tactic auto-generates a name instead -/
315+
target : Name := Name.anonymous
315316
/-- An optional doc string. -/
316317
doc : Option String := .none
317318
/-- If `allowAutoName` is `false` (default) then
@@ -911,39 +912,42 @@ def translateLemmas
911912
/-- Return the provided target name or autogenerate one if one was not provided. -/
912913
def targetName (t : TranslateData) (cfg : Config) (src : Name) : CoreM Name := do
913914
if cfg.self then
914-
if cfg.tgt != .anonymous then
915-
logWarning m!"`{t.attrName} self` ignores the provided name {cfg.tgt}"
915+
if cfg.target != .anonymous then
916+
logWarning m!"`{t.attrName} self` ignores the provided name {cfg.target}"
916917
return src
917918
if cfg.none then
918-
if cfg.tgt != .anonymous then
919-
logWarning m!"`{t.attrName} private` ignores the provided name {cfg.tgt}"
919+
if cfg.target != .anonymous then
920+
logWarning m!"`{t.attrName} private` ignores the provided name {cfg.target}"
920921
return ← withDeclNameForAuxNaming src do
921922
mkAuxDeclName <| .mkSimple ("_" ++ t.attrName.toString)
922923
-- When re-tagging an existing translation, simply return that existing translation.
923924
if cfg.existing then
924-
if cfg.tgt == .anonymous then
925+
if cfg.target == .anonymous then
925926
if let some tgt := findTranslationName? (← getEnv) t src then
926927
return tgt
927928
let .str pre s := src | throwError "{t.attrName}: can't transport {src}"
928929
trace[translate_detail] "The name {s} splits as {open GuessName in s.splitCase}"
929-
let tgt_auto := GuessName.guessName (t.guessNameExt.getState (← getEnv)) s
930-
let depth := cfg.tgt.getNumParts
931-
let pre := translateNamespace (← getEnv) pre
932-
let (pre1, pre2) := pre.splitAt (depth - 1)
933-
let res := if cfg.tgt == .anonymous then pre.str tgt_auto else pre1 ++ cfg.tgt
934-
if res == src then
930+
-- Auto-generated name of the resulting declaration, without prior namespace components.
931+
let translatedName := GuessName.guessName (t.guessNameExt.getState (← getEnv)) s
932+
let translatedNamespace := translateNamespace (← getEnv) pre
933+
let autoGeneratedName := translatedNamespace.str translatedName
934+
-- Heuristic: if a new name is manually provided which has fewer components than `src`,
935+
-- prepend the first components from `src` to create a translated name of the same depth.
936+
let resultingName := if cfg.target == .anonymous then autoGeneratedName else
937+
(translatedNamespace.splitAt (cfg.target.getNumParts - 1)).1 ++ cfg.target
938+
if resultingName == src then
935939
throwError "{t.attrName}: the generated translated name equals the original name '{src}'.\n\
936940
If this is intentional, use the `@[{t.attrName} self]` syntax.\n\
937941
Otherwise, check that your declaration name is correct \
938942
(if your declaration is an instance, try naming it)\n\
939943
or provide a translated name using the `@[{t.attrName} my_add_name]` syntax."
940-
if cfg.tgt == pre2.str tgt_auto && !cfg.allowAutoName then
944+
if cfg.target != .anonymous && autoGeneratedName == resultingName && !cfg.allowAutoName then
941945
Linter.logLintIf linter.translateGenerateName cfg.ref m!"\
942946
`{t.attrName}` correctly autogenerated target name for {src}.\n\
943-
You may remove the explicit argument {cfg.tgt}."
944-
if cfg.tgt != .anonymous then
945-
trace[translate_detail] "The automatically generated name would be {pre.str tgt_auto}"
946-
return res
947+
You may remove the explicit argument {cfg.target}."
948+
if cfg.target != .anonymous then
949+
trace[translate_detail] "The automatically generated name would be {autoGeneratedName}"
950+
return resultingName
947951
where
948952
translateNamespace (env : Environment) (n : Name) : Name :=
949953
let n' := Name.mapPrefix (findTranslationName? env t) n
@@ -1132,7 +1136,7 @@ def elabTranslationAttr (declName : Name) (stx : Syntax) : CoreM Config := do
11321136
| _ => throwUnsupportedSyntax
11331137
return {
11341138
trace := !stx[1].isNone
1135-
tgt := match tgt with | some tgt => tgt.getId | _ => Name.anonymous
1139+
target := match tgt with | some tgt => tgt.getId | _ => Name.anonymous
11361140
doc, attrs, reorder?, relevantArg?, dontTranslate, existing, self, none, rename,
11371141
ref := match tgt with | some tgt => tgt.raw | _ => stx[0] }
11381142
| _ => throwUnsupportedSyntax

Mathlib/Tactic/Translate/TagUnfoldBoundary.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ def elabInsertCastAux (declName : Name) (castKind : CastKind) (stx : Term) (t :
7676
let newName ← mkAuxDeclName ((t.attrName.appendBefore "_").appendAfter "_cast")
7777
addDecl newName newType newValue
7878
-- Now add the translation attribute to relate the two new declarations
79-
_ ← addTranslationAttr t name { tgt := newName, existing := true, ref := .missing }
79+
_ ← addTranslationAttr t name { target := newName, existing := true, ref := .missing }
8080
return (name, newName)
8181
where
8282
unfoldLHS? : CastKind → Expr → OptionT TermElabM Expr

MathlibTest/Attribute/ToAdditive/Basic.lean

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,16 @@ lemma Foo.Bar.baz'' (g h : G) : g * h = h * g := mul_comm g h
3535
/-- info: Bar.Bars.Stars.Bazzz.b.{u_1} {G : Type u_1} [AddCommGroup G] (g h : G) : g + h = h + g -/
3636
#guard_msgs in #check Bar.Bars.Stars.Bazzz.b
3737

38+
/--
39+
warning: `to_additive` correctly autogenerated target name for CommGroup.foo.
40+
You may remove the explicit argument AddCommGroup.foo.
41+
42+
Note: This linter can be disabled with `set_option linter.translateGenerateName false`
43+
-/
44+
#guard_msgs in
45+
@[to_additive AddCommGroup.foo]
46+
lemma _root_.CommGroup.foo {g h : G} : g * h = h * g := mul_comm g h
47+
3848
end
3949

4050
@[to_additive bar0]

0 commit comments

Comments
 (0)