ruc-ai4math/mathlib_handler_benchmark_410 huggingface dataset:
File: Mathlib/Algebra/CharP/Two.lean

full_name: CharTwo.two_eq_zero
code: theorem two_eq_zero : (2 : R) = 0 
goal: 2 = 0

full_name: CharTwo.add_self_eq_zero
code: @[simp]
theorem add_self_eq_zero (x : R) : x + x = 0 
goal: x + x = 0

full_name: CharTwo.neg_eq
code: @[simp]
theorem neg_eq (x : R) : -x = x 
goal: -x = x

full_name: CharTwo.neg_eq'
code: theorem neg_eq' : Neg.neg = (id : R → R) 
goal: Neg.neg = id

full_name: CharTwo.sub_eq_add
code: @[simp]
theorem sub_eq_add (x y : R) : x - y = x + y 
goal: x - y = x + y

full_name: CharTwo.sub_eq_add'
code: theorem sub_eq_add' : HSub.hSub = ((· + ·) : R → R → R) 
goal: HSub.hSub = fun x x_1 => x + x_1

full_name: CharTwo.add_sq
code: theorem add_sq (x y : R) : (x + y) ^ 2 = x ^ 2 + y ^ 2 
goal: (x + y) ^ 2 = x ^ 2 + y ^ 2

full_name: CharTwo.add_mul_self
code: theorem add_mul_self (x y : R) : (x + y) * (x + y) = x * x + y * y 
goal: (x + y) * (x + y) = x * x + y * y

full_name: CharTwo.list_sum_sq
code: theorem list_sum_sq (l : List R) : l.sum ^ 2 = (l.map (· ^ 2)).sum 
goal: l.sum ^ 2 = (List.map (fun x => x ^ 2) l).sum

full_name: CharTwo.list_sum_mul_self
code: theorem list_sum_mul_self (l : List R) : l.sum * l.sum = (List.map (fun x => x * x) l).sum 
goal: l.sum * l.sum = (List.map (fun x => x * x) l).sum

full_name: CharTwo.multiset_sum_sq
code: theorem multiset_sum_sq (l : Multiset R) : l.sum ^ 2 = (l.map (· ^ 2)).sum 
goal: l.sum ^ 2 = (Multiset.map (fun x => x ^ 2) l).sum

full_name: CharTwo.multiset_sum_mul_self
code: theorem multiset_sum_mul_self (l : Multiset R) :
    l.sum * l.sum = (Multiset.map (fun x => x * x) l).sum 
goal: l.sum * l.sum = (Multiset.map (fun x => x * x) l).sum

full_name: CharTwo.sum_sq
code: theorem sum_sq (s : Finset ι) (f : ι → R) : (∑ i ∈ s, f i) ^ 2 = ∑ i ∈ s, f i ^ 2 
goal: (∑ i ∈ s, f i) ^ 2 = ∑ i ∈ s, f i ^ 2

full_name: CharTwo.sum_mul_self
code: theorem sum_mul_self (s : Finset ι) (f : ι → R) :
    ((∑ i ∈ s, f i) * ∑ i ∈ s, f i) = ∑ i ∈ s, f i * f i 
goal: (∑ i ∈ s, f i) * ∑ i ∈ s, f i = ∑ i ∈ s, f i * f i

full_name: neg_one_eq_one_iff
code: theorem neg_one_eq_one_iff [Nontrivial R] : (-1 : R) = 1 ↔ ringChar R = 2 
goal: -1 = 1 ↔ ringChar R = 2

full_name: orderOf_neg_one
code: @[simp]
theorem orderOf_neg_one [Nontrivial R] : orderOf (-1 : R) = if ringChar R = 2 then 1 else 2 
goal: orderOf (-1) = if ringChar R = 2 then 1 else 2
File: Mathlib/Algebra/CharP/Pi.lean

full_name: CharP.pi
code: instance pi (ι : Type u) [hi : Nonempty ι] (R : Type v) [Semiring R] (p : ℕ) [CharP R p] :
    CharP (ι → R) p 
goal: CharP (ι → R) p

full_name: CharP.pi'
code: instance pi' (ι : Type u) [Nonempty ι] (R : Type v) [CommRing R] (p : ℕ) [CharP R p] :
    CharP (ι → R) p 
goal: CharP (ι → R) p
File: Mathlib/Algebra/CharP/Subring.lean

