File: Mathlib/Tactic/Abel.lean

full_name: Mathlib.Tactic.Abel.initFn._@.Mathlib.Tactic.Abel._hyg.9
code: initialize registerTraceClass `abel
goal: IO Unit

full_name: Mathlib.Tactic.Abel.initFn._@.Mathlib.Tactic.Abel._hyg.50
code: initialize registerTraceClass `abel.detail
goal: IO Unit

full_name: Mathlib.Tactic.Abel.Context.α0
code: /-- The `Context` for a call to `abel`.

Stores a few options for this call, and caches some common subexpressions
such as typeclass instances and `0 : α`.
-/
structure Context where
  /-- The type of the ambient additive commutative group or monoid. -/
  α       : Expr
  /-- The universe level for `α`. -/
  univ    : Level
  /-- The expression representing `0 : α`. -/
  α0      : Expr
  /-- Specify whether we are in an additive commutative group or an additive commutative monoid. -/
  isGroup : Bool
  /-- The `AddCommGroup α` or `AddCommMonoid α` expression. -/
  inst    : Expr
goal: Lean.Expr

full_name: Mathlib.Tactic.Abel.Context
code: /-- The `Context` for a call to `abel`.

Stores a few options for this call, and caches some common subexpressions
such as typeclass instances and `0 : α`.
-/
structure Context where
  /-- The type of the ambient additive commutative group or monoid. -/
  α       : Expr
  /-- The universe level for `α`. -/
  univ    : Level
  /-- The expression representing `0 : α`. -/
  α0      : Expr
  /-- Specify whether we are in an additive commutative group or an additive commutative monoid. -/
  isGroup : Bool
  /-- The `AddCommGroup α` or `AddCommMonoid α` expression. -/
  inst    : Expr
goal: Type

full_name: Mathlib.Tactic.Abel.Context.univ
code: /-- The `Context` for a call to `abel`.

Stores a few options for this call, and caches some common subexpressions
such as typeclass instances and `0 : α`.
-/
structure Context where
  /-- The type of the ambient additive commutative group or monoid. -/
  α       : Expr
  /-- The universe level for `α`. -/
  univ    : Level
  /-- The expression representing `0 : α`. -/
  α0      : Expr
  /-- Specify whether we are in an additive commutative group or an additive commutative monoid. -/
  isGroup : Bool
  /-- The `AddCommGroup α` or `AddCommMonoid α` expression. -/
  inst    : Expr
goal: Lean.Level

full_name: Mathlib.Tactic.Abel.Context.inst
code: /-- The `Context` for a call to `abel`.

Stores a few options for this call, and caches some common subexpressions
such as typeclass instances and `0 : α`.
-/
structure Context where
  /-- The type of the ambient additive commutative group or monoid. -/
  α       : Expr
  /-- The universe level for `α`. -/
  univ    : Level
  /-- The expression representing `0 : α`. -/
  α0      : Expr
  /-- Specify whether we are in an additive commutative group or an additive commutative monoid. -/
  isGroup : Bool
  /-- The `AddCommGroup α` or `AddCommMonoid α` expression. -/
  inst    : Expr
goal: Lean.Expr

full_name: Mathlib.Tactic.Abel.Context.isGroup
code: /-- The `Context` for a call to `abel`.

Stores a few options for this call, and caches some common subexpressions
such as typeclass instances and `0 : α`.
-/
structure Context where
  /-- The type of the ambient additive commutative group or monoid. -/
  α       : Expr
  /-- The universe level for `α`. -/
  univ    : Level
  /-- The expression representing `0 : α`. -/
  α0      : Expr
  /-- Specify whether we are in an additive commutative group or an additive commutative monoid. -/
  isGroup : Bool
  /-- The `AddCommGroup α` or `AddCommMonoid α` expression. -/
  inst    : Expr
goal: Bool

full_name: Mathlib.Tactic.Abel.Context.α
code: /-- The `Context` for a call to `abel`.

Stores a few options for this call, and caches some common subexpressions
such as typeclass instances and `0 : α`.
-/
structure Context where
  /-- The type of the ambient additive commutative group or monoid. -/
  α       : Expr
  /-- The universe level for `α`. -/
  univ    : Level
  /-- The expression representing `0 : α`. -/
  α0      : Expr
  /-- Specify whether we are in an additive commutative group or an additive commutative monoid. -/
  isGroup : Bool
  /-- The `AddCommGroup α` or `AddCommMonoid α` expression. -/
  inst    : Expr
goal: Lean.Expr

full_name: Mathlib.Tactic.Abel.mkContext
code: /-- Populate a `context` object for evaluating `e`. -/
def mkContext (e : Expr) : MetaM Context 
goal: Lean.MetaM Mathlib.Tactic.Abel.Context

full_name: Mathlib.Tactic.Abel.M
code: /-- The monad for `Abel` contains, in addition to the `AtomM` state,
some information about the current type we are working over, so that we can consistently
use group lemmas or monoid lemmas as appropriate. -/
abbrev M 
goal: Type

