ruc-ai4math/mathlib_handler_benchmark_410 huggingface dataset:
File: Mathlib/Tactic/Spread.lean

full_name: letImplDetailStx
code: /--
Mathlib extension to preserve old behavior of structure instances.
We need to be able to `let` some implementation details that are still local instances.
Normally implementation detail fvars are not local instances,
but we need them to be implementation details so that `simp` will see them as "reducible" fvars.
-/
syntax (name := letImplDetailStx) "let_impl_detail " ident " := " term "; " term : term
goal: Lean.ParserDescr

full_name: elabLetImplDetail
code: @[term_elab letImplDetailStx, inherit_doc letImplDetailStx]
def elabLetImplDetail : TermElab 
goal: Lean.Elab.Term.TermElab

full_name: _aux_Mathlib_Tactic_Spread___macroRules_Lean_Parser_Term_structInst_1
code: macro_rules
| `({ $[$srcs,* with]? $[$fields],* $[: $ty?]? }) => show MacroM Term from do
    let mut spreads := #[]
    let mut newFields := #[]

    for field in fields do
      match field.1 with
        | `(structInstField| $name:ident := $arg) =>
          if name.getId.eraseMacroScopes == `__ then do
            spreads := spreads.push arg
          else
            newFields := newFields.push field
        | `(structInstFieldAbbrev| $_:ident) =>
          newFields := newFields.push field
        | _ =>
          throwUnsupported

    if spreads.isEmpty then throwUnsupported

    let spreadData ← withFreshMacroScope <| spreads.mapIdxM fun i spread => do
      let n := Name.num `__spread i
      return (mkIdent <| ← Macro.addMacroScope n, spread)

    let srcs := (srcs.map (·.getElems)).getD {} ++ spreadData.map Prod.fst
    let body ← `({ $srcs,* with $[$newFields],* $[: $ty?]? })
    spreadData.foldrM (init := body) fun (id, val) body => `(let_impl_detail $id := $val; $body)
goal: Lean.Macro
File: Mathlib/Tactic/Substs.lean

full_name: Mathlib.Tactic.Substs.substs
code: /--
Applies the `subst` tactic to all given hypotheses from left to right.
-/
syntax (name := substs) "substs" (colGt ppSpace ident)* : tactic
goal: Lean.ParserDescr

full_name: Mathlib.Tactic.Substs._aux_Mathlib_Tactic_Substs___macroRules_Mathlib_Tactic_Substs_substs_1
code: macro_rules
| `(tactic| substs $xs:ident*) => `(tactic| ($[subst $xs]*))
goal: Lean.Macro
File: Mathlib/Tactic/ApplyAt.lean

full_name: Mathlib.Tactic.tacticApply_At_
code: /--
`apply t at i` will use forward reasoning with `t` at the hypothesis `i`.
Explicitly, if `t : α₁ → ⋯ → αᵢ → ⋯ → αₙ` and `i` has type `αᵢ`, then this tactic will add
metavariables/goals for any terms of `αⱼ` for `j = 1, …, i-1`,
then replace the type of `i` with `αᵢ₊₁ → ⋯ → αₙ` by applying those metavariables and the
original `i`.
-/
elab "apply" t:term "at" i:ident : tactic => withSynthesize <| withMainContext do
  let f ← elabTermForApply t
  let some ldecl := (← getLCtx).findFromUserName? i.getId
    | throwErrorAt i m!"Identifier {i} not found"
  let (mvs, bis, tp) ← forallMetaTelescopeReducingUntilDefEq (← inferType f) ldecl.type
  let mainGoal ← getMainGoal
  let mainGoal ← mainGoal.tryClear ldecl.fvarId
  for (m, b) in mvs.zip bis do
    if b.isInstImplicit && !(← m.mvarId!.isAssigned) then
      try m.mvarId!.inferInstance
      catch _ => continue
  let mainGoal ← mainGoal.assert ldecl.userName tp
    (← mkAppOptM' f (mvs.pop.push ldecl.toExpr |>.map fun e => some e))
  let (_, mainGoal) ← mainGoal.intro1P
  replaceMainGoal <| [mainGoal] ++ mvs.pop.toList.map fun e => e.mvarId!
goal: Lean.ParserDescr

full_name: Mathlib.Tactic._aux_Mathlib_Tactic_ApplyAt___elabRules_Mathlib_Tactic_tacticApply_At__1
code: /--
`apply t at i` will use forward reasoning with `t` at the hypothesis `i`.
Explicitly, if `t : α₁ → ⋯ → αᵢ → ⋯ → αₙ` and `i` has type `αᵢ`, then this tactic will add
metavariables/goals for any terms of `αⱼ` for `j = 1, …, i-1`,
then replace the type of `i` with `αᵢ₊₁ → ⋯ → αₙ` by applying those metavariables and the
original `i`.
-/
elab "apply" t:term "at" i:ident : tactic => withSynthesize <| withMainContext do
  let f ← elabTermForApply t
  let some ldecl := (← getLCtx).findFromUserName? i.getId
    | throwErrorAt i m!"Identifier {i} not found"
  let (mvs, bis, tp) ← forallMetaTelescopeReducingUntilDefEq (← inferType f) ldecl.type
  let mainGoal ← getMainGoal
  let mainGoal ← mainGoal.tryClear ldecl.fvarId
  for (m, b) in mvs.zip bis do
    if b.isInstImplicit && !(← m.mvarId!.isAssigned) then
      try m.mvarId!.inferInstance
      catch _ => continue
  let mainGoal ← mainGoal.assert ldecl.userName tp
    (← mkAppOptM' f (mvs.pop.push ldecl.toExpr |>.map fun e => some e))
  let (_, mainGoal) ← mainGoal.intro1P
  replaceMainGoal <| [mainGoal] ++ mvs.pop.toList.map fun e => e.mvarId!
goal: Lean.Elab.Tactic.Tactic
File: Mathlib/Tactic/Eval.lean

full_name: Mathlib.Meta.eval_expr
code: /--
`eval% x` evaluates the term `x : X` in the interpreter, and then injects the resulting expression.

As an example:
```lean
example : 2^10 = eval% 2^10 := by
  -- goal is `2^10 = 1024`
  sorry
