File: .lake/packages/lean4/src/lean/Lean/Meta/WHNF.lean

full_name: Lean.Meta.getStructuralRecArgPos?
code: /--
Forward declaration. It is defined in the module `src/Lean/Elab/PreDefinition/Structural/Eqns.lean`.
It is possible to avoid this hack if we move `Structural.EqnInfo` and `Structural.eqnInfoExt`
to this module.
-/
@[extern "lean_get_structural_rec_arg_pos"]
opaque getStructuralRecArgPos? (declName : Name) : CoreM (Option Nat)
goal: Lean.CoreM (Option Nat)

full_name: Lean.Meta.smartUnfoldingSuffix
code: def smartUnfoldingSuffix 
goal: String

full_name: Lean.Meta.mkSmartUnfoldingNameFor
code: @[inline] def mkSmartUnfoldingNameFor (declName : Name) : Name 
goal: Lean.Name

full_name: Lean.Meta.hasSmartUnfoldingDecl
code: def hasSmartUnfoldingDecl (env : Environment) (declName : Name) : Bool 
goal: Bool

full_name: Lean.Meta.initFn._@..lake.packages.lean4.src.lean.Lean.Meta.WHNF._hyg.37
code: register_builtin_option smartUnfolding : Bool := {
  defValue := true
  descr := "when computing weak head normal form, use auxiliary definition created for functions defined by structural recursion"
}
goal: IO (Lean.Option Bool)

full_name: Lean.Meta.smartUnfolding
code: register_builtin_option smartUnfolding : Bool := {
  defValue := true
  descr := "when computing weak head normal form, use auxiliary definition created for functions defined by structural recursion"
}
goal: Lean.Option Bool

full_name: Lean.Meta.markSmartUnfoldingMatch
code: /-- Add auxiliary annotation to indicate the `match`-expression `e` must be reduced when performing smart unfolding. -/
def markSmartUnfoldingMatch (e : Expr) : Expr 
goal: Lean.Expr

full_name: Lean.Meta.smartUnfoldingMatch?
code: def smartUnfoldingMatch? (e : Expr) : Option Expr 
goal: Option Lean.Expr

full_name: Lean.Meta.markSmartUnfoldingMatchAlt
code: /-- Add auxiliary annotation to indicate expression `e` (a `match` alternative rhs) was successfully reduced by smart unfolding. -/
def markSmartUnfoldingMatchAlt (e : Expr) : Expr 
goal: Lean.Expr

full_name: Lean.Meta.smartUnfoldingMatchAlt?
code: def smartUnfoldingMatchAlt? (e : Expr) : Option Expr 
goal: Option Lean.Expr

full_name: Lean.Meta.isAuxDef
code: def isAuxDef (constName : Name) : MetaM Bool 
goal: Lean.MetaM Bool

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Meta.WHNF.0.Lean.Meta.matchConstAux
code: @[inline] private def matchConstAux {α} (e : Expr) (failK : Unit → MetaM α) (k : ConstantInfo → List Level → MetaM α) : MetaM α 
goal: Lean.MetaM α

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Meta.WHNF.0.Lean.Meta.getFirstCtor
code: private def getFirstCtor (d : Name) : MetaM (Option Name) 
goal: Lean.MetaM (Option Lean.Name)

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Meta.WHNF.0.Lean.Meta.mkNullaryCtor
code: private def mkNullaryCtor (type : Expr) (nparams : Nat) : MetaM (Option Expr) 
goal: Lean.MetaM (Option Lean.Expr)

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Meta.WHNF.0.Lean.Meta.getRecRuleFor
code: private def getRecRuleFor (recVal : RecursorVal) (major : Expr) : Option RecursorRule 
goal: Option Lean.RecursorRule

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Meta.WHNF.0.Lean.Meta.toCtorWhenK
code: private def toCtorWhenK (recVal : RecursorVal) (major : Expr) : MetaM Expr 
goal: Lean.MetaM Lean.Expr

full_name: Lean.Meta.mkProjFn
code: /--
  Create the `i`th projection `major`. It tries to use the auto-generated projection functions if available. Otherwise falls back
  to `Expr.proj`.
-/
def mkProjFn (ctorVal : ConstructorVal) (us : List Level) (params : Array Expr) (i : Nat) (major : Expr) : CoreM Expr 
goal: Lean.CoreM Lean.Expr

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Meta.WHNF.0.Lean.Meta.toCtorWhenStructure
code: /--
  If `major` is not a constructor application, and its type is a structure `C ...`, then return `C.mk major.1 ... major.n`

  \pre `inductName` is `C`.

  If `Meta.Config.etaStruct` is `false` or the condition above does not hold, this method just returns `major`. -/