full_name: CharP.subsemiring
code: instance subsemiring (R : Type u) [Semiring R] (p : ℕ) [CharP R p] (S : Subsemiring R) :
    CharP S p 
goal: CharP (↥S) p

full_name: CharP.subring
code: instance subring (R : Type u) [Ring R] (p : ℕ) [CharP R p] (S : Subring R) : CharP S p 
goal: CharP (↥S) p

full_name: CharP.subring'
code: instance subring' (R : Type u) [CommRing R] (p : ℕ) [CharP R p] (S : Subring R) : CharP S p 
goal: CharP (↥S) p
File: Mathlib/Algebra/CharP/Invertible.lean

full_name: invertibleOfRingCharNotDvd
code: /-- A natural number `t` is invertible in a field `K` if the characteristic of `K` does not divide
`t`. -/
def invertibleOfRingCharNotDvd {t : ℕ} (not_dvd : ¬ringChar K ∣ t) : Invertible (t : K) 
goal: Invertible ↑t

full_name: not_ringChar_dvd_of_invertible
code: theorem not_ringChar_dvd_of_invertible {t : ℕ} [Invertible (t : K)] : ¬ringChar K ∣ t 
goal: ¬ringChar K ∣ t

full_name: invertibleOfCharPNotDvd
code: /-- A natural number `t` is invertible in a field `K` of characteristic `p` if `p` does not divide
`t`. -/
def invertibleOfCharPNotDvd {p : ℕ} [CharP K p] {t : ℕ} (not_dvd : ¬p ∣ t) : Invertible (t : K) 
goal: Invertible ↑t

full_name: invertibleOfPos
code: instance invertibleOfPos [CharZero K] (n : ℕ) [NeZero n] : Invertible (n : K) 
goal: Invertible ↑n

full_name: invertibleSucc
code: instance invertibleSucc (n : ℕ) : Invertible (n.succ : K) 
goal: Invertible ↑n.succ

full_name: invertibleTwo
code: instance invertibleTwo : Invertible (2 : K) 
goal: Invertible 2

full_name: invertibleThree
code: instance invertibleThree : Invertible (3 : K) 
goal: Invertible 3
File: Mathlib/Algebra/Expr.lean

full_name: Expr.instOne
code: /-- Produce a `One` instance for `Q($α)` such that `1 : Q($α)` is `q(1 : $α)`. -/
def Expr.instOne {u : Lean.Level} (α : Q(Type u)) (_ : Q(One $α)) : One Q($α) 
goal: Q(One «$α») → One Q(«$α»)

full_name: Expr.instZero
code: /-- Produce a `Zero` instance for `Q($α)` such that `0 : Q($α)` is `q(0 : $α)`. -/
def Expr.instZero {u : Lean.Level} (α : Q(Type u)) (_ : Q(Zero $α)) : Zero Q($α) 
goal: Q(Zero «$α») → Zero Q(«$α»)

full_name: Expr.instMul
code: /-- Produce a `Mul` instance for `Q($α)` such that `x * y : Q($α)` is `q($x * $y)`. -/
def Expr.instMul {u : Lean.Level} (α : Q(Type u)) (_ : Q(Mul $α)) : Mul Q($α) 
goal: Q(Mul «$α») → Mul Q(«$α»)

full_name: Expr.instAdd
code: /-- Produce an `Add` instance for `Q($α)` such that `x + y : Q($α)` is `q($x + $y)`. -/
def Expr.instAdd {u : Lean.Level} (α : Q(Type u)) (_ : Q(Add $α)) : Add Q($α) 
goal: Q(Add «$α») → Add Q(«$α»)
File: Mathlib/Algebra/CharP/CharAndCard.lean

full_name: isUnit_iff_not_dvd_char_of_ringChar_ne_zero
code: /-- A prime `p` is a unit in a commutative ring `R` of nonzero characteristic iff it does not divide
the characteristic. -/
theorem isUnit_iff_not_dvd_char_of_ringChar_ne_zero (R : Type*) [CommRing R] (p : ℕ) [Fact p.Prime]
    (hR : ringChar R ≠ 0) : IsUnit (p : R) ↔ ¬p ∣ ringChar R 
goal: IsUnit ↑p ↔ ¬p ∣ ringChar R

full_name: isUnit_iff_not_dvd_char
code: /-- A prime `p` is a unit in a finite commutative ring `R`
iff it does not divide the characteristic. -/
theorem isUnit_iff_not_dvd_char (R : Type*) [CommRing R] (p : ℕ) [Fact p.Prime] [Finite R] :
    IsUnit (p : R) ↔ ¬p ∣ ringChar R 