```
This only works if a `Lean.ToExpr X` instance is available.

Tip: you can use `show_term eval% x` to see the value of `eval% x`.
-/
syntax (name := eval_expr) "eval% " term : term
goal: Lean.ParserDescr

full_name: Mathlib.Meta.elabEvalExpr
code: @[term_elab eval_expr, inherit_doc eval_expr]
unsafe def elabEvalExpr : Lean.Elab.Term.TermElab

goal: Lean.Elab.Term.TermElab
File: Mathlib/Tactic/Coe.lean

full_name: Lean.Elab.Term.CoeImpl.elabPartiallyAppliedCoe
code: /-- Elaborator for the `(↑)`, `(⇑)`, and `(↥)` notations. -/
def elabPartiallyAppliedCoe (sym : String) (expectedType : Expr)
    (mkCoe : (expectedType x : Expr) → TermElabM Expr) : TermElabM Expr 
goal: Lean.Elab.TermElabM Lean.Expr

full_name: Lean.Elab.Term.CoeImpl.«_aux_Mathlib_Tactic_Coe___elabRules_Lean_Elab_Term_CoeImpl_term(↑)_1»
code: /-- Partially applied coercion.  Equivalent to the η-reduction of `(↑ ·)` -/
elab "(" "↑" ")" : term <= expectedType =>
  elabPartiallyAppliedCoe "↑" expectedType fun b x => do
    if b.hasExprMVar then tryPostpone
    if let .some e ← coerce? x b then
      return e
    else
      throwError "cannot coerce{indentExpr x}\nto type{indentExpr b}"
goal: Lean.Elab.Term.TermElab

full_name: Lean.Elab.Term.CoeImpl.«term(↑)»
code: /-- Partially applied coercion.  Equivalent to the η-reduction of `(↑ ·)` -/
elab "(" "↑" ")" : term <= expectedType =>
  elabPartiallyAppliedCoe "↑" expectedType fun b x => do
    if b.hasExprMVar then tryPostpone
    if let .some e ← coerce? x b then
      return e
    else
      throwError "cannot coerce{indentExpr x}\nto type{indentExpr b}"
goal: Lean.ParserDescr

full_name: Lean.Elab.Term.CoeImpl.«term(⇑)»
code: /-- Partially applied function coercion.  Equivalent to the η-reduction of `(⇑ ·)` -/
elab "(" "⇑" ")" : term <= expectedType =>
  elabPartiallyAppliedCoe "⇑" expectedType fun b x => do
    if let some ty ← coerceToFunction? x then
      ensureHasType b ty
    else
      throwError "cannot coerce to function{indentExpr x}"
goal: Lean.ParserDescr

full_name: Lean.Elab.Term.CoeImpl.«_aux_Mathlib_Tactic_Coe___elabRules_Lean_Elab_Term_CoeImpl_term(⇑)_1»
code: /-- Partially applied function coercion.  Equivalent to the η-reduction of `(⇑ ·)` -/
elab "(" "⇑" ")" : term <= expectedType =>
  elabPartiallyAppliedCoe "⇑" expectedType fun b x => do
    if let some ty ← coerceToFunction? x then
      ensureHasType b ty
    else
      throwError "cannot coerce to function{indentExpr x}"
goal: Lean.Elab.Term.TermElab

full_name: Lean.Elab.Term.CoeImpl.«term(↥)»
code: /-- Partially applied type coercion.  Equivalent to the η-reduction of `(↥ ·)` -/
elab "(" "↥" ")" : term <= expectedType =>
  elabPartiallyAppliedCoe "↥" expectedType fun b x => do
    if let some ty ← coerceToSort? x then
      ensureHasType b ty
    else
      throwError "cannot coerce to sort{indentExpr x}"
goal: Lean.ParserDescr

full_name: Lean.Elab.Term.CoeImpl.«_aux_Mathlib_Tactic_Coe___elabRules_Lean_Elab_Term_CoeImpl_term(↥)_1»
code: /-- Partially applied type coercion.  Equivalent to the η-reduction of `(↥ ·)` -/
elab "(" "↥" ")" : term <= expectedType =>
  elabPartiallyAppliedCoe "↥" expectedType fun b x => do
    if let some ty ← coerceToSort? x then
      ensureHasType b ty
    else
      throwError "cannot coerce to sort{indentExpr x}"
goal: Lean.Elab.Term.TermElab
File: Mathlib/Tactic/Continuity/Init.lean

full_name: initFn._@.Mathlib.Tactic.Continuity.Init._hyg.5
code: declare_aesop_rule_sets [Continuous]
goal: IO Unit
File: Mathlib/Tactic/RenameBVar.lean

full_name: Mathlib.Tactic.renameBVarHyp
code: /-- Renames a bound variable in a hypothesis. -/
def renameBVarHyp (mvarId : MVarId) (fvarId : FVarId) (old new : Name) :
    MetaM Unit 
goal: Lean.MetaM Unit

full_name: Mathlib.Tactic.renameBVarTarget
code: /-- Renames a bound variable in the target. -/
def renameBVarTarget (mvarId : MVarId) (old new : Name) : MetaM Unit 
goal: Lean.MetaM Unit

full_name: Mathlib.Tactic.«tacticRename_bvar_→__»
code: /--
* `rename_bvar old new` renames all bound variables named `old` to `new` in the target.
* `rename_bvar old new at h` does the same in hypothesis `h`.

```lean
example (P : ℕ → ℕ → Prop) (h : ∀ n, ∃ m, P n m) : ∀ l, ∃ m, P l m := by
  rename_bvar n q at h -- h is now ∀ (q : ℕ), ∃ (m : ℕ), P q m,
  rename_bvar m n -- target is now ∀ (l : ℕ), ∃ (n : ℕ), P k n,
  exact h -- Lean does not care about those bound variable names