private def toCtorWhenStructure (inductName : Name) (major : Expr) : MetaM Expr 
goal: Lean.MetaM Lean.Expr

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Meta.WHNF.0.Lean.Meta.isWFRec
code: private def isWFRec (declName : Name) : Bool 
goal: Bool

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Meta.WHNF.0.Lean.Meta.cleanupNatOffsetMajor
code: /--
Helper method for `reduceRec`.
We use it to ensure we don't expose `Nat.add` when reducing `Nat.rec`.
We we use the following trick, if `e` can be expressed as an offest `(a, k)` with `k > 0`,
we create a new expression `Nat.succ e'` where `e'` is `a` for `k = 1`, or `a + (k-1)` for `k > 1`.
See issue #3022
-/
private def cleanupNatOffsetMajor (e : Expr) : MetaM Expr 
goal: Lean.MetaM Lean.Expr

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Meta.WHNF.0.Lean.Meta.reduceRec
code: /-- Auxiliary function for reducing recursor applications. -/
private def reduceRec (recVal : RecursorVal) (recLvls : List Level) (recArgs : Array Expr) (failK : Unit → MetaM α) (successK : Expr → MetaM α) : MetaM α 
goal: Lean.MetaM α

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Meta.WHNF.0.Lean.Meta.reduceQuotRec
code: /-- Auxiliary function for reducing `Quot.lift` and `Quot.ind` applications. -/
private def reduceQuotRec (recVal  : QuotVal) (recArgs : Array Expr) (failK : Unit → MetaM α) (successK : Expr → MetaM α) : MetaM α 
goal: Lean.MetaM α

full_name: Lean.Meta.ProjReductionKind.yes
code: /--
Configuration for projection reduction. See `whnfCore`.
-/
inductive ProjReductionKind where
  /-- Projections `s.i` are not reduced at `whnfCore`. -/
  | no
  /--
  Projections `s.i` are reduced at `whnfCore`, and `whnfCore` is used at `s` during the process.
  Recall that `whnfCore` does not perform `delta` reduction (i.e., it will not unfold constant declarations).
  -/
  | yes
  /--
  Projections `s.i` are reduced at `whnfCore`, and `whnf` is used at `s` during the process.
  Recall that `whnfCore` does not perform `delta` reduction (i.e., it will not unfold constant declarations), but `whnf` does.
  -/
  | yesWithDelta
  /--
  Projections `s.i` are reduced at `whnfCore`, and `whnfAtMostI` is used at `s` during the process.
  Recall that `whnfAtMostI` is like `whnf` but uses transparency at most `instances`.
  This option is stronger than `yes`, but weaker than `yesWithDelta`.
  We use this option to ensure we reduce projections to prevent expensive defeq checks when unifying TC operations.
  When unifying e.g. `(@Field.toNeg α inst1).1 =?= (@Field.toNeg α inst2).1`,
  we only want to unify negation (and not all other field operations as well).
  Unifying the field instances slowed down unification: https://github.com/leanprover/lean4/issues/1986
  -/
  | yesWithDeltaI
  deriving DecidableEq, Inhabited, Repr
goal: Lean.Meta.ProjReductionKind

full_name: Lean.Meta.instReprProjReductionKind
code: /--
Configuration for projection reduction. See `whnfCore`.
-/
inductive ProjReductionKind where
  /-- Projections `s.i` are not reduced at `whnfCore`. -/
  | no
  /--
  Projections `s.i` are reduced at `whnfCore`, and `whnfCore` is used at `s` during the process.
  Recall that `whnfCore` does not perform `delta` reduction (i.e., it will not unfold constant declarations).
  -/
  | yes
  /--
  Projections `s.i` are reduced at `whnfCore`, and `whnf` is used at `s` during the process.
  Recall that `whnfCore` does not perform `delta` reduction (i.e., it will not unfold constant declarations), but `whnf` does.
  -/
  | yesWithDelta
  /--
  Projections `s.i` are reduced at `whnfCore`, and `whnfAtMostI` is used at `s` during the process.
  Recall that `whnfAtMostI` is like `whnf` but uses transparency at most `instances`.
  This option is stronger than `yes`, but weaker than `yesWithDelta`.
  We use this option to ensure we reduce projections to prevent expensive defeq checks when unifying TC operations.
  When unifying e.g. `(@Field.toNeg α inst1).1 =?= (@Field.toNeg α inst2).1`,
  we only want to unify negation (and not all other field operations as well).
  Unifying the field instances slowed down unification: https://github.com/leanprover/lean4/issues/1986
  -/
  | yesWithDeltaI
  deriving DecidableEq, Inhabited, Repr
goal: Repr Lean.Meta.ProjReductionKind

full_name: Lean.Meta.ProjReductionKind.yesWithDeltaI
code: /--
Configuration for projection reduction. See `whnfCore`.
-/
inductive ProjReductionKind where
  /-- Projections `s.i` are not reduced at `whnfCore`. -/
  | no
  /--
  Projections `s.i` are reduced at `whnfCore`, and `whnfCore` is used at `s` during the process.
  Recall that `whnfCore` does not perform `delta` reduction (i.e., it will not unfold constant declarations).
  -/
  | yes
  /--
  Projections `s.i` are reduced at `whnfCore`, and `whnf` is used at `s` during the process.
  Recall that `whnfCore` does not perform `delta` reduction (i.e., it will not unfold constant declarations), but `whnf` does.
  -/
  | yesWithDelta
  /--
  Projections `s.i` are reduced at `whnfCore`, and `whnfAtMostI` is used at `s` during the process.
  Recall that `whnfAtMostI` is like `whnf` but uses transparency at most `instances`.
  This option is stronger than `yes`, but weaker than `yesWithDelta`.
  We use this option to ensure we reduce projections to prevent expensive defeq checks when unifying TC operations.
  When unifying e.g. `(@Field.toNeg α inst1).1 =?= (@Field.toNeg α inst2).1`,
  we only want to unify negation (and not all other field operations as well).
  Unifying the field instances slowed down unification: https://github.com/leanprover/lean4/issues/1986
  -/
  | yesWithDeltaI
  deriving DecidableEq, Inhabited, Repr