goal: IsUnit ↑p ↔ ¬p ∣ ringChar R

full_name: prime_dvd_char_iff_dvd_card
code: /-- The prime divisors of the characteristic of a finite commutative ring are exactly
the prime divisors of its cardinality. -/
theorem prime_dvd_char_iff_dvd_card {R : Type*} [CommRing R] [Fintype R] (p : ℕ) [Fact p.Prime] :
    p ∣ ringChar R ↔ p ∣ Fintype.card R 
goal: p ∣ ringChar R ↔ p ∣ Fintype.card R

full_name: not_isUnit_prime_of_dvd_card
code: /-- A prime that does not divide the cardinality of a finite commutative ring `R`
is a unit in `R`. -/
theorem not_isUnit_prime_of_dvd_card {R : Type*} [CommRing R] [Fintype R] (p : ℕ) [Fact p.Prime]
    (hp : p ∣ Fintype.card R) : ¬IsUnit (p : R) 
goal: ¬IsUnit ↑p

full_name: charP_of_card_eq_prime
code: lemma charP_of_card_eq_prime {R : Type*} [NonAssocRing R] [Fintype R] (p : ℕ) [hp : Fact p.Prime]
    (hR : Fintype.card R = p) : CharP R p 
goal: CharP R p
File: Mathlib/Util/IncludeStr.lean

full_name: Mathlib.Util._aux_Mathlib_Util_IncludeStr___elabRules_Mathlib_Util_includeStr_1
code: /-- A term macro that includes the content of a file, as a string. -/
elab (name := includeStr) "include_str " str:str : term => do
  let some str := str.1.isStrLit? | Lean.Elab.throwUnsupportedSyntax
  let srcPath := System.FilePath.mk (← Lean.MonadLog.getFileName)
  let some srcDir := srcPath.parent | throwError "{srcPath} not in a valid directory"
  let path := srcDir / str
  Lean.mkStrLit <$> IO.FS.readFile path
goal: Lean.Elab.Term.TermElab

full_name: Mathlib.Util.includeStr
code: /-- A term macro that includes the content of a file, as a string. -/
elab (name := includeStr) "include_str " str:str : term => do
  let some str := str.1.isStrLit? | Lean.Elab.throwUnsupportedSyntax
  let srcPath := System.FilePath.mk (← Lean.MonadLog.getFileName)
  let some srcDir := srcPath.parent | throwError "{srcPath} not in a valid directory"
  let path := srcDir / str
  Lean.mkStrLit <$> IO.FS.readFile path
goal: Lean.ParserDescr
File: Mathlib/Util/WithWeakNamespace.lean

full_name: Lean.Elab.Command.resolveNamespace
code: /-- Adds the name to the namespace, `_root_`-aware.
```
resolveNamespace `A `B.b == `A.B.b
resolveNamespace `A `_root_.B.c == `B.c
```
-/
def resolveNamespace (ns : Name) : Name → Name
  
goal: Lean.Name → Lean.Name

full_name: Lean.Elab.Command.withWeakNamespace
code: /-- Changes the current namespace without causing scoped things to go out of scope -/
def withWeakNamespace {α : Type} (ns : Name) (m : CommandElabM α) : CommandElabM α 
goal: Lean.Elab.Command.CommandElabM α

full_name: Lean.Elab.Command._aux_Mathlib_Util_WithWeakNamespace___elabRules_Lean_Elab_Command_commandWith_weak_namespace___1
code: /-- Changes the current namespace without causing scoped things to go out of scope -/
elab "with_weak_namespace " ns:ident cmd:command : command =>
  withWeakNamespace ns.getId (elabCommand cmd)
goal: Lean.Elab.Command.CommandElab

full_name: Lean.Elab.Command.commandWith_weak_namespace__
code: /-- Changes the current namespace without causing scoped things to go out of scope -/
elab "with_weak_namespace " ns:ident cmd:command : command =>
  withWeakNamespace ns.getId (elabCommand cmd)
goal: Lean.ParserDescr
File: Mathlib/Util/Time.lean

full_name: timeCmd
code: syntax (name := timeCmd) "#time " command : command
goal: Lean.ParserDescr

full_name: timeCmdElab
code: /--
Time the elaboration of a command, and print the result (in milliseconds).