```
Note: name clashes are resolved automatically.
-/
elab "rename_bvar " old:ident " → " new:ident loc?:(location)? : tactic => do
  let mvarId ← getMainGoal
  match loc? with
  | none => renameBVarTarget mvarId old.getId new.getId
  | some loc =>
    withLocation (expandLocation loc)
      (fun fvarId ↦ renameBVarHyp mvarId fvarId old.getId new.getId)
      (renameBVarTarget mvarId old.getId new.getId)
      fun _ ↦ throwError "unexpected location syntax"
goal: Lean.ParserDescr

full_name: Mathlib.Tactic.«_aux_Mathlib_Tactic_RenameBVar___elabRules_Mathlib_Tactic_tacticRename_bvar_→___1»
code: /--
* `rename_bvar old new` renames all bound variables named `old` to `new` in the target.
* `rename_bvar old new at h` does the same in hypothesis `h`.

```lean
example (P : ℕ → ℕ → Prop) (h : ∀ n, ∃ m, P n m) : ∀ l, ∃ m, P l m := by
  rename_bvar n q at h -- h is now ∀ (q : ℕ), ∃ (m : ℕ), P q m,
  rename_bvar m n -- target is now ∀ (l : ℕ), ∃ (n : ℕ), P k n,
  exact h -- Lean does not care about those bound variable names
