File: Mathlib/Tactic/LiftLets.lean

full_name: Lean.Expr.LiftLetsConfig.proofs
code: /-- Configuration for `Lean.Expr.liftLets` and the `lift_lets` tactic. -/
structure Lean.Expr.LiftLetsConfig where
  /-- Whether to lift lets out of proofs. The default is not to. -/
  proofs : Bool := false
  /-- Whether to merge let bindings if they have the same type and value.
  This test is by syntactic equality, not definitional equality.
  The default is to merge. -/
  merge : Bool := true
goal: Bool

full_name: Lean.Expr.LiftLetsConfig
code: /-- Configuration for `Lean.Expr.liftLets` and the `lift_lets` tactic. -/
structure Lean.Expr.LiftLetsConfig where
  /-- Whether to lift lets out of proofs. The default is not to. -/
  proofs : Bool := false
  /-- Whether to merge let bindings if they have the same type and value.
  This test is by syntactic equality, not definitional equality.
  The default is to merge. -/
  merge : Bool := true
goal: Type

full_name: Lean.Expr.LiftLetsConfig.merge
code: /-- Configuration for `Lean.Expr.liftLets` and the `lift_lets` tactic. -/
structure Lean.Expr.LiftLetsConfig where
  /-- Whether to lift lets out of proofs. The default is not to. -/
  proofs : Bool := false
  /-- Whether to merge let bindings if they have the same type and value.
  This test is by syntactic equality, not definitional equality.
  The default is to merge. -/
  merge : Bool := true
goal: Bool

full_name: _private.Mathlib.Tactic.LiftLets.0.Lean.Expr.liftLetsAux
code: /--
Auxiliary definition for `Lean.Expr.liftLets`. Takes a list of the accumulated fvars.
This list is used during the computation to merge let bindings.
-/
private partial def Lean.Expr.liftLetsAux (config : LiftLetsConfig) (e : Expr) (fvars : Array Expr)
    (f : Array Expr → Expr → MetaM Expr) : MetaM Expr 
goal: Lean.MetaM Lean.Expr

full_name: _private.Mathlib.Tactic.LiftLets.0.Lean.Expr.liftLetsAux.insideLets
code: /--
Auxiliary definition for `Lean.Expr.liftLets`. Takes a list of the accumulated fvars.
This list is used during the computation to merge let bindings.
-/
private partial def Lean.Expr.liftLetsAux (config : LiftLetsConfig) (e : Expr) (fvars : Array Expr)
    (f : Array Expr → Expr → MetaM Expr) : MetaM Expr 
goal: Lean.MetaM α

full_name: Lean.Expr.liftLets
code: /-- Take all the `let`s in an expression and move them outwards as far as possible.
All top-level `let`s are added to the local context, and then `f` is called with the list
of local bindings (each an fvar) and the new expression.

Let bindings are merged if they have the same type and value.

Use `e.liftLets mkLetFVars` to get a defeq expression with all `let`s lifted as far as possible. -/
def Lean.Expr.liftLets (e : Expr) (f : Array Expr → Expr → MetaM Expr)
    (config : LiftLetsConfig := {}) : MetaM Expr 
goal: Lean.MetaM Lean.Expr

full_name: Mathlib.Tactic.evalUnsafe._@.Mathlib.Tactic.LiftLets._hyg.1089
code: declare_config_elab elabConfig Lean.Expr.LiftLetsConfig
goal: Lean.Expr → Lean.Elab.TermElabM Lean.Expr.LiftLetsConfig

full_name: Mathlib.Tactic.elabConfig
code: declare_config_elab elabConfig Lean.Expr.LiftLetsConfig
goal: Lean.Syntax → Lean.Elab.TermElabM Lean.Expr.LiftLetsConfig

full_name: Mathlib.Tactic.eval._@.Mathlib.Tactic.LiftLets._hyg.1089
code: declare_config_elab elabConfig Lean.Expr.LiftLetsConfig
goal: Lean.Expr → Lean.Elab.TermElabM Lean.Expr.LiftLetsConfig

full_name: Mathlib.Tactic.lift_lets
code: /--
Lift all the `let` bindings in the type of an expression as far out as possible.

When applied to the main goal, this gives one the ability to `intro` embedded `let` expressions.
For example,
```lean
example : (let x := 1; x) = 1 := by
  lift_lets
  -- ⊢ let x := 1; x = 1
  intro x
  sorry
```

During the lifting process, let bindings are merged if they have the same type and value.
-/
syntax (name := lift_lets) "lift_lets" (Parser.Tactic.config)? (ppSpace location)? : tactic
goal: Lean.ParserDescr

full_name: Mathlib.Tactic._aux_Mathlib_Tactic_LiftLets___elabRules_Mathlib_Tactic_lift_lets_1
code: elab_rules : tactic
  | `(tactic| lift_lets $[$cfg:config]? $[$loc:location]?) => do
    let config ← elabConfig (mkOptionalNode cfg)
    withLocation (expandOptLocation (Lean.mkOptionalNode loc))
      (atLocal := fun h ↦ liftMetaTactic1 fun mvarId ↦ do
        let hTy ← instantiateMVars (← h.getType)
        mvarId.changeLocalDecl h (← hTy.liftLets mkLetFVars config))
      (atTarget := liftMetaTactic1 fun mvarId ↦ do
        let ty ← instantiateMVars (← mvarId.getType)
        mvarId.change (← ty.liftLets mkLetFVars config))
      (failed := fun _ ↦ throwError "lift_lets tactic failed")
goal: Lean.Elab.Tactic.Tactic