goal: Lean.Meta.ProjReductionKind

full_name: Lean.Meta.ProjReductionKind
code: /--
Configuration for projection reduction. See `whnfCore`.
-/
inductive ProjReductionKind where
  /-- Projections `s.i` are not reduced at `whnfCore`. -/
  | no
  /--
  Projections `s.i` are reduced at `whnfCore`, and `whnfCore` is used at `s` during the process.
  Recall that `whnfCore` does not perform `delta` reduction (i.e., it will not unfold constant declarations).
  -/
  | yes
  /--
  Projections `s.i` are reduced at `whnfCore`, and `whnf` is used at `s` during the process.
  Recall that `whnfCore` does not perform `delta` reduction (i.e., it will not unfold constant declarations), but `whnf` does.
  -/
  | yesWithDelta
  /--
  Projections `s.i` are reduced at `whnfCore`, and `whnfAtMostI` is used at `s` during the process.
  Recall that `whnfAtMostI` is like `whnf` but uses transparency at most `instances`.
  This option is stronger than `yes`, but weaker than `yesWithDelta`.
  We use this option to ensure we reduce projections to prevent expensive defeq checks when unifying TC operations.
  When unifying e.g. `(@Field.toNeg α inst1).1 =?= (@Field.toNeg α inst2).1`,
  we only want to unify negation (and not all other field operations as well).
  Unifying the field instances slowed down unification: https://github.com/leanprover/lean4/issues/1986
  -/
  | yesWithDeltaI
  deriving DecidableEq, Inhabited, Repr
goal: Type

full_name: Lean.Meta.instDecidableEqProjReductionKind
code: /--
Configuration for projection reduction. See `whnfCore`.
-/
inductive ProjReductionKind where
  /-- Projections `s.i` are not reduced at `whnfCore`. -/
  | no
  /--
  Projections `s.i` are reduced at `whnfCore`, and `whnfCore` is used at `s` during the process.
  Recall that `whnfCore` does not perform `delta` reduction (i.e., it will not unfold constant declarations).
  -/
  | yes
  /--
  Projections `s.i` are reduced at `whnfCore`, and `whnf` is used at `s` during the process.
  Recall that `whnfCore` does not perform `delta` reduction (i.e., it will not unfold constant declarations), but `whnf` does.
  -/
  | yesWithDelta
  /--
  Projections `s.i` are reduced at `whnfCore`, and `whnfAtMostI` is used at `s` during the process.
  Recall that `whnfAtMostI` is like `whnf` but uses transparency at most `instances`.
  This option is stronger than `yes`, but weaker than `yesWithDelta`.
  We use this option to ensure we reduce projections to prevent expensive defeq checks when unifying TC operations.
  When unifying e.g. `(@Field.toNeg α inst1).1 =?= (@Field.toNeg α inst2).1`,
  we only want to unify negation (and not all other field operations as well).
  Unifying the field instances slowed down unification: https://github.com/leanprover/lean4/issues/1986
  -/
  | yesWithDeltaI
  deriving DecidableEq, Inhabited, Repr
goal: DecidableEq Lean.Meta.ProjReductionKind

full_name: Lean.Meta.ProjReductionKind.yesWithDelta
code: /--
Configuration for projection reduction. See `whnfCore`.
-/
inductive ProjReductionKind where
  /-- Projections `s.i` are not reduced at `whnfCore`. -/
  | no
  /--
  Projections `s.i` are reduced at `whnfCore`, and `whnfCore` is used at `s` during the process.
  Recall that `whnfCore` does not perform `delta` reduction (i.e., it will not unfold constant declarations).
  -/
  | yes
  /--
  Projections `s.i` are reduced at `whnfCore`, and `whnf` is used at `s` during the process.
  Recall that `whnfCore` does not perform `delta` reduction (i.e., it will not unfold constant declarations), but `whnf` does.
  -/
  | yesWithDelta
  /--
  Projections `s.i` are reduced at `whnfCore`, and `whnfAtMostI` is used at `s` during the process.
  Recall that `whnfAtMostI` is like `whnf` but uses transparency at most `instances`.
  This option is stronger than `yes`, but weaker than `yesWithDelta`.
  We use this option to ensure we reduce projections to prevent expensive defeq checks when unifying TC operations.
  When unifying e.g. `(@Field.toNeg α inst1).1 =?= (@Field.toNeg α inst2).1`,
  we only want to unify negation (and not all other field operations as well).
  Unifying the field instances slowed down unification: https://github.com/leanprover/lean4/issues/1986
  -/
  | yesWithDeltaI
  deriving DecidableEq, Inhabited, Repr