full_name: Mathlib.Tactic.Abel.Context.app
code: /-- Apply the function `n : ∀ {α} [inst : AddWhatever α], _` to the
implicit parameters in the context, and the given list of arguments. -/
def Context.app (c : Context) (n : Name) (inst : Expr) : Array Expr → Expr 
goal: Array Lean.Expr → Lean.Expr

full_name: Mathlib.Tactic.Abel.Context.mkApp
code: /-- Apply the function `n : ∀ {α} [inst α], _` to the implicit parameters in the
context, and the given list of arguments.

Compared to `context.app`, this takes the name of the typeclass, rather than an
inferred typeclass instance.
-/
def Context.mkApp (c : Context) (n inst : Name) (l : Array Expr) : MetaM Expr 
goal: Lean.MetaM Lean.Expr

full_name: Mathlib.Tactic.Abel.addG
code: /-- Add the letter "g" to the end of the name, e.g. turning `term` into `termg`.

This is used to choose between declarations taking `AddCommMonoid` and those
taking `AddCommGroup` instances.
-/
def addG : Name → Name
  
goal: Lean.Name → Lean.Name

full_name: Mathlib.Tactic.Abel.iapp
code: /-- Apply the function `n : ∀ {α} [AddComm{Monoid,Group} α]` to the given list of arguments.

Will use the `AddComm{Monoid,Group}` instance that has been cached in the context.
-/
def iapp (n : Name) (xs : Array Expr) : M Expr 
goal: Mathlib.Tactic.Abel.M Lean.Expr

full_name: Mathlib.Tactic.Abel.term
code: /-- A type synonym used by `abel` to represent `n • x + a` in an additive commutative monoid. -/
def term {α} [AddCommMonoid α] (n : ℕ) (x a : α) : α 
goal: α

full_name: Mathlib.Tactic.Abel.termg
code: /-- A type synonym used by `abel` to represent `n • x + a` in an additive commutative group. -/
def termg {α} [AddCommGroup α] (n : ℤ) (x a : α) : α 
goal: α

full_name: Mathlib.Tactic.Abel.mkTerm
code: /-- Evaluate a term with coefficient `n`, atom `x` and successor terms `a`. -/
def mkTerm (n x a : Expr) : M Expr 
goal: Mathlib.Tactic.Abel.M Lean.Expr

full_name: Mathlib.Tactic.Abel.intToExpr
code: /-- Interpret an integer as a coefficient to a term. -/
def intToExpr (n : ℤ) : M Expr 
goal: Mathlib.Tactic.Abel.M Lean.Expr

full_name: Mathlib.Tactic.Abel.instInhabitedNormalExpr
code: /-- A normal form for `abel`.
Expressions are represented as a list of terms of the form `e = n • x`,
where `n : ℤ` and `x` is an arbitrary element of the additive commutative monoid or group.
We explicitly track the `Expr` forms of `e` and `n`, even though they could be reconstructed,
for efficiency. -/
inductive NormalExpr : Type
  | zero (e : Expr) : NormalExpr
  | nterm (e : Expr) (n : Expr × ℤ) (x : ℕ × Expr) (a : NormalExpr) : NormalExpr
  deriving Inhabited
goal: Inhabited Mathlib.Tactic.Abel.NormalExpr

full_name: Mathlib.Tactic.Abel.NormalExpr
code: /-- A normal form for `abel`.
Expressions are represented as a list of terms of the form `e = n • x`,
where `n : ℤ` and `x` is an arbitrary element of the additive commutative monoid or group.
We explicitly track the `Expr` forms of `e` and `n`, even though they could be reconstructed,
for efficiency. -/
inductive NormalExpr : Type
  | zero (e : Expr) : NormalExpr
  | nterm (e : Expr) (n : Expr × ℤ) (x : ℕ × Expr) (a : NormalExpr) : NormalExpr
  deriving Inhabited
goal: Type

full_name: Mathlib.Tactic.Abel.NormalExpr.nterm
code: /-- A normal form for `abel`.
Expressions are represented as a list of terms of the form `e = n • x`,
where `n : ℤ` and `x` is an arbitrary element of the additive commutative monoid or group.
We explicitly track the `Expr` forms of `e` and `n`, even though they could be reconstructed,
for efficiency. -/
inductive NormalExpr : Type
  | zero (e : Expr) : NormalExpr
  | nterm (e : Expr) (n : Expr × ℤ) (x : ℕ × Expr) (a : NormalExpr) : NormalExpr
  deriving Inhabited
goal: Mathlib.Tactic.Abel.NormalExpr