```
Note: name clashes are resolved automatically.
-/
elab "rename_bvar " old:ident " → " new:ident loc?:(location)? : tactic => do
  let mvarId ← getMainGoal
  match loc? with
  | none => renameBVarTarget mvarId old.getId new.getId
  | some loc =>
    withLocation (expandLocation loc)
      (fun fvarId ↦ renameBVarHyp mvarId fvarId old.getId new.getId)
      (renameBVarTarget mvarId old.getId new.getId)
      fun _ ↦ throwError "unexpected location syntax"
goal: Lean.Elab.Tactic.Tactic
File: Mathlib/Tactic/Relation/Symm.lean

full_name: Lean.Expr.relSidesIfSymm?
code: /-- If `e` is the form `@R .. x y`, where `R` is a symmetric
relation, return `some (R, x, y)`.
As a special case, if `e` is `@HEq α a β b`, return ``some (`HEq, a, b)``. -/
def _root_.Lean.Expr.relSidesIfSymm? (e : Expr) : MetaM (Option (Name × Expr × Expr)) 
goal: Lean.MetaM (Option (Lean.Name × Lean.Expr × Lean.Expr))
File: Mathlib/Tactic/NoncommRing.lean

full_name: Mathlib.Tactic.NoncommRing.nat_lit_mul_eq_nsmul
code: lemma nat_lit_mul_eq_nsmul [n.AtLeastTwo] : no_index (OfNat.ofNat n) * r = n • r 
goal: OfNat.ofNat n * r = n • r

full_name: Mathlib.Tactic.NoncommRing.mul_nat_lit_eq_nsmul
code: lemma mul_nat_lit_eq_nsmul [n.AtLeastTwo] : r * no_index (OfNat.ofNat n) = n • r 
goal: r * OfNat.ofNat n = n • r

full_name: Mathlib.Tactic.NoncommRing.noncomm_ring
code: /-- A tactic for simplifying identities in not-necessarily-commutative rings.

An example:
```lean
example {R : Type*} [Ring R] (a b c : R) : a * (b + c + c - b) = 2 * a * c := by
  noncomm_ring
```

You can use `noncomm_ring [h]` to also simplify using `h`.
-/
syntax (name := noncomm_ring) "noncomm_ring"  (config)? (discharger)?
  (" [" ((simpStar <|> simpErase <|> simpLemma),*,?) "]")? : tactic
goal: Lean.ParserDescr