goal: Lean.Meta.ProjReductionKind

full_name: Lean.Meta.instInhabitedProjReductionKind
code: /--
Configuration for projection reduction. See `whnfCore`.
-/
inductive ProjReductionKind where
  /-- Projections `s.i` are not reduced at `whnfCore`. -/
  | no
  /--
  Projections `s.i` are reduced at `whnfCore`, and `whnfCore` is used at `s` during the process.
  Recall that `whnfCore` does not perform `delta` reduction (i.e., it will not unfold constant declarations).
  -/
  | yes
  /--
  Projections `s.i` are reduced at `whnfCore`, and `whnf` is used at `s` during the process.
  Recall that `whnfCore` does not perform `delta` reduction (i.e., it will not unfold constant declarations), but `whnf` does.
  -/
  | yesWithDelta
  /--
  Projections `s.i` are reduced at `whnfCore`, and `whnfAtMostI` is used at `s` during the process.
  Recall that `whnfAtMostI` is like `whnf` but uses transparency at most `instances`.
  This option is stronger than `yes`, but weaker than `yesWithDelta`.
  We use this option to ensure we reduce projections to prevent expensive defeq checks when unifying TC operations.
  When unifying e.g. `(@Field.toNeg α inst1).1 =?= (@Field.toNeg α inst2).1`,
  we only want to unify negation (and not all other field operations as well).
  Unifying the field instances slowed down unification: https://github.com/leanprover/lean4/issues/1986
  -/
  | yesWithDeltaI
  deriving DecidableEq, Inhabited, Repr
goal: Inhabited Lean.Meta.ProjReductionKind

full_name: Lean.Meta.ProjReductionKind.no
code: /--
Configuration for projection reduction. See `whnfCore`.
-/
inductive ProjReductionKind where
  /-- Projections `s.i` are not reduced at `whnfCore`. -/
  | no
  /--
  Projections `s.i` are reduced at `whnfCore`, and `whnfCore` is used at `s` during the process.
  Recall that `whnfCore` does not perform `delta` reduction (i.e., it will not unfold constant declarations).
  -/
  | yes
  /--
  Projections `s.i` are reduced at `whnfCore`, and `whnf` is used at `s` during the process.
  Recall that `whnfCore` does not perform `delta` reduction (i.e., it will not unfold constant declarations), but `whnf` does.
  -/
  | yesWithDelta
  /--
  Projections `s.i` are reduced at `whnfCore`, and `whnfAtMostI` is used at `s` during the process.
  Recall that `whnfAtMostI` is like `whnf` but uses transparency at most `instances`.
  This option is stronger than `yes`, but weaker than `yesWithDelta`.
  We use this option to ensure we reduce projections to prevent expensive defeq checks when unifying TC operations.
  When unifying e.g. `(@Field.toNeg α inst1).1 =?= (@Field.toNeg α inst2).1`,
  we only want to unify negation (and not all other field operations as well).
  Unifying the field instances slowed down unification: https://github.com/leanprover/lean4/issues/1986
  -/
  | yesWithDeltaI
  deriving DecidableEq, Inhabited, Repr
goal: Lean.Meta.ProjReductionKind

full_name: Lean.Meta.WhnfCoreConfig.proj
code: /--
Configuration options for `whnfEasyCases` and `whnfCore`.
-/
structure WhnfCoreConfig where
  /-- If `true`, reduce recursor/matcher applications, e.g., `Nat.rec true (fun _ _ => false) Nat.zero` reduces to `true` -/
  iota : Bool := true
  /-- If `true`, reduce terms such as `(fun x => t[x]) a` into `t[a]` -/
  beta : Bool := true
  /-- Control projection reduction at `whnfCore`. -/
  proj : ProjReductionKind := .yesWithDelta
  /--
  Zeta reduction: `let x := v; e[x]` reduces to `e[v]`.
  We say a let-declaration `let x := v; e` is non dependent if it is equivalent to `(fun x => e) v`.
  Recall that
  ```
  fun x : BitVec 5 => let n := 5; fun y : BitVec n => x = y
  ```
  is type correct, but
  ```
  fun x : BitVec 5 => (fun n => fun y : BitVec n => x = y) 5
  ```
  is not.
  -/
  zeta : Bool := true
  /--
  Zeta-delta reduction: given a local context containing entry `x : t := e`, free variable `x` reduces to `e`.
  -/
  zetaDelta : Bool := true
goal: Lean.Meta.ProjReductionKind