full_name: Mathlib.Tactic.Abel.NormalExpr.zero
code: /-- A normal form for `abel`.
Expressions are represented as a list of terms of the form `e = n • x`,
where `n : ℤ` and `x` is an arbitrary element of the additive commutative monoid or group.
We explicitly track the `Expr` forms of `e` and `n`, even though they could be reconstructed,
for efficiency. -/
inductive NormalExpr : Type
  | zero (e : Expr) : NormalExpr
  | nterm (e : Expr) (n : Expr × ℤ) (x : ℕ × Expr) (a : NormalExpr) : NormalExpr
  deriving Inhabited
goal: Mathlib.Tactic.Abel.NormalExpr

full_name: Mathlib.Tactic.Abel.NormalExpr.e
code: /-- Extract the expression from a normal form. -/
def NormalExpr.e : NormalExpr → Expr
  
goal: Mathlib.Tactic.Abel.NormalExpr → Lean.Expr

full_name: Mathlib.Tactic.Abel.instCoeNormalExprExpr
code: instance : Coe NormalExpr Expr 
goal: Coe Mathlib.Tactic.Abel.NormalExpr Lean.Expr

full_name: Mathlib.Tactic.Abel.NormalExpr.term'
code: /-- Construct the normal form representing a single term. -/
def NormalExpr.term' (n : Expr × ℤ) (x : ℕ × Expr) (a : NormalExpr) : M NormalExpr 
goal: Mathlib.Tactic.Abel.M Mathlib.Tactic.Abel.NormalExpr

full_name: Mathlib.Tactic.Abel.NormalExpr.zero'
code: /-- Construct the normal form representing zero. -/
def NormalExpr.zero' : M NormalExpr 
goal: Mathlib.Tactic.Abel.M Mathlib.Tactic.Abel.NormalExpr

full_name: Mathlib.Tactic.Abel.const_add_term
code: theorem const_add_term {α} [AddCommMonoid α] (k n x a a') (h : k + a = a') :
    k + @term α _ n x a = term n x a' 
goal: k + Mathlib.Tactic.Abel.term n x a = Mathlib.Tactic.Abel.term n x a'

full_name: Mathlib.Tactic.Abel.const_add_termg
code: theorem const_add_termg {α} [AddCommGroup α] (k n x a a') (h : k + a = a') :
    k + @termg α _ n x a = termg n x a' 
goal: k + Mathlib.Tactic.Abel.termg n x a = Mathlib.Tactic.Abel.termg n x a'

full_name: Mathlib.Tactic.Abel.term_add_const
code: theorem term_add_const {α} [AddCommMonoid α] (n x a k a') (h : a + k = a') :
    @term α _ n x a + k = term n x a' 
goal: Mathlib.Tactic.Abel.term n x a + k = Mathlib.Tactic.Abel.term n x a'

full_name: Mathlib.Tactic.Abel.term_add_constg
code: theorem term_add_constg {α} [AddCommGroup α] (n x a k a') (h : a + k = a') :
    @termg α _ n x a + k = termg n x a' 
goal: Mathlib.Tactic.Abel.termg n x a + k = Mathlib.Tactic.Abel.termg n x a'

