File: Mathlib/Tactic/Ring/RingNF.lean

full_name: Mathlib.Tactic.Ring.ExBase.isAtom
code: /-- True if this represents an atomic expression. -/
def ExBase.isAtom : ExBase sα a → Bool
  
goal: Mathlib.Tactic.Ring.ExBase sα a → Bool

full_name: Mathlib.Tactic.Ring.ExProd.isAtom
code: /-- True if this represents an atomic expression. -/
def ExProd.isAtom : ExProd sα a → Bool
  
goal: Mathlib.Tactic.Ring.ExProd sα a → Bool

full_name: Mathlib.Tactic.Ring.ExSum.isAtom
code: /-- True if this represents an atomic expression. -/
def ExSum.isAtom : ExSum sα a → Bool
  
goal: Mathlib.Tactic.Ring.ExSum sα a → Bool

full_name: Mathlib.Tactic.RingNF.RingMode.raw
code: /-- The normalization style for `ring_nf`. -/
inductive RingMode where
  /-- Sum-of-products form, like `x + x * y * 2 + z ^ 2`. -/
  | SOP
  /-- Raw form: the representation `ring` uses internally. -/
  | raw
  deriving Inhabited, BEq, Repr
goal: Mathlib.Tactic.RingNF.RingMode

full_name: Mathlib.Tactic.RingNF.RingMode
code: /-- The normalization style for `ring_nf`. -/
inductive RingMode where
  /-- Sum-of-products form, like `x + x * y * 2 + z ^ 2`. -/
  | SOP
  /-- Raw form: the representation `ring` uses internally. -/
  | raw
  deriving Inhabited, BEq, Repr
goal: Type

full_name: Mathlib.Tactic.RingNF.instInhabitedRingMode
code: /-- The normalization style for `ring_nf`. -/
inductive RingMode where
  /-- Sum-of-products form, like `x + x * y * 2 + z ^ 2`. -/
  | SOP
  /-- Raw form: the representation `ring` uses internally. -/
  | raw
  deriving Inhabited, BEq, Repr
goal: Inhabited Mathlib.Tactic.RingNF.RingMode

full_name: Mathlib.Tactic.RingNF.RingMode.SOP
code: /-- The normalization style for `ring_nf`. -/
inductive RingMode where
  /-- Sum-of-products form, like `x + x * y * 2 + z ^ 2`. -/
  | SOP
  /-- Raw form: the representation `ring` uses internally. -/
  | raw
  deriving Inhabited, BEq, Repr
goal: Mathlib.Tactic.RingNF.RingMode

full_name: Mathlib.Tactic.RingNF.instReprRingMode
code: /-- The normalization style for `ring_nf`. -/
inductive RingMode where
  /-- Sum-of-products form, like `x + x * y * 2 + z ^ 2`. -/
  | SOP
  /-- Raw form: the representation `ring` uses internally. -/
  | raw
  deriving Inhabited, BEq, Repr
goal: Repr Mathlib.Tactic.RingNF.RingMode

full_name: Mathlib.Tactic.RingNF.instBEqRingMode
code: BEq
goal: BEq Mathlib.Tactic.RingNF.RingMode

full_name: Mathlib.Tactic.RingNF.instReprConfig
code: /-- Configuration for `ring_nf`. -/
structure 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 := RingMode.SOP
  deriving Inhabited, BEq, Repr
goal: Repr Mathlib.Tactic.RingNF.Config

full_name: Mathlib.Tactic.RingNF.instInhabitedConfig
code: /-- Configuration for `ring_nf`. -/
structure 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 := RingMode.SOP
  deriving Inhabited, BEq, Repr
goal: Inhabited Mathlib.Tactic.RingNF.Config

full_name: Mathlib.Tactic.RingNF.Config.recursive
code: /-- Configuration for `ring_nf`. -/
structure 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 := RingMode.SOP
  deriving Inhabited, BEq, Repr
goal: Bool

full_name: Mathlib.Tactic.RingNF.Config.red
code: /-- Configuration for `ring_nf`. -/
structure 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 := RingMode.SOP
  deriving Inhabited, BEq, Repr
goal: Lean.Meta.TransparencyMode

full_name: Mathlib.Tactic.RingNF.instBEqConfig
code: /-- Configuration for `ring_nf`. -/
structure 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 := RingMode.SOP
  deriving Inhabited, BEq, Repr