full_name: Lean.Meta.WhnfCoreConfig.zeta
code: /--
Configuration options for `whnfEasyCases` and `whnfCore`.
-/
structure WhnfCoreConfig where
  /-- If `true`, reduce recursor/matcher applications, e.g., `Nat.rec true (fun _ _ => false) Nat.zero` reduces to `true` -/
  iota : Bool := true
  /-- If `true`, reduce terms such as `(fun x => t[x]) a` into `t[a]` -/
  beta : Bool := true
  /-- Control projection reduction at `whnfCore`. -/
  proj : ProjReductionKind := .yesWithDelta
  /--
  Zeta reduction: `let x := v; e[x]` reduces to `e[v]`.
  We say a let-declaration `let x := v; e` is non dependent if it is equivalent to `(fun x => e) v`.
  Recall that
  ```
  fun x : BitVec 5 => let n := 5; fun y : BitVec n => x = y
  ```
  is type correct, but
  ```
  fun x : BitVec 5 => (fun n => fun y : BitVec n => x = y) 5
  ```
  is not.
  -/
  zeta : Bool := true
  /--
  Zeta-delta reduction: given a local context containing entry `x : t := e`, free variable `x` reduces to `e`.
  -/
  zetaDelta : Bool := true
goal: Bool

full_name: Lean.Meta.WhnfCoreConfig
code: /--
Configuration options for `whnfEasyCases` and `whnfCore`.
-/
structure WhnfCoreConfig where
  /-- If `true`, reduce recursor/matcher applications, e.g., `Nat.rec true (fun _ _ => false) Nat.zero` reduces to `true` -/
  iota : Bool := true
  /-- If `true`, reduce terms such as `(fun x => t[x]) a` into `t[a]` -/
  beta : Bool := true
  /-- Control projection reduction at `whnfCore`. -/
  proj : ProjReductionKind := .yesWithDelta
  /--
  Zeta reduction: `let x := v; e[x]` reduces to `e[v]`.
  We say a let-declaration `let x := v; e` is non dependent if it is equivalent to `(fun x => e) v`.
  Recall that
  ```
  fun x : BitVec 5 => let n := 5; fun y : BitVec n => x = y
  ```
  is type correct, but
  ```
  fun x : BitVec 5 => (fun n => fun y : BitVec n => x = y) 5
  ```
  is not.
  -/
  zeta : Bool := true
  /--
  Zeta-delta reduction: given a local context containing entry `x : t := e`, free variable `x` reduces to `e`.
  -/
  zetaDelta : Bool := true
goal: Type

full_name: Lean.Meta.WhnfCoreConfig.zetaDelta
code: /--
Configuration options for `whnfEasyCases` and `whnfCore`.
-/
structure WhnfCoreConfig where
  /-- If `true`, reduce recursor/matcher applications, e.g., `Nat.rec true (fun _ _ => false) Nat.zero` reduces to `true` -/
  iota : Bool := true
  /-- If `true`, reduce terms such as `(fun x => t[x]) a` into `t[a]` -/
  beta : Bool := true
  /-- Control projection reduction at `whnfCore`. -/
  proj : ProjReductionKind := .yesWithDelta
  /--
  Zeta reduction: `let x := v; e[x]` reduces to `e[v]`.
  We say a let-declaration `let x := v; e` is non dependent if it is equivalent to `(fun x => e) v`.
  Recall that
  ```
  fun x : BitVec 5 => let n := 5; fun y : BitVec n => x = y
  ```
  is type correct, but
  ```
  fun x : BitVec 5 => (fun n => fun y : BitVec n => x = y) 5
  ```
  is not.
  -/
  zeta : Bool := true
  /--
  Zeta-delta reduction: given a local context containing entry `x : t := e`, free variable `x` reduces to `e`.
  -/
  zetaDelta : Bool := true
goal: Bool

full_name: Lean.Meta.WhnfCoreConfig.iota
code: /--
Configuration options for `whnfEasyCases` and `whnfCore`.
-/
structure WhnfCoreConfig where
  /-- If `true`, reduce recursor/matcher applications, e.g., `Nat.rec true (fun _ _ => false) Nat.zero` reduces to `true` -/
  iota : Bool := true
  /-- If `true`, reduce terms such as `(fun x => t[x]) a` into `t[a]` -/
  beta : Bool := true
  /-- Control projection reduction at `whnfCore`. -/
  proj : ProjReductionKind := .yesWithDelta
  /--
  Zeta reduction: `let x := v; e[x]` reduces to `e[v]`.
  We say a let-declaration `let x := v; e` is non dependent if it is equivalent to `(fun x => e) v`.
  Recall that
  ```
  fun x : BitVec 5 => let n := 5; fun y : BitVec n => x = y
  ```
  is type correct, but
  ```
  fun x : BitVec 5 => (fun n => fun y : BitVec n => x = y) 5
  ```
  is not.
  -/
  zeta : Bool := true
  /--
  Zeta-delta reduction: given a local context containing entry `x : t := e`, free variable `x` reduces to `e`.
  -/
  zetaDelta : Bool := true
goal: Bool