Example usage:
```
set_option maxRecDepth 100000 in
#time example : (List.range 500).length = 500 := rfl
```
-/
@[command_elab timeCmd] def timeCmdElab : CommandElab
  
goal: Lean.Elab.Command.CommandElab
File: Mathlib/Algebra/Associated/OrderedCommMonoid.lean

full_name: Associates.instOrderedCommMonoid
code: instance instOrderedCommMonoid : OrderedCommMonoid (Associates α) 
goal: OrderedCommMonoid (Associates α)

full_name: Associates.instCanonicallyOrderedCommMonoid
code: instance : CanonicallyOrderedCommMonoid (Associates α) 
goal: CanonicallyOrderedCommMonoid (Associates α)
File: Mathlib/Algebra/BigOperators/Module.lean

full_name: Finset._aux_Mathlib_Algebra_BigOperators_Module___macroRules_Finset_termG__1
code: local notation "G " n:80 => ∑ i ∈ range n, g i
goal: Lean.Macro

full_name: Finset.sum_Ico_by_parts
code: /-- **Summation by parts**, also known as **Abel's lemma** or an **Abel transformation** -/
theorem sum_Ico_by_parts (hmn : m < n) :
    ∑ i ∈ Ico m n, f i • g i =
      f (n - 1) • G n - f m • G m - ∑ i ∈ Ico m (n - 1), (f (i + 1) - f i) • G (i + 1) 
goal: ∑ i ∈ Finset.Ico m n, f i • g i =
  f (n - 1) • ∑ i ∈ Finset.range n, g i - f m • ∑ i ∈ Finset.range m, g i -
    ∑ i ∈ Finset.Ico m (n - 1), (f (i + 1) - f i) • ∑ i ∈ Finset.range (i + 1), g i

full_name: Finset.sum_range_by_parts
code: /-- **Summation by parts** for ranges -/
theorem sum_range_by_parts :
    ∑ i ∈ range n, f i • g i =
      f (n - 1) • G n - ∑ i ∈ range (n - 1), (f (i + 1) - f i) • G (i + 1) 
goal: ∑ i ∈ Finset.range n, f i • g i =
  f (n - 1) • ∑ i ∈ Finset.range n, g i -
    ∑ i ∈ Finset.range (n - 1), (f (i + 1) - f i) • ∑ i ∈ Finset.range (i + 1), g i
File: Mathlib/Algebra/GCDMonoid/IntegrallyClosed.lean

full_name: IsLocalization.surj_of_gcd_domain
code: theorem IsLocalization.surj_of_gcd_domain [GCDMonoid R] (M : Submonoid R) [IsLocalization M A]
    (z : A) : ∃ a b : R, IsUnit (gcd a b) ∧ z * algebraMap R A b = algebraMap R A a 
goal: ∃ a b, IsUnit (gcd a b) ∧ z * (algebraMap R A) b = (algebraMap R A) a

full_name: GCDMonoid.toIsIntegrallyClosed
code: instance (priority := 100) GCDMonoid.toIsIntegrallyClosed
    [h : Nonempty (GCDMonoid R)] : IsIntegrallyClosed R 
goal: IsIntegrallyClosed R
File: Mathlib/Util/MemoFix.lean

full_name: _private.Mathlib.Util.MemoFix.0.ObjectMap
code: private unsafe abbrev ObjectMap 
goal: Type

full_name: _private.Mathlib.Util.MemoFix.0.memoFixImplObj
code: private unsafe def memoFixImplObj (f : (Object → Object) → (Object → Object)) (a : Object) :
    Object 
goal: ShareCommon.Object

full_name: _private.Mathlib.Util.MemoFix.0.memoFixImplObj.fix
code: private unsafe def memoFixImplObj (f : (Object → Object) → (Object → Object)) (a : Object) :
    Object 
goal: ShareCommon.Object

full_name: _private.Mathlib.Util.MemoFix.0.memoFixImpl
code: private unsafe def memoFixImpl {α : Type u} {β : Type v} [Nonempty β] :
    (f : (α → β) → (α → β)) → (a : α) → β 
goal: β

full_name: memoFix
code: /-- Takes the fixpoint of `f` with caching of values that have been seen before.
Hashing makes use of a pointer hash.

This is useful for implementing tree traversal functions where
subtrees may be referenced in multiple places.
-/
@[implemented_by memoFixImpl]
opaque memoFix {α : Type u} {β : Type v} [Nonempty β] (f : (α → β) → (α → β)) : α → β
goal: α → β
File: Mathlib/Util/AddRelatedDecl.lean