goal: BEq Mathlib.Tactic.RingNF.Config

full_name: Mathlib.Tactic.RingNF.Config
code: /-- Configuration for `ring_nf`. -/
structure 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 := RingMode.SOP
  deriving Inhabited, BEq, Repr
goal: Type

full_name: Mathlib.Tactic.RingNF.Config.mode
code: /-- Configuration for `ring_nf`. -/
structure 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 := RingMode.SOP
  deriving Inhabited, BEq, Repr
goal: Mathlib.Tactic.RingNF.RingMode

full_name: Mathlib.Tactic.RingNF.evalUnsafe._@.Mathlib.Tactic.Ring.RingNF._hyg.789
code: /-- Function elaborating `RingNF.Config`. -/
declare_config_elab elabConfig Config
goal: Lean.Expr → Lean.Elab.TermElabM Mathlib.Tactic.RingNF.Config

full_name: Mathlib.Tactic.RingNF.eval._@.Mathlib.Tactic.Ring.RingNF._hyg.789
code: /-- Function elaborating `RingNF.Config`. -/
declare_config_elab elabConfig Config
goal: Lean.Expr → Lean.Elab.TermElabM Mathlib.Tactic.RingNF.Config

full_name: Mathlib.Tactic.RingNF.elabConfig
code: /-- Function elaborating `RingNF.Config`. -/
declare_config_elab elabConfig Config
goal: Lean.Syntax → Lean.Elab.TermElabM Mathlib.Tactic.RingNF.Config

full_name: Mathlib.Tactic.RingNF.Context.ctx
code: /-- The read-only state of the `RingNF` monad. -/
structure Context where
  /-- A basically empty simp context, passed to the `simp` traversal in `RingNF.rewrite`. -/
  ctx : Simp.Context
  /-- A cleanup routine, which simplifies normalized polynomials to a more human-friendly
  format. -/
  simp : Simp.Result → SimpM Simp.Result
goal: Lean.Meta.Simp.Context

full_name: Mathlib.Tactic.RingNF.Context.simp
code: /-- The read-only state of the `RingNF` monad. -/
structure Context where
  /-- A basically empty simp context, passed to the `simp` traversal in `RingNF.rewrite`. -/
  ctx : Simp.Context
  /-- A cleanup routine, which simplifies normalized polynomials to a more human-friendly
  format. -/
  simp : Simp.Result → SimpM Simp.Result
goal: Lean.Meta.Simp.Result → Lean.Meta.SimpM Lean.Meta.Simp.Result

full_name: Mathlib.Tactic.RingNF.Context
code: /-- The read-only state of the `RingNF` monad. -/
structure Context where
  /-- A basically empty simp context, passed to the `simp` traversal in `RingNF.rewrite`. -/
  ctx : Simp.Context
  /-- A cleanup routine, which simplifies normalized polynomials to a more human-friendly
  format. -/
  simp : Simp.Result → SimpM Simp.Result
goal: Type

full_name: Mathlib.Tactic.RingNF.M
code: /-- The monad for `RingNF` contains, in addition to the `AtomM` state,
a simp context for the main traversal and a simp function (which has another simp context)
to simplify normalized polynomials. -/
abbrev M 
goal: Type

full_name: Mathlib.Tactic.RingNF.rewrite
code: /--
A tactic in the `RingNF.M` monad which will simplify expression `parent` to a normal form.
* `root`: true if this is a direct call to the function.
  `RingNF.M.run` sets this to `false` in recursive mode.
-/
def rewrite (parent : Expr) (root := true) : M Simp.Result 
goal: Mathlib.Tactic.RingNF.M Lean.Meta.Simp.Result

full_name: Mathlib.Tactic.RingNF.add_assoc_rev
code: theorem add_assoc_rev (a b c : R) : a + (b + c) = a + b + c 
goal: a + (b + c) = a + b + c

full_name: Mathlib.Tactic.RingNF.mul_assoc_rev
code: theorem mul_assoc_rev (a b c : R) : a * (b * c) = a * b * c 
goal: a * (b * c) = a * b * c

full_name: Mathlib.Tactic.RingNF.mul_neg
code: theorem mul_neg {R} [Ring R] (a b : R) : a * -b = -(a * b) 
goal: a * -b = -(a * b)

full_name: Mathlib.Tactic.RingNF.add_neg
code: theorem add_neg {R} [Ring R] (a b : R) : a + -b = a - b 
goal: a + -b = a - b