full_name: Lean.Meta.WhnfCoreConfig.beta
code: /--
Configuration options for `whnfEasyCases` and `whnfCore`.
-/
structure WhnfCoreConfig where
  /-- If `true`, reduce recursor/matcher applications, e.g., `Nat.rec true (fun _ _ => false) Nat.zero` reduces to `true` -/
  iota : Bool := true
  /-- If `true`, reduce terms such as `(fun x => t[x]) a` into `t[a]` -/
  beta : Bool := true
  /-- Control projection reduction at `whnfCore`. -/
  proj : ProjReductionKind := .yesWithDelta
  /--
  Zeta reduction: `let x := v; e[x]` reduces to `e[v]`.
  We say a let-declaration `let x := v; e` is non dependent if it is equivalent to `(fun x => e) v`.
  Recall that
  ```
  fun x : BitVec 5 => let n := 5; fun y : BitVec n => x = y
  ```
  is type correct, but
  ```
  fun x : BitVec 5 => (fun n => fun y : BitVec n => x = y) 5
  ```
  is not.
  -/
  zeta : Bool := true
  /--
  Zeta-delta reduction: given a local context containing entry `x : t := e`, free variable `x` reduces to `e`.
  -/
  zetaDelta : Bool := true
goal: Bool

full_name: Lean.Meta.whnfEasyCases
code: /-- Auxiliary combinator for handling easy WHNF cases. It takes a function for handling the "hard" cases as an argument -/
@[specialize] partial def whnfEasyCases (e : Expr) (k : Expr → MetaM Expr) (config : WhnfCoreConfig := {}) : MetaM Expr 
goal: Lean.MetaM Lean.Expr

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Meta.WHNF.0.Lean.Meta.deltaDefinition
code: @[specialize] private def deltaDefinition (c : ConstantInfo) (lvls : List Level)
    (failK : Unit → MetaM α) (successK : Expr → MetaM α) : MetaM α 
goal: Lean.MetaM α

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Meta.WHNF.0.Lean.Meta.deltaBetaDefinition
code: @[specialize] private def deltaBetaDefinition (c : ConstantInfo) (lvls : List Level) (revArgs : Array Expr)
    (failK : Unit → MetaM α) (successK : Expr → MetaM α) (preserveMData := false) : MetaM α 
goal: Lean.MetaM α

full_name: Lean.Meta.ReduceMatcherResult.reduced
code: inductive ReduceMatcherResult where
  | reduced (val : Expr)
  | stuck   (val : Expr)
  | notMatcher
  | partialApp
goal: Lean.Meta.ReduceMatcherResult

full_name: Lean.Meta.ReduceMatcherResult
code: inductive ReduceMatcherResult where
  | reduced (val : Expr)
  | stuck   (val : Expr)
  | notMatcher
  | partialApp
goal: Type

full_name: Lean.Meta.ReduceMatcherResult.partialApp
code: inductive ReduceMatcherResult where
  | reduced (val : Expr)
  | stuck   (val : Expr)
  | notMatcher
  | partialApp
goal: Lean.Meta.ReduceMatcherResult

full_name: Lean.Meta.ReduceMatcherResult.stuck
code: inductive ReduceMatcherResult where
  | reduced (val : Expr)
  | stuck   (val : Expr)
  | notMatcher
  | partialApp
goal: Lean.Meta.ReduceMatcherResult

full_name: Lean.Meta.ReduceMatcherResult.notMatcher
code: inductive ReduceMatcherResult where
  | reduced (val : Expr)
  | stuck   (val : Expr)
  | notMatcher
  | partialApp
goal: Lean.Meta.ReduceMatcherResult

full_name: Lean.Meta.canUnfoldAtMatcher
code: /--
  The "match" compiler uses `if-then-else` expressions and other auxiliary declarations to compile match-expressions such as
  ```
  match v with
  | 'a' => 1
  | 'b' => 2
  | _   => 3
  ```
  because it is more efficient than using `casesOn` recursors.
  The method `reduceMatcher?` fails if these auxiliary definitions (e.g., `ite`) cannot be unfolded in the current
  transparency setting. This is problematic because tactics such as `simp` use `TransparencyMode.reducible`, and
  most users assume that expressions such as
  ```
  match 0 with
  | 0 => 1
  | 100 => 2
  | _ => 3
  ```
  should reduce in any transparency mode.
  Thus, we define a custom `canUnfoldAtMatcher` predicate for `whnfMatcher`.

  This solution is not very modular because modifications at the `match` compiler require changes here.
  We claim this is defensible because it is reducing the auxiliary declaration defined by the `match` compiler.

  Alternative solution: tactics that use `TransparencyMode.reducible` should rely on the equations we generated for match-expressions.
  This solution is also not perfect because the match-expression above will not reduce during type checking when we are not using
  `TransparencyMode.default` or `TransparencyMode.all`.
-/
def canUnfoldAtMatcher (cfg : Config) (info : ConstantInfo) : CoreM Bool 
goal: Lean.CoreM Bool

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Meta.WHNF.0.Lean.Meta.whnfMatcher
code: private def whnfMatcher (e : Expr) : MetaM Expr 
goal: Lean.MetaM Lean.Expr

full_name: Lean.Meta.reduceMatcher?
code: def reduceMatcher? (e : Expr) : MetaM ReduceMatcherResult 
goal: Lean.MetaM Lean.Meta.ReduceMatcherResult

full_name: Lean.Meta.projectCore?
code: def projectCore? (e : Expr) (i : Nat) : MetaM (Option Expr) 
goal: Lean.MetaM (Option Lean.Expr)

