File: Mathlib/Tactic/IrreducibleDef.lean

full_name: Lean.Elab.Command.«termDelta%_»
code: /-- `delta% t` elaborates to a head-delta reduced version of `t`. -/
elab "delta% " t:term : term <= expectedType => do
  let t ← elabTerm t expectedType
  synthesizeSyntheticMVars
  let t ← instantiateMVars t
  let some t ← delta? t | throwError "cannot delta reduce {t}"
  pure t
goal: Lean.ParserDescr

full_name: Lean.Elab.Command.«_aux_Mathlib_Tactic_IrreducibleDef___elabRules_Lean_Elab_Command_termDelta%__1»
code: /-- `delta% t` elaborates to a head-delta reduced version of `t`. -/
elab "delta% " t:term : term <= expectedType => do
  let t ← elabTerm t expectedType
  synthesizeSyntheticMVars
  let t ← instantiateMVars t
  let some t ← delta? t | throwError "cannot delta reduce {t}"
  pure t
goal: Lean.Elab.Term.TermElab

full_name: Lean.Elab.Command._aux_Mathlib_Tactic_IrreducibleDef___elabRules_Lean_Elab_Command_termEta_helper__1
code: /-- `eta_helper f = (· + 3)` elabs to `∀ x, f x = x + 3` -/
local elab "eta_helper " t:term : term => do
  let t ← elabTerm t none
  let some (_, lhs, rhs) := t.eq? | throwError "not an equation: {t}"
  synthesizeSyntheticMVars
  let rhs ← instantiateMVars rhs
  lambdaTelescope rhs fun xs rhs ↦ do
    let lhs := (mkAppN lhs xs).headBeta
    mkForallFVars xs <|← mkEq lhs rhs
goal: Lean.Elab.Term.TermElab

full_name: Lean.Elab.Command.termEta_helper_._@.Mathlib.Tactic.IrreducibleDef._hyg.202
code: /-- `eta_helper f = (· + 3)` elabs to `∀ x, f x = x + 3` -/
local elab "eta_helper " t:term : term => do
  let t ← elabTerm t none
  let some (_, lhs, rhs) := t.eq? | throwError "not an equation: {t}"
  synthesizeSyntheticMVars
  let rhs ← instantiateMVars rhs
  lambdaTelescope rhs fun xs rhs ↦ do
    let lhs := (mkAppN lhs xs).headBeta
    mkForallFVars xs <|← mkEq lhs rhs
goal: Lean.ParserDescr

full_name: Lean.Elab.Command.termVal_proj_._@.Mathlib.Tactic.IrreducibleDef._hyg.488
code: /-- `val_proj x` elabs to the *primitive projection* `@x.val`.  -/
local elab "val_proj " e:term : term => do
  let e ← elabTerm (← `(($e : Subtype _))) none
  return mkProj ``Subtype 0 e
goal: Lean.ParserDescr

full_name: Lean.Elab.Command._aux_Mathlib_Tactic_IrreducibleDef___elabRules_Lean_Elab_Command_termVal_proj__1
code: /-- `val_proj x` elabs to the *primitive projection* `@x.val`.  -/
local elab "val_proj " e:term : term => do
  let e ← elabTerm (← `(($e : Subtype _))) none
  return mkProj ``Subtype 0 e
goal: Lean.Elab.Term.TermElab

full_name: Lean.Elab.Command.commandStop_at_first_error__._@.Mathlib.Tactic.IrreducibleDef._hyg.732
code: /--
Executes the commands,
and stops after the first error.
In short, S-A-F-E.
-/
local syntax "stop_at_first_error" (ppLine command)* : command
goal: Lean.ParserDescr