full_name: Mathlib.Tactic.RingNF.nat_rawCast_0
code: theorem nat_rawCast_0 : (Nat.rawCast 0 : R) = 0 
goal: Nat.rawCast 0 = 0

full_name: Mathlib.Tactic.RingNF.nat_rawCast_1
code: theorem nat_rawCast_1 : (Nat.rawCast 1 : R) = 1 
goal: Nat.rawCast 1 = 1

full_name: Mathlib.Tactic.RingNF.nat_rawCast_2
code: theorem nat_rawCast_2 [Nat.AtLeastTwo n] : (Nat.rawCast n : R) = OfNat.ofNat n 
goal: n.rawCast = OfNat.ofNat n

full_name: Mathlib.Tactic.RingNF.int_rawCast_neg
code: theorem int_rawCast_neg {R} [Ring R] : (Int.rawCast (.negOfNat n) : R) = -Nat.rawCast n 
goal: (Int.negOfNat n).rawCast = -n.rawCast

full_name: Mathlib.Tactic.RingNF.rat_rawCast_pos
code: theorem rat_rawCast_pos {R} [DivisionRing R] :
    (Rat.rawCast (.ofNat n) d : R) = Nat.rawCast n / Nat.rawCast d 
goal: Rat.rawCast (Int.ofNat n) d = n.rawCast / d.rawCast

full_name: Mathlib.Tactic.RingNF.rat_rawCast_neg
code: theorem rat_rawCast_neg {R} [DivisionRing R] :
    (Rat.rawCast (.negOfNat n) d : R) = Int.rawCast (.negOfNat n) / Nat.rawCast d 
goal: Rat.rawCast (Int.negOfNat n) d = (Int.negOfNat n).rawCast / d.rawCast

full_name: Mathlib.Tactic.RingNF.M.run.evalAtom
code: /--
Runs a tactic in the `RingNF.M` monad, given initial data:

* `s`: a reference to the mutable state of `ring`, for persisting across calls.
  This ensures that atom ordering is used consistently.
* `cfg`: the configuration options
* `x`: the tactic to run
-/
partial def M.run
    {α : Type} (s : IO.Ref AtomM.State) (cfg : RingNF.Config) (x : M α) : MetaM α 
goal: Lean.MetaM Lean.Meta.Simp.Result

full_name: Mathlib.Tactic.RingNF.M.run
code: /--
Runs a tactic in the `RingNF.M` monad, given initial data:

* `s`: a reference to the mutable state of `ring`, for persisting across calls.
  This ensures that atom ordering is used consistently.
* `cfg`: the configuration options
* `x`: the tactic to run
-/
partial def M.run
    {α : Type} (s : IO.Ref AtomM.State) (cfg : RingNF.Config) (x : M α) : MetaM α 
goal: Lean.MetaM α

full_name: Mathlib.Tactic.RingNF.M.run.rctx
code: /--
Runs a tactic in the `RingNF.M` monad, given initial data:

* `s`: a reference to the mutable state of `ring`, for persisting across calls.
  This ensures that atom ordering is used consistently.
* `cfg`: the configuration options
* `x`: the tactic to run
-/
partial def M.run
    {α : Type} (s : IO.Ref AtomM.State) (cfg : RingNF.Config) (x : M α) : MetaM α 
goal: Mathlib.Tactic.AtomM.Context

full_name: Mathlib.Tactic.RingNF.initFn._@.Mathlib.Tactic.Ring.RingNF._hyg.2522
code: /-- Overrides the default error message in `ring1` to use a prettified version of the goal. -/
initialize ringCleanupRef.set fun e => do
  M.run (← IO.mkRef {}) { recursive := false } fun nctx _ _ =>
    return (← nctx.simp { expr := e } ({} : Lean.Meta.Simp.Methods).toMethodsRef nctx.ctx
      |>.run {}).1.expr
goal: IO Unit

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

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

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

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

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

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

full_name: Mathlib.Tactic.RingNF.ringNFConv
code: @[inherit_doc ringNF] syntax (name := ringNFConv) "ring_nf" "!"? (config)? : conv
goal: Lean.ParserDescr

full_name: Mathlib.Tactic.RingNF._aux_Mathlib_Tactic_Ring_RingNF___elabRules_Mathlib_Tactic_RingNF_ring1NF_1
code: /--
Tactic for solving equations of *commutative* (semi)rings, allowing variables in the exponent.