full_name: Lean.Meta.project?
code: def project? (e : Expr) (i : Nat) : MetaM (Option Expr) 
goal: Lean.MetaM (Option Lean.Expr)

full_name: Lean.Meta.reduceProj?
code: /-- Reduce kernel projection `Expr.proj ..` expression. -/
def reduceProj? (e : Expr) : MetaM (Option Expr) 
goal: Lean.MetaM (Option Lean.Expr)

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Meta.WHNF.0.Lean.Meta.whnfDelayedAssigned?
code: /--
  Auxiliary method for reducing terms of the form `?m t_1 ... t_n` where `?m` is delayed assigned.
  Recall that we can only expand a delayed assignment when all holes/metavariables in the assigned value have been "filled".
-/
private def whnfDelayedAssigned? (f' : Expr) (e : Expr) : MetaM (Option Expr) 
goal: Lean.MetaM (Option Lean.Expr)

full_name: Lean.Meta.whnfCore.go
code: /--
Apply beta-reduction, zeta-reduction (i.e., unfold let local-decls), iota-reduction,
expand let-expressions, expand assigned meta-variables.
-/
partial def whnfCore (e : Expr) (config : WhnfCoreConfig := {}): MetaM Expr 
goal: Lean.MetaM Lean.Expr

full_name: Lean.Meta.whnfCore
code: /--
Apply beta-reduction, zeta-reduction (i.e., unfold let local-decls), iota-reduction,
expand let-expressions, expand assigned meta-variables.
-/
partial def whnfCore (e : Expr) (config : WhnfCoreConfig := {}): MetaM Expr 
goal: Lean.MetaM Lean.Expr

full_name: Lean.Meta.smartUnfoldingReduce?.go
code: /--
  Recall that `_sunfold` auxiliary definitions contains the markers: `markSmartUnfoldingMatch` (*) and `markSmartUnfoldingMatchAlt` (**).
  For example, consider the following definition
  ```
  def r (i j : Nat) : Nat :=
    i +
      match j with
      | Nat.zero => 1
      | Nat.succ j =>
        i + match j with
            | Nat.zero => 2
            | Nat.succ j => r i j
  ```
  produces the following `_sunfold` auxiliary definition with the markers
  ```
  def r._sunfold (i j : Nat) : Nat :=
    i +
      (*) match j with
      | Nat.zero => (**) 1
      | Nat.succ j =>
        i + (*) match j with
            | Nat.zero => (**) 2
            | Nat.succ j => (**) r i j
  ```

  `match` expressions marked with `markSmartUnfoldingMatch` (*) must be reduced, otherwise the resulting term is not definitionally
   equal to the given expression. The recursion may be interrupted as soon as the annotation `markSmartUnfoldingAlt` (**) is reached.

  For example, the term `r i j.succ.succ` reduces to the definitionally equal term `i + i * r i j`
-/
partial def smartUnfoldingReduce? (e : Expr) : MetaM (Option Expr) 
goal: OptionT Lean.MetaM Lean.Expr

full_name: Lean.Meta.smartUnfoldingReduce?.goMatch
code: /--
  Recall that `_sunfold` auxiliary definitions contains the markers: `markSmartUnfoldingMatch` (*) and `markSmartUnfoldingMatchAlt` (**).
  For example, consider the following definition
  ```
  def r (i j : Nat) : Nat :=
    i +
      match j with
      | Nat.zero => 1
      | Nat.succ j =>
        i + match j with
            | Nat.zero => 2
            | Nat.succ j => r i j
  ```
  produces the following `_sunfold` auxiliary definition with the markers
  ```
  def r._sunfold (i j : Nat) : Nat :=
    i +
      (*) match j with
      | Nat.zero => (**) 1
      | Nat.succ j =>
        i + (*) match j with
            | Nat.zero => (**) 2
            | Nat.succ j => (**) r i j
  ```

  `match` expressions marked with `markSmartUnfoldingMatch` (*) must be reduced, otherwise the resulting term is not definitionally
   equal to the given expression. The recursion may be interrupted as soon as the annotation `markSmartUnfoldingAlt` (**) is reached.

  For example, the term `r i j.succ.succ` reduces to the definitionally equal term `i + i * r i j`
-/
partial def smartUnfoldingReduce? (e : Expr) : MetaM (Option Expr) 
goal: OptionT Lean.MetaM Lean.Expr

full_name: Lean.Meta.smartUnfoldingReduce?
code: /--
  Recall that `_sunfold` auxiliary definitions contains the markers: `markSmartUnfoldingMatch` (*) and `markSmartUnfoldingMatchAlt` (**).
  For example, consider the following definition
  ```
  def r (i j : Nat) : Nat :=
    i +
      match j with
      | Nat.zero => 1
      | Nat.succ j =>
        i + match j with
            | Nat.zero => 2
            | Nat.succ j => r i j
  ```
  produces the following `_sunfold` auxiliary definition with the markers
  ```
  def r._sunfold (i j : Nat) : Nat :=
    i +
      (*) match j with
      | Nat.zero => (**) 1
      | Nat.succ j =>
        i + (*) match j with
            | Nat.zero => (**) 2
            | Nat.succ j => (**) r i j
  ```

  `match` expressions marked with `markSmartUnfoldingMatch` (*) must be reduced, otherwise the resulting term is not definitionally
   equal to the given expression. The recursion may be interrupted as soon as the annotation `markSmartUnfoldingAlt` (**) is reached.

  For example, the term `r i j.succ.succ` reduces to the definitionally equal term `i + i * r i j`
-/
partial def smartUnfoldingReduce? (e : Expr) : MetaM (Option Expr) 
goal: Lean.MetaM (Option Lean.Expr)

full_name: Lean.Meta.unfoldDefinition
code: def unfoldDefinition (e : Expr) : MetaM Expr 
goal: Lean.MetaM Lean.Expr

full_name: Lean.Meta.whnfHeadPred
code: @[specialize] partial def whnfHeadPred (e : Expr) (pred : Expr → MetaM Bool) : MetaM Expr 
goal: Lean.MetaM Lean.Expr

full_name: Lean.Meta.whnfUntil
code: def whnfUntil (e : Expr) (declName : Name) : MetaM (Option Expr) 
goal: Lean.MetaM (Option Lean.Expr)

full_name: Lean.Meta.reduceRecMatcher?
code: /-- Try to reduce matcher/recursor/quot applications. We say they are all "morally" recursor applications. -/
def reduceRecMatcher? (e : Expr) : MetaM (Option Expr) 
goal: Lean.MetaM (Option Lean.Expr)

full_name: Lean.Meta.reduceBoolNativeUnsafe
code: unsafe def reduceBoolNativeUnsafe (constName : Name) : MetaM Bool 
goal: Lean.MetaM Bool

full_name: Lean.Meta.reduceNatNativeUnsafe
code: unsafe def reduceNatNativeUnsafe (constName : Name) : MetaM Nat 
goal: Lean.MetaM Nat

full_name: Lean.Meta.reduceBoolNative
code: @[implemented_by reduceBoolNativeUnsafe] opaque reduceBoolNative (constName : Name) : MetaM Bool
goal: Lean.MetaM Bool

full_name: Lean.Meta.reduceNatNative
code: @[implemented_by reduceNatNativeUnsafe] opaque reduceNatNative (constName : Name) : MetaM Nat
goal: Lean.MetaM Nat

full_name: Lean.Meta.reduceNative?
code: def reduceNative? (e : Expr) : MetaM (Option Expr) 
goal: Lean.MetaM (Option Lean.Expr)

full_name: Lean.Meta.withNatValue
code: @[inline] def withNatValue (a : Expr) (k : Nat → MetaM (Option α)) : MetaM (Option α) 
goal: Lean.MetaM (Option α)

full_name: Lean.Meta.reduceUnaryNatOp
code: def reduceUnaryNatOp (f : Nat → Nat) (a : Expr) : MetaM (Option Expr) 
goal: Lean.MetaM (Option Lean.Expr)

full_name: Lean.Meta.reduceBinNatOp
code: def reduceBinNatOp (f : Nat → Nat → Nat) (a b : Expr) : MetaM (Option Expr) 
goal: Lean.MetaM (Option Lean.Expr)

full_name: Lean.Meta.reduceBinNatPred
code: def reduceBinNatPred (f : Nat → Nat → Bool) (a b : Expr) : MetaM (Option Expr) 
goal: Lean.MetaM (Option Lean.Expr)

full_name: Lean.Meta.reduceNat?
code: def reduceNat? (e : Expr) : MetaM (Option Expr) 
goal: Lean.MetaM (Option Lean.Expr)

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Meta.WHNF.0.Lean.Meta.useWHNFCache
code: @[inline] private def useWHNFCache (e : Expr) : MetaM Bool 
goal: Lean.MetaM Bool

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Meta.WHNF.0.Lean.Meta.cached?
code: @[inline] private def cached? (useCache : Bool) (e : Expr) : MetaM (Option Expr) 
goal: Lean.MetaM (Option Lean.Expr)

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Meta.WHNF.0.Lean.Meta.cache
code: private def cache (useCache : Bool) (e r : Expr) : MetaM Expr 
goal: Lean.MetaM Lean.Expr

full_name: Lean.Meta.whnfImp
code: @[export lean_whnf]
partial def whnfImp (e : Expr) : MetaM Expr 
goal: Lean.MetaM Lean.Expr

full_name: Lean.Meta.reduceProjOf?
code: /-- If `e` is a projection function that satisfies `p`, then reduce it -/
def reduceProjOf? (e : Expr) (p : Name → Bool) : MetaM (Option Expr) 
goal: Lean.MetaM (Option Lean.Expr)

full_name: Lean.Meta.initFn._@..lake.packages.lean4.src.lean.Lean.Meta.WHNF._hyg.10411
code: builtin_initialize
  registerTraceClass `Meta.whnf
  registerTraceClass `Meta.isDefEq.whnf.reduceBinOp
goal: IO Unit