full_name: Lean.Elab.Command._aux_Mathlib_Tactic_IrreducibleDef___elabRules_Lean_Elab_Command_commandStop_at_first_error___1
code: elab_rules : command
  | `(stop_at_first_error $[$cmds]*) => do
    for cmd in cmds do
      elabCommand cmd.raw
      if (← get).messages.hasErrors then break
goal: Lean.Elab.Command.CommandElab

full_name: Lean.Elab.Command.irredDefLemma
code: syntax irredDefLemma := atomic(" (" &"lemma" " := ") ident ")"
goal: Lean.ParserDescr

full_name: Lean.Elab.Command._aux_Mathlib_Tactic_IrreducibleDef___elabRules_Lean_Elab_Command_command_Irreducible_def_____1
code: /--
Introduces an irreducible definition.
`irreducible_def foo := 42` generates
a constant `foo : Nat` as well as
a theorem `foo_def : foo = 42`.
-/
elab mods:declModifiers "irreducible_def" n_id:declId n_def:(irredDefLemma)?
    declSig:ppIndent(optDeclSig) val:declVal :
    command => do
  let declSig : TSyntax ``Parser.Command.optDeclSig := ⟨declSig.raw⟩ -- HACK
  let (n, us) ← match n_id with
    | `(Parser.Command.declId| $n:ident $[.{$us,*}]?) => pure (n, us)
    | _ => throwUnsupportedSyntax
  let us' := us.getD { elemsAndSeps := #[] }
  let n_def ← match n_def.getD ⟨mkNullNode⟩ with
    | `(irredDefLemma| (lemma := $id)) => pure id
    | _ => pure <| mkIdentFrom n <| (·.review) <|
      let scopes := extractMacroScopes n.getId
      { scopes with name := scopes.name.appendAfter "_def" }
  let `(Parser.Command.declModifiersF|
      $[$doc:docComment]? $[@[$attrs,*]]?
      $[$vis]? $[$nc:noncomputable]? $[$uns:unsafe]?) := mods
    | throwError "unsupported modifiers {format mods}"
  let attrs := attrs.getD {}
  let prot := vis.filter (· matches `(Parser.Command.visibility| protected))
  let priv := vis.filter (· matches `(Parser.Command.visibility| private))
  elabCommand <|<- `(stop_at_first_error
    $[$nc:noncomputable]? $[$uns]? def definition$[.{$us,*}]? $declSig:optDeclSig $val
    $[$nc:noncomputable]? $[$uns]? opaque wrapped$[.{$us,*}]? : Subtype (Eq @definition.{$us',*}) :=
      ⟨_, rfl⟩
    $[$doc:docComment]? $[private%$priv]? $[$nc:noncomputable]? $[$uns]?
    def $n:ident$[.{$us,*}]? :=
      val_proj @wrapped.{$us',*}
    $[private%$priv]? $[$uns:unsafe]? theorem $n_def:ident $[.{$us,*}]? :
        eta_helper Eq @$n.{$us',*} @(delta% @definition) := by
      intros
      delta $n:ident
      rw [show wrapped = ⟨@definition.{$us',*}, rfl⟩ from Subtype.ext wrapped.2.symm]
      rfl
    attribute [irreducible] $n definition
    attribute [eqns $n_def] $n
    attribute [$attrs:attrInstance,*] $n)
  if prot.isSome then
    modifyEnv (addProtected · ((← getCurrNamespace) ++ n.getId))
goal: Lean.Elab.Command.CommandElab

full_name: Lean.Elab.Command.command_Irreducible_def____
code: /--
Introduces an irreducible definition.
`irreducible_def foo := 42` generates
a constant `foo : Nat` as well as
a theorem `foo_def : foo = 42`.
-/
elab mods:declModifiers "irreducible_def" n_id:declId n_def:(irredDefLemma)?
    declSig:ppIndent(optDeclSig) val:declVal :
    command => do
  let declSig : TSyntax ``Parser.Command.optDeclSig := ⟨declSig.raw⟩ -- HACK
  let (n, us) ← match n_id with
    | `(Parser.Command.declId| $n:ident $[.{$us,*}]?) => pure (n, us)
    | _ => throwUnsupportedSyntax
  let us' := us.getD { elemsAndSeps := #[] }
  let n_def ← match n_def.getD ⟨mkNullNode⟩ with
    | `(irredDefLemma| (lemma := $id)) => pure id
    | _ => pure <| mkIdentFrom n <| (·.review) <|
      let scopes := extractMacroScopes n.getId
      { scopes with name := scopes.name.appendAfter "_def" }
  let `(Parser.Command.declModifiersF|
      $[$doc:docComment]? $[@[$attrs,*]]?
      $[$vis]? $[$nc:noncomputable]? $[$uns:unsafe]?) := mods
    | throwError "unsupported modifiers {format mods}"
  let attrs := attrs.getD {}
  let prot := vis.filter (· matches `(Parser.Command.visibility| protected))
  let priv := vis.filter (· matches `(Parser.Command.visibility| private))
  elabCommand <|<- `(stop_at_first_error
    $[$nc:noncomputable]? $[$uns]? def definition$[.{$us,*}]? $declSig:optDeclSig $val
    $[$nc:noncomputable]? $[$uns]? opaque wrapped$[.{$us,*}]? : Subtype (Eq @definition.{$us',*}) :=
      ⟨_, rfl⟩
    $[$doc:docComment]? $[private%$priv]? $[$nc:noncomputable]? $[$uns]?
    def $n:ident$[.{$us,*}]? :=
      val_proj @wrapped.{$us',*}
    $[private%$priv]? $[$uns:unsafe]? theorem $n_def:ident $[.{$us,*}]? :
        eta_helper Eq @$n.{$us',*} @(delta% @definition) := by
      intros
      delta $n:ident
      rw [show wrapped = ⟨@definition.{$us',*}, rfl⟩ from Subtype.ext wrapped.2.symm]
      rfl
    attribute [irreducible] $n definition
    attribute [eqns $n_def] $n
    attribute [$attrs:attrInstance,*] $n)
  if prot.isSome then
    modifyEnv (addProtected · ((← getCurrNamespace) ++ n.getId))
goal: Lean.ParserDescr