* This version of `ring1` uses `ring_nf` to simplify in atoms.
* The variant `ring1_nf!` will use a more aggressive reducibility setting
  to determine equality of atoms.
-/
elab (name := ring1NF) "ring1_nf" tk:"!"? cfg:(config ?) : tactic => do
  let mut cfg ← elabConfig cfg
  if tk.isSome then cfg := { cfg with red := .default }
  let s ← IO.mkRef {}
  liftMetaMAtMain fun g ↦ M.run s cfg <| proveEq g
goal: Lean.Elab.Tactic.Tactic

full_name: Mathlib.Tactic.RingNF.ring1NF
code: /--
Tactic for solving equations of *commutative* (semi)rings, allowing variables in the exponent.

* This version of `ring1` uses `ring_nf` to simplify in atoms.
* The variant `ring1_nf!` will use a more aggressive reducibility setting
  to determine equality of atoms.
-/
elab (name := ring1NF) "ring1_nf" tk:"!"? cfg:(config ?) : tactic => do
  let mut cfg ← elabConfig cfg
  if tk.isSome then cfg := { cfg with red := .default }
  let s ← IO.mkRef {}
  liftMetaMAtMain fun g ↦ M.run s cfg <| proveEq g
goal: Lean.ParserDescr

full_name: Mathlib.Tactic.RingNF.tacticRing1_nf!_
code: macro "ring1_nf!" cfg:(config)? : tactic => `(tactic| ring1_nf ! $(cfg)?)
goal: Lean.ParserDescr

full_name: Mathlib.Tactic.RingNF._aux_Mathlib_Tactic_Ring_RingNF___macroRules_Mathlib_Tactic_RingNF_tacticRing1_nf!__1
code: macro "ring1_nf!" cfg:(config)? : tactic => `(tactic| ring1_nf ! $(cfg)?)
goal: Lean.Macro

full_name: Mathlib.Tactic.RingNF.elabRingNFConv
code: /-- Elaborator for the `ring_nf` tactic. -/
@[tactic ringNFConv] def elabRingNFConv : Tactic 
goal: Lean.Elab.Tactic.Tactic

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

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

full_name: Mathlib.Tactic.RingNF.ring
code: macro (name := ring) "ring" : tactic =>
  `(tactic| first | ring1 | try_this ring_nf)
goal: Lean.ParserDescr

full_name: Mathlib.Tactic.RingNF._aux_Mathlib_Tactic_Ring_RingNF___macroRules_Mathlib_Tactic_RingNF_ring_1
code: macro (name := ring) "ring" : tactic =>
  `(tactic| first | ring1 | try_this ring_nf)
goal: Lean.Macro

full_name: Mathlib.Tactic.RingNF._aux_Mathlib_Tactic_Ring_RingNF___macroRules_Mathlib_Tactic_RingNF_tacticRing!_1
code: macro "ring!" : tactic =>
  `(tactic| first | ring1! | try_this ring_nf!)
goal: Lean.Macro

full_name: Mathlib.Tactic.RingNF.tacticRing!
code: macro "ring!" : tactic =>
  `(tactic| first | ring1! | try_this ring_nf!)
goal: Lean.ParserDescr

full_name: Mathlib.Tactic.RingNF.ringConv
code: macro (name := ringConv) "ring" : conv =>
  `(conv| first | discharge => ring1 | try_this ring_nf)
goal: Lean.ParserDescr

full_name: Mathlib.Tactic.RingNF._aux_Mathlib_Tactic_Ring_RingNF___macroRules_Mathlib_Tactic_RingNF_ringConv_1
code: macro (name := ringConv) "ring" : conv =>
  `(conv| first | discharge => ring1 | try_this ring_nf)
goal: Lean.Macro

full_name: Mathlib.Tactic.RingNF._aux_Mathlib_Tactic_Ring_RingNF___macroRules_Mathlib_Tactic_RingNF_convRing!_1
code: macro "ring!" : conv =>
  `(conv| first | discharge => ring1! | try_this ring_nf!)
goal: Lean.Macro

full_name: Mathlib.Tactic.RingNF.convRing!
code: macro "ring!" : conv =>
  `(conv| first | discharge => ring1! | try_this ring_nf!)
goal: Lean.ParserDescr