full_name: Mathlib.Tactic.Abel.term_add_term
code: theorem term_add_term {α} [AddCommMonoid α] (n₁ x a₁ n₂ a₂ n' a') (h₁ : n₁ + n₂ = n')
    (h₂ : a₁ + a₂ = a') : @term α _ n₁ x a₁ + @term α _ n₂ x a₂ = term n' x a' 
goal: Mathlib.Tactic.Abel.term n₁ x a₁ + Mathlib.Tactic.Abel.term n₂ x a₂ = Mathlib.Tactic.Abel.term n' x a'

full_name: Mathlib.Tactic.Abel.term_add_termg
code: theorem term_add_termg {α} [AddCommGroup α] (n₁ x a₁ n₂ a₂ n' a')
    (h₁ : n₁ + n₂ = n') (h₂ : a₁ + a₂ = a') :
    @termg α _ n₁ x a₁ + @termg α _ n₂ x a₂ = termg n' x a' 
goal: Mathlib.Tactic.Abel.termg n₁ x a₁ + Mathlib.Tactic.Abel.termg n₂ x a₂ = Mathlib.Tactic.Abel.termg n' x a'

full_name: Mathlib.Tactic.Abel.zero_term
code: theorem zero_term {α} [AddCommMonoid α] (x a) : @term α _ 0 x a = a 
goal: Mathlib.Tactic.Abel.term 0 x a = a

full_name: Mathlib.Tactic.Abel.zero_termg
code: theorem zero_termg {α} [AddCommGroup α] (x a) : @termg α _ 0 x a = a 
goal: Mathlib.Tactic.Abel.termg 0 x a = a

full_name: Mathlib.Tactic.Abel.evalAdd
code: /--
Interpret the sum of two expressions in `abel`'s normal form.
-/
partial def evalAdd : NormalExpr → NormalExpr → M (NormalExpr × Expr)
  
goal: Mathlib.Tactic.Abel.NormalExpr →
  Mathlib.Tactic.Abel.NormalExpr → Mathlib.Tactic.Abel.M (Mathlib.Tactic.Abel.NormalExpr × Lean.Expr)

full_name: Mathlib.Tactic.Abel.term_neg
code: theorem term_neg {α} [AddCommGroup α] (n x a n' a')
    (h₁ : -n = n') (h₂ : -a = a') : -@termg α _ n x a = termg n' x a' 
goal: -Mathlib.Tactic.Abel.termg n x a = Mathlib.Tactic.Abel.termg n' x a'

full_name: Mathlib.Tactic.Abel.evalNeg
code: /--
Interpret a negated expression in `abel`'s normal form.
-/
def evalNeg : NormalExpr → M (NormalExpr × Expr)
  
goal: Mathlib.Tactic.Abel.NormalExpr → Mathlib.Tactic.Abel.M (Mathlib.Tactic.Abel.NormalExpr × Lean.Expr)

full_name: Mathlib.Tactic.Abel.smul
code: /-- A synonym for `•`, used internally in `abel`. -/
def smul {α} [AddCommMonoid α] (n : ℕ) (x : α) : α 
goal: α

full_name: Mathlib.Tactic.Abel.smulg
code: /-- A synonym for `•`, used internally in `abel`. -/
def smulg {α} [AddCommGroup α] (n : ℤ) (x : α) : α 
goal: α

full_name: Mathlib.Tactic.Abel.zero_smul
code: theorem zero_smul {α} [AddCommMonoid α] (c) : smul c (0 : α) = 0 
goal: Mathlib.Tactic.Abel.smul c 0 = 0

full_name: Mathlib.Tactic.Abel.zero_smulg
code: theorem zero_smulg {α} [AddCommGroup α] (c) : smulg c (0 : α) = 0 
goal: Mathlib.Tactic.Abel.smulg c 0 = 0

full_name: Mathlib.Tactic.Abel.term_smul
code: theorem term_smul {α} [AddCommMonoid α] (c n x a n' a')
    (h₁ : c * n = n') (h₂ : smul c a = a') :
    smul c (@term α _ n x a) = term n' x a' 
goal: Mathlib.Tactic.Abel.smul c (Mathlib.Tactic.Abel.term n x a) = Mathlib.Tactic.Abel.term n' x a'

full_name: Mathlib.Tactic.Abel.term_smulg
code: theorem term_smulg {α} [AddCommGroup α] (c n x a n' a')
    (h₁ : c * n = n') (h₂ : smulg c a = a') :
    smulg c (@termg α _ n x a) = termg n' x a' 
goal: Mathlib.Tactic.Abel.smulg c (Mathlib.Tactic.Abel.termg n x a) = Mathlib.Tactic.Abel.termg n' x a'

full_name: Mathlib.Tactic.Abel.evalSMul
code: /--
Auxiliary function for `evalSMul'`.
-/
def evalSMul (k : Expr × ℤ) : NormalExpr → M (NormalExpr × Expr)
  
goal: Mathlib.Tactic.Abel.NormalExpr → Mathlib.Tactic.Abel.M (Mathlib.Tactic.Abel.NormalExpr × Lean.Expr)

full_name: Mathlib.Tactic.Abel.term_atom
code: theorem term_atom {α} [AddCommMonoid α] (x : α) : x = term 1 x 0 
goal: x = Mathlib.Tactic.Abel.term 1 x 0

full_name: Mathlib.Tactic.Abel.term_atomg
code: theorem term_atomg {α} [AddCommGroup α] (x : α) : x = termg 1 x 0 
goal: x = Mathlib.Tactic.Abel.termg 1 x 0

full_name: Mathlib.Tactic.Abel.term_atom_pf
code: theorem term_atom_pf {α} [AddCommMonoid α] (x x' : α) (h : x = x') : x = term 1 x' 0 
goal: x = Mathlib.Tactic.Abel.term 1 x' 0

full_name: Mathlib.Tactic.Abel.term_atom_pfg
code: theorem term_atom_pfg {α} [AddCommGroup α] (x x' : α) (h : x = x') : x = termg 1 x' 0 
goal: x = Mathlib.Tactic.Abel.termg 1 x' 0

full_name: Mathlib.Tactic.Abel.evalAtom
code: /-- Interpret an expression as an atom for `abel`'s normal form. -/
def evalAtom (e : Expr) : M (NormalExpr × Expr) 
goal: Mathlib.Tactic.Abel.M (Mathlib.Tactic.Abel.NormalExpr × Lean.Expr)

full_name: Mathlib.Tactic.Abel.unfold_sub
code: theorem unfold_sub {α} [SubtractionMonoid α] (a b c : α) (h : a + -b = c) : a - b = c 
goal: a - b = c

full_name: Mathlib.Tactic.Abel.unfold_smul
code: theorem unfold_smul {α} [AddCommMonoid α] (n) (x y : α)
    (h : smul n x = y) : n • x = y 
goal: n • x = y

full_name: Mathlib.Tactic.Abel.unfold_smulg
code: theorem unfold_smulg {α} [AddCommGroup α] (n : ℕ) (x y : α)
    (h : smulg (Int.ofNat n) x = y) : (n : ℤ) • x = y 
goal: ↑n • x = y

full_name: Mathlib.Tactic.Abel.unfold_zsmul
code: theorem unfold_zsmul {α} [AddCommGroup α] (n : ℤ) (x y : α)
    (h : smulg n x = y) : n • x = y 
goal: n • x = y

full_name: Mathlib.Tactic.Abel.subst_into_smul
code: lemma subst_into_smul {α} [AddCommMonoid α]
    (l r tl tr t) (prl : l = tl) (prr : r = tr)
    (prt : @smul α _ tl tr = t) : smul l r = t 
goal: Mathlib.Tactic.Abel.smul l r = t

full_name: Mathlib.Tactic.Abel.subst_into_smulg
code: lemma subst_into_smulg {α} [AddCommGroup α]
    (l r tl tr t) (prl : l = tl) (prr : r = tr)
    (prt : @smulg α _ tl tr = t) : smulg l r = t 
goal: Mathlib.Tactic.Abel.smulg l r = t

full_name: Mathlib.Tactic.Abel.subst_into_smul_upcast
code: lemma subst_into_smul_upcast {α} [AddCommGroup α]
    (l r tl zl tr t) (prl₁ : l = tl) (prl₂ : ↑tl = zl) (prr : r = tr)
    (prt : @smulg α _ zl tr = t) : smul l r = t 
goal: Mathlib.Tactic.Abel.smul l r = t

full_name: Mathlib.Tactic.Abel.subst_into_add
code: lemma subst_into_add {α} [AddCommMonoid α] (l r tl tr t)
    (prl : (l : α) = tl) (prr : r = tr) (prt : tl + tr = t) : l + r = t 
goal: l + r = t

full_name: Mathlib.Tactic.Abel.subst_into_addg
code: lemma subst_into_addg {α} [AddCommGroup α] (l r tl tr t)
    (prl : (l : α) = tl) (prr : r = tr) (prt : tl + tr = t) : l + r = t 
goal: l + r = t

full_name: Mathlib.Tactic.Abel.subst_into_negg
code: lemma subst_into_negg {α} [AddCommGroup α] (a ta t : α)
    (pra : a = ta) (prt : -ta = t) : -a = t 
goal: -a = t

full_name: Mathlib.Tactic.Abel.evalSMul'
code: /-- Normalize a term `orig` of the form `smul e₁ e₂` or `smulg e₁ e₂`.
  Normalized terms use `smul` for monoids and `smulg` for groups,
  so there are actually four cases to handle:
  * Using `smul` in a monoid just simplifies the pieces using `subst_into_smul`
  * Using `smulg` in a group just simplifies the pieces using `subst_into_smulg`
  * Using `smul a b` in a group requires converting `a` from a nat to an int and
    then simplifying `smulg ↑a b` using `subst_into_smul_upcast`
  * Using `smulg` in a monoid is impossible (or at least out of scope),
    because you need a group argument to write a `smulg` term -/
def evalSMul' (eval : Expr → M (NormalExpr × Expr))
    (is_smulg : Bool) (orig e₁ e₂ : Expr) : M (NormalExpr × Expr) 
goal: Mathlib.Tactic.Abel.M (Mathlib.Tactic.Abel.NormalExpr × Lean.Expr)

full_name: Mathlib.Tactic.Abel.eval
code: /-- Evaluate an expression into its `abel` normal form, by recursing into subexpressions. -/
partial def eval (e : Expr) : M (NormalExpr × Expr) 
goal: Mathlib.Tactic.Abel.M (Mathlib.Tactic.Abel.NormalExpr × Lean.Expr)

full_name: Mathlib.Tactic.Abel.abel1
code: /-- Tactic for solving equations in the language of
*additive*, commutative monoids and groups.
This version of `abel` fails if the target is not an equality
that is provable by the axioms of commutative monoids/groups.

`abel1!` will use a more aggressive reducibility setting to identify atoms.
This can prove goals that `abel` cannot, but is more expensive.
-/
syntax (name := abel1) "abel1" "!"? : tactic
goal: Lean.ParserDescr

full_name: Mathlib.Tactic.Abel._aux_Mathlib_Tactic_Abel___elabRules_Mathlib_Tactic_Abel_abel1_1
code: /-- The `abel1` tactic, which solves equations in the language of commutative additive groups
(or monoids). -/
elab_rules : tactic | `(tactic| abel1 $[!%$tk]?) => withMainContext do
  let tm := if tk.isSome then .default else .reducible
  let some (_, e₁, e₂) := (← whnfR <| ← getMainTarget).eq?
    | throwError "abel1 requires an equality goal"
  trace[abel] "running on an equality `{e₁} = {e₂}`."
  let c ← mkContext e₁
  closeMainGoal <| ← AtomM.run tm <| ReaderT.run (r := c) do
    let (e₁', p₁) ← eval e₁
    trace[abel] "found `{p₁}`, a proof that `{e₁} = {e₁'.e}`"
    let (e₂', p₂) ← eval e₂
    trace[abel] "found `{p₂}`, a proof that `{e₂} = {e₂'.e}`"
    unless ← isDefEq e₁' e₂' do
      throwError "abel1 found that the two sides were not equal"
    trace[abel] "verified that the simplified forms are identical"
    mkEqTrans p₁ (← mkEqSymm p₂)
goal: Lean.Elab.Tactic.Tactic

full_name: Mathlib.Tactic.Abel.abel1!
code: macro (name := abel1!) "abel1!" : tactic => `(tactic| abel1 !)
goal: Lean.ParserDescr

full_name: Mathlib.Tactic.Abel._aux_Mathlib_Tactic_Abel___macroRules_Mathlib_Tactic_Abel_abel1!_1
code: macro (name := abel1!) "abel1!" : tactic => `(tactic| abel1 !)
goal: Lean.Macro

full_name: Mathlib.Tactic.Abel.term_eq
code: theorem term_eq {α : Type*} [AddCommMonoid α] (n : ℕ) (x a : α) : term n x a = n • x + a 
goal: Mathlib.Tactic.Abel.term n x a = n • x + a

full_name: Mathlib.Tactic.Abel.termg_eq
code: /-- A type synonym used by `abel` to represent `n • x + a` in an additive commutative group. -/
theorem termg_eq {α : Type*} [AddCommGroup α] (n : ℤ) (x a : α) : termg n x a = n • x + a 
goal: Mathlib.Tactic.Abel.termg n x a = n • x + a

full_name: Mathlib.Tactic.Abel.NormalExpr.isAtom
code: /-- True if this represents an atomic expression. -/
def NormalExpr.isAtom : NormalExpr → Bool
  
goal: Mathlib.Tactic.Abel.NormalExpr → Bool

full_name: Mathlib.Tactic.Abel.AbelMode
code: /-- The normalization style for `abel_nf`. -/
inductive AbelMode where
  /-- The default form -/
  | term
  /-- Raw form: the representation `abel` uses internally. -/
  | raw
goal: Type

full_name: Mathlib.Tactic.Abel.AbelMode.raw
code: /-- The normalization style for `abel_nf`. -/
inductive AbelMode where
  /-- The default form -/
  | term
  /-- Raw form: the representation `abel` uses internally. -/
  | raw
goal: Mathlib.Tactic.Abel.AbelMode

full_name: Mathlib.Tactic.Abel.AbelMode.term
code: /-- The normalization style for `abel_nf`. -/
inductive AbelMode where
  /-- The default form -/
  | term
  /-- Raw form: the representation `abel` uses internally. -/
  | raw
goal: Mathlib.Tactic.Abel.AbelMode

full_name: Mathlib.Tactic.Abel.AbelNF.Config.red
code: /-- Configuration for `abel_nf`. -/
structure AbelNF.Config where
  /-- the reducibility setting to use when comparing atoms for defeq -/
  red := TransparencyMode.reducible
  /-- if true, atoms inside ring expressions will be reduced recursively -/
  recursive := true
  /-- The normalization style. -/
  mode := AbelMode.term
goal: Lean.Meta.TransparencyMode

full_name: Mathlib.Tactic.Abel.AbelNF.Config.mode
code: /-- Configuration for `abel_nf`. -/
structure AbelNF.Config where
  /-- the reducibility setting to use when comparing atoms for defeq -/
  red := TransparencyMode.reducible
  /-- if true, atoms inside ring expressions will be reduced recursively -/
  recursive := true
  /-- The normalization style. -/
  mode := AbelMode.term
goal: Mathlib.Tactic.Abel.AbelMode

full_name: Mathlib.Tactic.Abel.AbelNF.Config
code: /-- Configuration for `abel_nf`. -/
structure AbelNF.Config where
  /-- the reducibility setting to use when comparing atoms for defeq -/
  red := TransparencyMode.reducible
  /-- if true, atoms inside ring expressions will be reduced recursively -/
  recursive := true
  /-- The normalization style. -/
  mode := AbelMode.term
goal: Type

full_name: Mathlib.Tactic.Abel.AbelNF.Config.recursive
code: /-- Configuration for `abel_nf`. -/
structure AbelNF.Config where
  /-- the reducibility setting to use when comparing atoms for defeq -/
  red := TransparencyMode.reducible
  /-- if true, atoms inside ring expressions will be reduced recursively -/
  recursive := true
  /-- The normalization style. -/
  mode := AbelMode.term
goal: Bool

full_name: Mathlib.Tactic.Abel.eval._@.Mathlib.Tactic.Abel._hyg.7530
code: /-- Function elaborating `AbelNF.Config`. -/
declare_config_elab elabAbelNFConfig AbelNF.Config
goal: Lean.Expr → Lean.Elab.TermElabM Mathlib.Tactic.Abel.AbelNF.Config

full_name: Mathlib.Tactic.Abel.elabAbelNFConfig
code: /-- Function elaborating `AbelNF.Config`. -/
declare_config_elab elabAbelNFConfig AbelNF.Config
goal: Lean.Syntax → Lean.Elab.TermElabM Mathlib.Tactic.Abel.AbelNF.Config

full_name: Mathlib.Tactic.Abel.evalUnsafe._@.Mathlib.Tactic.Abel._hyg.7530
code: /-- Function elaborating `AbelNF.Config`. -/
declare_config_elab elabAbelNFConfig AbelNF.Config
goal: Lean.Expr → Lean.Elab.TermElabM Mathlib.Tactic.Abel.AbelNF.Config

full_name: Mathlib.Tactic.Abel.abelNFCore.go
code: /--
The core of `abel_nf`, which rewrites the expression `e` into `abel` normal form.

* `s`: a reference to the mutable state of `abel`, for persisting across calls.
  This ensures that atom ordering is used consistently.
* `cfg`: the configuration options
* `e`: the expression to rewrite
-/
partial def abelNFCore
    (s : IO.Ref AtomM.State) (cfg : AbelNF.Config) (e : Expr) : MetaM Simp.Result 
goal: Lean.MetaM Lean.Meta.Simp.Result

full_name: Mathlib.Tactic.Abel.abelNFCore.evalAtom
code: /--
The core of `abel_nf`, which rewrites the expression `e` into `abel` normal form.

* `s`: a reference to the mutable state of `abel`, for persisting across calls.
  This ensures that atom ordering is used consistently.
* `cfg`: the configuration options
* `e`: the expression to rewrite
-/
partial def abelNFCore
    (s : IO.Ref AtomM.State) (cfg : AbelNF.Config) (e : Expr) : MetaM Simp.Result 
goal: Lean.Expr → Lean.MetaM Lean.Meta.Simp.Result

full_name: Mathlib.Tactic.Abel.abelNFCore
code: /--
The core of `abel_nf`, which rewrites the expression `e` into `abel` normal form.

* `s`: a reference to the mutable state of `abel`, for persisting across calls.
  This ensures that atom ordering is used consistently.
* `cfg`: the configuration options
* `e`: the expression to rewrite
-/
partial def abelNFCore
    (s : IO.Ref AtomM.State) (cfg : AbelNF.Config) (e : Expr) : MetaM Simp.Result 
goal: Lean.MetaM Lean.Meta.Simp.Result

full_name: Mathlib.Tactic.Abel.abelNFTarget
code: /-- Use `abel_nf` to rewrite the main goal. -/
def abelNFTarget (s : IO.Ref AtomM.State) (cfg : AbelNF.Config) : TacticM Unit 
goal: Lean.Elab.Tactic.TacticM Unit

full_name: Mathlib.Tactic.Abel.abelNFLocalDecl
code: /-- Use `abel_nf` to rewrite hypothesis `h`. -/
def abelNFLocalDecl (s : IO.Ref AtomM.State) (cfg : AbelNF.Config) (fvarId : FVarId) :
    TacticM Unit 
goal: Lean.Elab.Tactic.TacticM Unit

full_name: Mathlib.Tactic.Abel.abel_term
code: /-- Unsupported legacy syntax from mathlib3, which allowed passing additional terms to `abel`. -/
syntax (name := abel_term) "abel" (&" raw" <|> &" term")? (location)? : tactic
goal: Lean.ParserDescr

full_name: Mathlib.Tactic.Abel.abel!_term
code: /-- Unsupported legacy syntax from mathlib3, which allowed passing additional terms to `abel!`. -/
syntax (name := abel!_term) "abel!" (&" raw" <|> &" term")? (location)? : tactic
goal: Lean.ParserDescr

full_name: Mathlib.Tactic.Abel._aux_Mathlib_Tactic_Abel___elabRules_Mathlib_Tactic_Abel_abelNF_1
code: /--
Simplification tactic for expressions in the language of abelian groups,
which rewrites all group expressions into a normal form.
* `abel_nf!` will use a more aggressive reducibility setting to identify atoms.
* `abel_nf (config := cfg)` allows for additional configuration:
  * `red`: the reducibility setting (overridden by `!`)
  * `recursive`: if true, `abel_nf` will also recurse into atoms
* `abel_nf` works as both a tactic and a conv tactic.
  In tactic mode, `abel_nf at h` can be used to rewrite in a hypothesis.
-/
elab (name := abelNF) "abel_nf" tk:"!"? cfg:(config ?) loc:(location)? : tactic => do
  let mut cfg ← elabAbelNFConfig cfg
  if tk.isSome then cfg := { cfg with red := .default }
  let loc := (loc.map expandLocation).getD (.targets #[] true)
  let s ← IO.mkRef {}
  withLocation loc (abelNFLocalDecl s cfg) (abelNFTarget s cfg)
    fun _ ↦ throwError "abel_nf made no progress"
goal: Lean.Elab.Tactic.Tactic

full_name: Mathlib.Tactic.Abel.abelNF
code: /--
Simplification tactic for expressions in the language of abelian groups,
which rewrites all group expressions into a normal form.
* `abel_nf!` will use a more aggressive reducibility setting to identify atoms.
* `abel_nf (config := cfg)` allows for additional configuration:
  * `red`: the reducibility setting (overridden by `!`)
  * `recursive`: if true, `abel_nf` will also recurse into atoms
* `abel_nf` works as both a tactic and a conv tactic.
  In tactic mode, `abel_nf at h` can be used to rewrite in a hypothesis.
-/
elab (name := abelNF) "abel_nf" tk:"!"? cfg:(config ?) loc:(location)? : tactic => do
  let mut cfg ← elabAbelNFConfig cfg
  if tk.isSome then cfg := { cfg with red := .default }
  let loc := (loc.map expandLocation).getD (.targets #[] true)
  let s ← IO.mkRef {}
  withLocation loc (abelNFLocalDecl s cfg) (abelNFTarget s cfg)
    fun _ ↦ throwError "abel_nf made no progress"
goal: Lean.ParserDescr

full_name: Mathlib.Tactic.Abel._aux_Mathlib_Tactic_Abel___macroRules_Mathlib_Tactic_Abel_tacticAbel_nf!___1
code: macro "abel_nf!" cfg:(config)? loc:(location)? : tactic =>
  `(tactic| abel_nf ! $(cfg)? $(loc)?)
goal: Lean.Macro

full_name: Mathlib.Tactic.Abel.tacticAbel_nf!__
code: macro "abel_nf!" cfg:(config)? loc:(location)? : tactic =>
  `(tactic| abel_nf ! $(cfg)? $(loc)?)
goal: Lean.ParserDescr

full_name: Mathlib.Tactic.Abel.abelNFConv
code: @[inherit_doc abelNF] syntax (name := abelNFConv) "abel_nf" "!"? (config)? : conv
goal: Lean.ParserDescr

full_name: Mathlib.Tactic.Abel.elabAbelNFConv
code: /-- Elaborator for the `abel_nf` tactic. -/
@[tactic abelNFConv] def elabAbelNFConv : Tactic 
goal: Lean.Elab.Tactic.Tactic

full_name: Mathlib.Tactic.Abel._aux_Mathlib_Tactic_Abel___macroRules_Mathlib_Tactic_Abel_convAbel_nf!__1
code: macro "abel_nf!" cfg:(config)? : conv => `(conv| abel_nf ! $(cfg)?)
goal: Lean.Macro

full_name: Mathlib.Tactic.Abel.convAbel_nf!_
code: macro "abel_nf!" cfg:(config)? : conv => `(conv| abel_nf ! $(cfg)?)
goal: Lean.ParserDescr

full_name: Mathlib.Tactic.Abel.abel
code: macro (name := abel) "abel" : tactic =>
  `(tactic| first | abel1 | try_this abel_nf)
goal: Lean.ParserDescr

full_name: Mathlib.Tactic.Abel._aux_Mathlib_Tactic_Abel___macroRules_Mathlib_Tactic_Abel_abel_1
code: macro (name := abel) "abel" : tactic =>
  `(tactic| first | abel1 | try_this abel_nf)
goal: Lean.Macro

full_name: Mathlib.Tactic.Abel.tacticAbel!
code: macro "abel!" : tactic =>
  `(tactic| first | abel1! | try_this abel_nf!)
goal: Lean.ParserDescr

full_name: Mathlib.Tactic.Abel._aux_Mathlib_Tactic_Abel___macroRules_Mathlib_Tactic_Abel_tacticAbel!_1
code: macro "abel!" : tactic =>
  `(tactic| first | abel1! | try_this abel_nf!)
goal: Lean.Macro

full_name: Mathlib.Tactic.Abel._aux_Mathlib_Tactic_Abel___macroRules_Mathlib_Tactic_Abel_abelConv_1
code: macro (name := abelConv) "abel" : conv =>
  `(conv| first | discharge => abel1 | try_this abel_nf)
goal: Lean.Macro

full_name: Mathlib.Tactic.Abel.abelConv
code: macro (name := abelConv) "abel" : conv =>
  `(conv| first | discharge => abel1 | try_this abel_nf)
goal: Lean.ParserDescr

full_name: Mathlib.Tactic.Abel.convAbel!
code: macro "abel!" : conv =>
  `(conv| first | discharge => abel1! | try_this abel_nf!)
goal: Lean.ParserDescr

full_name: Mathlib.Tactic.Abel._aux_Mathlib_Tactic_Abel___macroRules_Mathlib_Tactic_Abel_convAbel!_1
code: macro "abel!" : conv =>
  `(conv| first | discharge => abel1! | try_this abel_nf!)
goal: Lean.Macro