full_name: Mathlib.Tactic.addRelatedDecl
code: /-- A helper function for constructing a related declaration from an existing one.

This is currently used by the attributes `reassoc` and `elementwise`,
and has been factored out to avoid code duplication.
Feel free to add features as needed for other applications.

This helper:
* calls `addDeclarationRanges`, so jump-to-definition works,
* copies the `protected` status of the existing declaration, and
* supports copying attributes.

Arguments:
* `src : Name` is the existing declaration that we are modifying.
* `suffix : String` will be appended to `src` to form the name of the new declaration.
* `ref : Syntax` is the syntax where the user requested the related declaration.
* `construct type value levels : MetaM (Expr × List Name)`
  given the type, value, and universe variables of the original declaration,
  should construct the value of the new declaration,
  along with the names of its universe variables.
* `attrs` is the attributes that should be applied to both the new and the original declaration,
  e.g. in the usage `@[reassoc (attr := simp)]`.
  We apply it to both declarations, to have the same behavior as `to_additive`, and to shorten some
  attribute commands. Note that `@[elementwise (attr := simp), reassoc (attr := simp)]` will try
  to apply `simp` twice to the current declaration, but that causes no issues.
-/
def addRelatedDecl (src : Name) (suffix : String) (ref : Syntax)
    (attrs? : Option (Syntax.TSepArray `Lean.Parser.Term.attrInstance ","))
    (construct : Expr → Expr → List Name → MetaM (Expr × List Name)) :
    MetaM Unit 
goal: Lean.MetaM Unit
File: Mathlib/Util/TermBeta.lean

full_name: Mathlib.Util.TermBeta.betaStx
code: /-- `beta% t` elaborates `t` and then if the result is in the form
`f x1 ... xn` where `f` is a (nested) lambda expression,
it will substitute all of its arguments by beta reduction.
This does not recursively do beta reduction, nor will it do
beta reduction of subexpressions.

In particular, `t` is elaborated, its metavariables are instantiated,
and then `Lean.Expr.headBeta` is applied. -/
syntax (name := betaStx) "beta% " term : term
goal: Lean.ParserDescr

full_name: Mathlib.Util.TermBeta.elabBeta
code: @[term_elab betaStx, inherit_doc betaStx]
def elabBeta : TermElab 
goal: Lean.Elab.Term.TermElab
File: Mathlib/Util/Qq.lean

full_name: Qq.inferTypeQ'
code: /-- Variant of `inferTypeQ` that yields a type in `Type u` rather than `Sort u`.
Throws an error if the type is a `Prop` or if it's otherwise not possible to represent
the universe as `Type u` (for example due to universe level metavariables). -/
-- See https://leanprover.zulipchat.com/#narrow/stream/287929-mathlib4/topic/Using.20.60QQ.60.20when.20you.20only.20have.20an.20.60Expr.60/near/303349037
def inferTypeQ' (e : Expr) : MetaM ((u : Level) × (α : Q(Type $u)) × Q($α)) 
goal: Lean.MetaM
  ((u : Lean.Level) ×
    (α :
      let u := u;
      Q(Type u)) ×
      Q(«$α»))

full_name: Qq.QuotedDefEq.rfl
code: theorem QuotedDefEq.rfl {u : Level} {α : Q(Sort u)} {a : Q($α)} : @QuotedDefEq u α a a 
goal: «$a» =Q «$a»
File: Mathlib/Util/Tactic.lean

full_name: Mathlib.Tactic.modifyMetavarDecl
code: /--
`modifyMetavarDecl mvarId f` updates the `MetavarDecl` for `mvarId` with `f`.
Conditions on `f`:

- The target of `f mdecl` is defeq to the target of `mdecl`.
- The local context of `f mdecl` must contain the same fvars as the local
  context of `mdecl`. For each fvar in the local context of `f mdecl`, the type
  (and value, if any) of the fvar must be defeq to the corresponding fvar in
  the local context of `mdecl`.

If `mvarId` does not refer to a declared metavariable, nothing happens.
-/
def modifyMetavarDecl [MonadMCtx m] (mvarId : MVarId)
    (f : MetavarDecl → MetavarDecl) : m Unit 
goal: m Unit

full_name: Mathlib.Tactic.modifyTarget
code: /--
`modifyTarget mvarId f` updates the target of the metavariable `mvarId` with
`f`. For any `e`, `f e` must be defeq to `e`. If `mvarId` does not refer to
a declared metavariable, nothing happens.
-/
def modifyTarget [MonadMCtx m] (mvarId : MVarId) (f : Expr → Expr) : m Unit 
goal: m Unit

full_name: Mathlib.Tactic.modifyLocalContext
code: /--
`modifyLocalContext mvarId f` updates the local context of the metavariable
`mvarId` with `f`. The new local context must contain the same fvars as the old
local context and the types (and values, if any) of the fvars in the new local
context must be defeq to their equivalents in the old local context.

If `mvarId` does not refer to a declared metavariable, nothing happens.
-/
def modifyLocalContext [MonadMCtx m] (mvarId : MVarId)
    (f : LocalContext → LocalContext) : m Unit 
goal: m Unit

full_name: Mathlib.Tactic.modifyLocalDecl
code: /--
`modifyLocalDecl mvarId fvarId f` updates the local decl `fvarId` in the local
context of `mvarId` with `f`. `f` must leave the `fvarId` and `index` of the
`LocalDecl` unchanged. The type of the new `LocalDecl` must be defeq to the type
of the old `LocalDecl` (and the same applies to the value of the `LocalDecl`, if
any).

If `mvarId` does not refer to a declared metavariable or if `fvarId` does not
exist in the local context of `mvarId`, nothing happens.
-/
def modifyLocalDecl [MonadMCtx m] (mvarId : MVarId) (fvarId : FVarId)
    (f : LocalDecl → LocalDecl) : m Unit 
goal: m Unit
File: Mathlib/Util/GetAllModules.lean

full_name: getAllFiles
code: /-- `getAllFiles git ml` takes all `.lean` files in the directory `ml`
(recursing into sub-directories) and returns the `Array` of `String`s
```
#[file₁, ..., fileₙ]
```
of all their file names. These are not sorted in general.

The input `git` is a `Bool`ean flag:
* `true` means that the command uses `git ls-files` to find the relevant files;
* `false` means that the command recursively scans all dirs searching for `.lean` files.
-/
def getAllFiles (git : Bool) (ml : String) : IO (Array System.FilePath) 
goal: IO (Array System.FilePath)

full_name: getAllModulesSorted
code: /-- Like `getAllFiles`, but return an array of *module* names instead,
i.e. names of the form `Mathlib.Algebra.Algebra.Basic`.
In addition, these names are sorted in a platform-independent order. -/
def getAllModulesSorted (git : Bool) (ml : String) : IO (Array String) 
goal: IO (Array String)
File: Mathlib/Util/DischargerAsTactic.lean

full_name: wrapSimpDischarger
code: /-- Wrap an simp discharger (a function `Expr → SimpM (Option Expr)`) as a tactic,
so that it can be passed as an argument to `simp (discharger := foo)`.
This is inverse to `mkDischargeWrapper`. -/
def wrapSimpDischarger (dis : Simp.Discharge) : TacticM Unit 
goal: Lean.Elab.Tactic.TacticM Unit
File: Mathlib/Util/Delaborators.lean

full_name: PiNotation.piNotation
code: /-- Dependent function type (a "pi type"). The notation `Π x : α, β x` can
also be written as `(x : α) → β x`. -/
-- A direct copy of forall notation but with `Π`/`Pi` instead of `∀`/`Forall`.
@[term_parser]
def piNotation 
goal: Lean.Parser.Parser

full_name: PiNotation.«termΠ__,_»
code: /-- Dependent function type (a "pi type"). The notation `Π x ∈ s, β x` is
short for `Π x, x ∈ s → β x`. -/
-- A copy of forall notation from `Batteries.Util.ExtendedBinder` for pi notation
syntax "Π " binderIdent binderPred ", " term : term
goal: Lean.ParserDescr

full_name: PiNotation.«_aux_Mathlib_Util_Delaborators___macroRules_PiNotation_termΠ__,__1»
code: macro_rules
  | `(Π $x:ident $pred:binderPred, $p) => `(Π $x:ident, satisfies_binder_pred% $x $pred → $p)
  | `(Π _ $pred:binderPred, $p) => `(Π x, satisfies_binder_pred% x $pred → $p)
goal: Lean.Macro

full_name: PiNotation.replacePiNotation
code: /-- Since pi notation and forall notation are interchangeable, we can
parse it by simply using the pre-existing forall parser. -/
@[macro PiNotation.piNotation] def replacePiNotation : Lean.Macro
  
goal: Lean.Macro

full_name: PiNotation.delabPi
code: /-- Override the Lean 4 pi notation delaborator with one that prints cute binders
such as `∀ ε > 0`. -/
@[delab forallE]
def delabPi : Delab 
goal: Lean.PrettyPrinter.Delaborator.Delab

full_name: PiNotation.delabPi'
code: /-- Override the Lean 4 pi notation delaborator with one that uses `Π` and prints
cute binders such as `∀ ε > 0`.
Note that this takes advantage of the fact that `(x : α) → p x` notation is
never used for propositions, so we can match on this result and rewrite it. -/
@[scoped delab forallE]
def delabPi' : Delab 
goal: Lean.PrettyPrinter.Delaborator.Delab

full_name: exists_delab
code: /-- Delaborator for existential quantifier, including extended binders. -/
-- TODO: reduce the duplication in this code
@[delab app.Exists]
def exists_delab : Delab 
goal: Lean.PrettyPrinter.Delaborator.Delab

full_name: delab_not_in
code: /-- Delaborator for `∉`. -/
@[delab app.Not] def delab_not_in 
goal: Lean.PrettyPrinter.Delaborator.Delab
File: Mathlib/Util/SynthesizeUsing.lean

full_name: synthesizeUsing
code: /--
`synthesizeUsing type tac` synthesizes an element of type `type` using tactic `tac`.

The tactic `tac` is allowed to leave goals open, and these remain as metavariables in the
returned expression.
-/
-- In Lean3 this was called `solve_aux`,
-- and took a `TacticM α` and captured the produced value in `α`.
-- As this was barely used, we've simplified here.
def synthesizeUsing {u : Level} (type : Q(Sort u)) (tac : TacticM Unit) :
    MetaM (List MVarId × Q($type)) 
goal: Lean.MetaM (List Lean.MVarId × Q(«$type»))

full_name: synthesizeUsing'
code: /--
`synthesizeUsing type tac` synthesizes an element of type `type` using tactic `tac`.

The tactic must solve for all goals, in contrast to `synthesizeUsing`.
-/
def synthesizeUsing' {u : Level} (type : Q(Sort u)) (tac : TacticM Unit) : MetaM Q($type) 
goal: Lean.MetaM Q(«$type»)

full_name: synthesizeUsingTactic
code: /--
`synthesizeUsing type tacticSyntax` synthesizes an element of type `type` by evaluating the
given tactic syntax.

Example:
```lean
let (gs, e) ← synthesizeUsingTactic ty (← `(tactic| congr!))
```

The tactic `tac` is allowed to leave goals open, and these remain as metavariables in the
returned expression.
-/
def synthesizeUsingTactic {u : Level} (type : Q(Sort u)) (tac : Syntax) :
    MetaM (List MVarId × Q($type)) 
goal: Lean.MetaM (List Lean.MVarId × Q(«$type»))

full_name: synthesizeUsingTactic'
code: /--
`synthesizeUsing' type tacticSyntax` synthesizes an element of type `type` by evaluating the
given tactic syntax.

Example:
```lean
let e ← synthesizeUsingTactic' ty (← `(tactic| norm_num))
```

The tactic must solve for all goals, in contrast to `synthesizeUsingTactic`.

If you need to insert expressions into a tactic proof, then you might use `synthesizeUsing'`
directly, since the `TacticM` monad has access to the `TermElabM` monad. For example, here
is a term elaborator that wraps the `simp at ...` tactic:
```
def simpTerm (e : Expr) : MetaM Expr := do
  let mvar ← Meta.mkFreshTypeMVar
  let e' ← synthesizeUsing' mvar
    (do evalTactic (← `(tactic| have h := $(← Term.exprToSyntax e); simp at h; exact h)))
  -- Note: `simp` does not always insert type hints, so to ensure that we get a term
  -- with the simplified type (as opposed to one that is merely defeq), we should add
  -- a type hint ourselves.
  Meta.mkExpectedTypeHint e' mvar

elab "simpTerm% " t:term : term => do simpTerm (← Term.elabTerm t none)
```
-/
def synthesizeUsingTactic' {u : Level} (type : Q(Sort u)) (tac : Syntax) : MetaM Q($type) 
goal: Lean.MetaM Q(«$type»)