full_name: Mathlib.Tactic.NoncommRing._aux_Mathlib_Tactic_NoncommRing___macroRules_Mathlib_Tactic_NoncommRing_noncomm_ring_1
code: macro_rules
  | `(tactic| noncomm_ring $[$cfg]? $[$disch]? $[[$rules,*]]?) => do
    let rules' := rules.getD ⟨#[]⟩
    let tac ← `(tactic|
      (first | simp $cfg ? $disch ? only [
          -- Expand everything out.
          add_mul, mul_add, sub_eq_add_neg,
          -- Right associate all products.
          mul_assoc,
          -- Expand powers to numerals.
          pow_one, pow_zero, pow_succ,
          -- Replace multiplication by numerals with `zsmul`.
          one_mul, mul_one, zero_mul, mul_zero,
          nat_lit_mul_eq_nsmul, mul_nat_lit_eq_nsmul,
          -- Pull `zsmul n` out the front so `abel` can see them.
          mul_smul_comm, smul_mul_assoc,
          -- Pull out negations.
          neg_mul, mul_neg,
          -- user-specified simp lemmas
          $rules',*] |
        fail "`noncomm_ring` simp lemmas don't apply; try `abel` instead") <;>
      first | abel1 | abel_nf)
    -- if a manual rewrite rule is provided, we repeat the tactic
    -- (since abel might simplify and allow the rewrite to apply again)
    if rules.isSome then `(tactic| repeat1 ($tac;)) else `(tactic| $tac)
goal: Lean.Macro
File: Mathlib/Tactic/Relation/Rfl.lean

full_name: Mathlib.Tactic.rflTac
code: /--
This tactic applies to a goal whose target has the form `x ~ x`, where `~` is a reflexive
relation, that is, a relation which has a reflexive lemma tagged with the attribute [refl].
-/
def rflTac : TacticM Unit 
goal: Lean.Elab.Tactic.TacticM Unit

full_name: Lean.Expr.relSidesIfRefl?
code: /-- If `e` is the form `@R .. x y`, where `R` is a reflexive
relation, return `some (R, x, y)`.
As a special case, if `e` is `@HEq α a β b`, return ``some (`HEq, a, b)``. -/
def _root_.Lean.Expr.relSidesIfRefl? (e : Expr) : MetaM (Option (Name × Expr × Expr)) 
goal: Lean.MetaM (Option (Lean.Name × Lean.Expr × Lean.Expr))
File: Mathlib/Tactic/Rename.lean

full_name: Mathlib.Tactic.renameArg
code: syntax renameArg := term " => " ident
goal: Lean.ParserDescr

full_name: Mathlib.Tactic.rename'
code: /-- `rename' h => hnew` renames the hypothesis named `h` to `hnew`.
To rename several hypothesis, use `rename' h₁ => h₁new, h₂ => h₂new`.
You can use `rename' a => b, b => a` to swap two variables. -/
syntax (name := rename') "rename' " renameArg,+ : tactic
goal: Lean.ParserDescr

full_name: Mathlib.Tactic._aux_Mathlib_Tactic_Rename___elabRules_Mathlib_Tactic_rename'_1
code: elab_rules : tactic
  | `(tactic| rename' $[$as:term => $bs:ident],*) => do
    let ids ← getFVarIds as
    liftMetaTactic1 fun goal ↦ do
      let mut lctx ← getLCtx
      for fvar in ids, tgt in bs do
        lctx := lctx.setUserName fvar tgt.getId
      let mvarNew ← mkFreshExprMVarAt lctx (← getLocalInstances)
        (← goal.getType) MetavarKind.syntheticOpaque (← goal.getTag)
      goal.assign mvarNew
      pure mvarNew.mvarId!
    withMainContext do
      for fvar in ids, tgt in bs do
        Elab.Term.addTermInfo' tgt (mkFVar fvar)
goal: Lean.Elab.Tactic.Tactic
File: Mathlib/Tactic/Continuity.lean

full_name: _aux_Mathlib_Tactic_Continuity___macroRules_attrContinuity_1
code: macro "continuity" : attr =>
  `(attr|aesop safe apply (rule_sets := [$(Lean.mkIdent `Continuous):ident]))
goal: Lean.Macro

full_name: attrContinuity
code: macro "continuity" : attr =>
  `(attr|aesop safe apply (rule_sets := [$(Lean.mkIdent `Continuous):ident]))
goal: Lean.ParserDescr

full_name: tacticContinuity
code: macro "continuity" : tactic =>
  `(tactic| aesop (config := { terminal := true })
     (rule_sets := [$(Lean.mkIdent `Continuous):ident]))
goal: Lean.ParserDescr

full_name: _aux_Mathlib_Tactic_Continuity___macroRules_tacticContinuity_1
code: macro "continuity" : tactic =>
  `(tactic| aesop (config := { terminal := true })
     (rule_sets := [$(Lean.mkIdent `Continuous):ident]))
goal: Lean.Macro

full_name: tacticContinuity?
code: macro "continuity?" : tactic =>
  `(tactic| aesop? (config := { terminal := true })
    (rule_sets := [$(Lean.mkIdent `Continuous):ident]))
goal: Lean.ParserDescr

full_name: _aux_Mathlib_Tactic_Continuity___macroRules_tacticContinuity?_1
code: macro "continuity?" : tactic =>
  `(tactic| aesop? (config := { terminal := true })
    (rule_sets := [$(Lean.mkIdent `Continuous):ident]))
goal: Lean.Macro
File: Mathlib/Tactic/Inhabit.lean

full_name: Lean.Elab.Tactic.nonempty_to_inhabited
code: /-- Derives `Inhabited α` from `Nonempty α` with `Classical.choice`-/
noncomputable def nonempty_to_inhabited (α : Sort*) (_ : Nonempty α) : Inhabited α 
goal: Nonempty α → Inhabited α

full_name: Lean.Elab.Tactic.nonempty_prop_to_inhabited
code: /-- Derives `Inhabited α` from `Nonempty α` without `Classical.choice`
assuming `α` is of type `Prop`-/
def nonempty_prop_to_inhabited (α : Prop) (α_nonempty : Nonempty α) : Inhabited α 
goal: Inhabited α

full_name: Lean.Elab.Tactic.inhabit
code: /--
`inhabit α` tries to derive a `Nonempty α` instance and
then uses it to make an `Inhabited α` instance.
If the target is a `Prop`, this is done constructively. Otherwise, it uses `Classical.choice`.
-/
syntax (name := inhabit) "inhabit " atomic(ident " : ")? term : tactic
goal: Lean.ParserDescr

full_name: Lean.Elab.Tactic.evalInhabit
code: /-- `evalInhabit` takes in the MVarId of the main goal, runs the core portion of the inhabit tactic,
    and returns the resulting MVarId -/
def evalInhabit (goal : MVarId) (h_name : Option Ident) (term : Syntax) : TacticM MVarId 
goal: Lean.Elab.Tactic.TacticM Lean.MVarId

full_name: Lean.Elab.Tactic._aux_Mathlib_Tactic_Inhabit___elabRules_Lean_Elab_Tactic_inhabit_1
code: elab_rules : tactic
  | `(tactic| inhabit $[$h_name:ident :]? $term) => do
    let goal ← evalInhabit (← getMainGoal) h_name term
    replaceMainGoal [goal]
goal: Lean.Elab.Tactic.Tactic
File: Mathlib/Tactic/HigherOrder.lean

full_name: Lean.Parser.Attr.higherOrder
code: syntax (name := higherOrder) "higher_order" (ppSpace ident)? : attr
goal: Lean.ParserDescr

full_name: Tactic.mkComp
code: /-- `mkComp v e` checks whether `e` is a sequence of nested applications `f (g (h v))`, and if so,
returns the expression `f ∘ g ∘ h`. If `e = v` it returns `id`. -/
def mkComp (v : Expr) : Expr → MetaM Expr
  
goal: Lean.Expr → Lean.MetaM Lean.Expr

full_name: Tactic.mkHigherOrderType
code: /--
From a lemma of the shape `∀ x, f (g x) = h x`
derive an auxiliary lemma of the form `f ∘ g = h`
for reasoning about higher-order functions.
-/
partial def mkHigherOrderType (e : Expr) : MetaM Expr 
goal: Lean.MetaM Lean.Expr

full_name: Tactic.higherOrderGetParam
code: /-- A user attribute that applies to lemmas of the shape `∀ x, f (g x) = h x`.
It derives an auxiliary lemma of the form `f ∘ g = h` for reasoning about higher-order functions.
-/
def higherOrderGetParam (thm : Name) (stx : Syntax) : AttrM Name 
goal: Lean.AttrM Lean.Name

full_name: Tactic.initFn._@.Mathlib.Tactic.HigherOrder._hyg.1455
code: /-- The `higher_order` attribute. From a lemma of the shape `∀ x, f (g x) = h x` derive an
auxiliary lemma of the form `f ∘ g = h` for reasoning about higher-order functions.

Syntax: `[higher_order]` or `[higher_order name]` where the given name is used for the
generated theorem. -/
initialize higherOrderAttr : ParametricAttribute Name ←
  registerParametricAttribute {
    name := `higherOrder,
    descr :=
"From a lemma of the shape `∀ x, f (g x) = h x` derive an auxiliary lemma of the
form `f ∘ g = h` for reasoning about higher-order functions.

Syntax: `[higher_order]` or `[higher_order name]`, where the given name is used for the
generated theorem.",
    getParam := higherOrderGetParam }
goal: IO (Lean.ParametricAttribute Lean.Name)

full_name: Tactic.higherOrderAttr
code: /-- The `higher_order` attribute. From a lemma of the shape `∀ x, f (g x) = h x` derive an
auxiliary lemma of the form `f ∘ g = h` for reasoning about higher-order functions.

Syntax: `[higher_order]` or `[higher_order name]` where the given name is used for the
generated theorem. -/
initialize higherOrderAttr : ParametricAttribute Name ←
  registerParametricAttribute {
    name := `higherOrder,
    descr :=
"From a lemma of the shape `∀ x, f (g x) = h x` derive an auxiliary lemma of the
form `f ∘ g = h` for reasoning about higher-order functions.

Syntax: `[higher_order]` or `[higher_order name]`, where the given name is used for the
generated theorem.",
    getParam := higherOrderGetParam }
goal: Lean.ParametricAttribute Lean.Name
File: Mathlib/Tactic/Explode/Pretty.lean

full_name: Mathlib.Explode.padRight
code: /--
Given a list of `MessageData`s, make them of equal length.
We need this in order to form columns in our Fitch table.

```lean
padRight ["hi", "hello"] = ["hi   ", "hello"]
```
-/
def padRight (mds : List MessageData) : MetaM (List MessageData) 
goal: Lean.MetaM (List Lean.MessageData)

full_name: Mathlib.Explode.rowToMessageData
code: /-- Render a particular row of the Fitch table. -/
def rowToMessageData :
    List MessageData → List MessageData → List MessageData → List Entry → MetaM MessageData
  
goal: List Lean.MessageData →
  List Lean.MessageData → List Lean.MessageData → List Mathlib.Explode.Entry → Lean.MetaM Lean.MessageData

full_name: Mathlib.Explode.entriesToMessageData
code: /-- Given all `Entries`, return the entire Fitch table. -/
def entriesToMessageData (entries : Entries) : MetaM MessageData 
goal: Lean.MetaM Lean.MessageData
File: Mathlib/Tactic/Set.lean

full_name: Mathlib.Tactic.setArgsRest
code: syntax setArgsRest := ppSpace ident (" : " term)? " := " term (" with " "← "? ident)?
goal: Lean.ParserDescr

full_name: Mathlib.Tactic.setTactic
code: syntax (name := setTactic) "set" "!"? setArgsRest : tactic
goal: Lean.ParserDescr

full_name: Mathlib.Tactic._aux_Mathlib_Tactic_Set___macroRules_Mathlib_Tactic_tacticSet!__1
code: macro "set!" rest:setArgsRest : tactic => `(tactic| set ! $rest:setArgsRest)
goal: Lean.Macro

full_name: Mathlib.Tactic.tacticSet!_
code: macro "set!" rest:setArgsRest : tactic => `(tactic| set ! $rest:setArgsRest)
goal: Lean.ParserDescr

full_name: Mathlib.Tactic._aux_Mathlib_Tactic_Set___elabRules_Mathlib_Tactic_setTactic_1
code: /--
`set a := t with h` is a variant of `let a := t`. It adds the hypothesis `h : a = t` to
the local context and replaces `t` with `a` everywhere it can.

`set a := t with ← h` will add `h : t = a` instead.

`set! a := t with h` does not do any replacing.

```lean
example (x : Nat) (h : x + x - x = 3) : x + x - x = 3 := by
  set y := x with ← h2
  sorry
/-
x : Nat
y : Nat := x
h : y + y - y = 3
h2 : x = y
⊢ y + y - y = 3
-/
```

-/
elab_rules : tactic
| `(tactic| set%$tk $[!%$rw]? $a:ident $[: $ty:term]? := $val:term $[with $[←%$rev]? $h:ident]?) =>
  withMainContext do
    let (ty, vale) ← match ty with
    | some ty =>
      let ty ← Term.elabType ty
      pure (ty, ← elabTermEnsuringType val ty)
    | none =>
      let val ← elabTerm val none
      pure (← inferType val, val)
    let fvar ← liftMetaTacticAux fun goal ↦ do
      let (fvar, goal) ← (← goal.define a.getId ty vale).intro1P
      pure (fvar, [goal])
    withMainContext <|
      Term.addTermInfo' (isBinder := true) a (mkFVar fvar)
    if rw.isNone then
      evalTactic (← `(tactic| try rewrite [show $(← Term.exprToSyntax vale) = $a from rfl] at *))
    match h, rev with
    | some h, some none =>
      evalTactic (← `(tactic| have%$tk
        $h : $a = ($(← Term.exprToSyntax vale) : $(← Term.exprToSyntax ty)) := rfl))
    | some h, some (some _) =>
      evalTactic (← `(tactic| have%$tk
        $h : ($(← Term.exprToSyntax vale) : $(← Term.exprToSyntax ty)) = $a := rfl))
    | _, _ => pure ()
goal: Lean.Elab.Tactic.Tactic