Documentation

Lean.Meta.WHNF

Equations
    Instances For

      Smart unfolding support #

      @[extern lean_get_structural_rec_arg_pos]

      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.

      Equations
        Instances For
          @[inline]
          Equations
            Instances For
              Equations
                Instances For

                  Add auxiliary annotation to indicate the match-expression e must be reduced when performing smart unfolding.

                  Equations
                    Instances For
                      Equations
                        Instances For

                          Add auxiliary annotation to indicate expression e (a match alternative rhs) was successfully reduced by smart unfolding.

                          Equations
                            Instances For
                              Equations
                                Instances For

                                  Helper methods #

                                  def Lean.Meta.isAuxDef (constName : Name) :
                                  Equations
                                    Instances For

                                      Helper functions for reducing recursors #

                                      def Lean.Meta.mkProjFn (ctorVal : ConstructorVal) (us : List Level) (params : Array Expr) (i : Nat) (major : Expr) :

                                      Create the ith projection major. It tries to use the auto-generated projection functions if available. Otherwise falls back to Expr.proj.

                                      Equations
                                        Instances For

                                          Helper functions for reducing Quot.lift and Quot.ind #

                                          Helper function for extracting "stuck term" #

                                          Return some (Expr.mvar mvarId) if metavariable mvarId is blocking reduction.

                                          Weak Head Normal Form auxiliary combinators #

                                          @[specialize #[]]
                                          partial def Lean.Meta.whnfEasyCases (e : Expr) (k : ExprMetaM Expr) :

                                          Auxiliary combinator for handling easy WHNF cases. It takes a function for handling the "hard" cases as an argument

                                          Instances For

                                            The "match" compiler uses dependent if-then-else dite 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 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, if the transparency mode is .reducible or .instances, we first eagerly unfold dite constants used in the auxiliary match-declaration, and then use a custom canUnfoldAtMatcher predicate for whnfMatcher.

                                            Remark: we used to include dite (and ite) as auxiliary declarations to unfold at canUnfoldAtMatcher, but this is problematic because the dite/ite may occur in the discriminant. See issue #5388.

                                            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.

                                            Remark: if the eager unfolding is problematic, we may cache the result. We may also consider not using dite in the match-compiler and use Decidable.casesOn, but it will require changes in how we generate equation lemmas.

                                            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.

                                            Auxiliary predicate for whnfMatcher. See comment above.

                                            Equations
                                              Instances For
                                                Equations
                                                  Instances For
                                                    Equations
                                                      Instances For

                                                        Reduce kernel projection Expr.proj .. expression.

                                                        Equations
                                                          Instances For
                                                            partial def Lean.Meta.expandLet (e : Expr) (vs : Array Expr) (zetaHave : Bool := true) :

                                                            Zeta reduces lets/haves. If zetaHave is false, then haves are not zeta reduced.

                                                            Auxiliary function for whnfCore and Simp.reduceStep, to implement the zeta option. This function does not implement zetaUnused logic, which is instead the responsibility of consumeUnusedLet. The expandLet function works with expressions with loose bound variables, and thus determining whether a let variable is used isn't an O(1) operation.

                                                            Note: since expandLet and consumeUnusedLet are separated like this, a consequence is that in the +zeta -zetaHave +zetaUnused configuration, then whnfCore has quadratic complexity when reducing a sequence of alternating lets and haves where the lets are used but the haves are unused.

                                                            partial def Lean.Meta.consumeUnusedLet (e : Expr) (consumeNondep : Bool := false) :

                                                            Consumes unused lets/haves. If consumeNondep is false, then haves are not consumed.

                                                            Auxiliary function for whnfCore, isDefEqQuick, and Simp.reduceStep, to implement the zetaUnused option. In the case of isDefEqQuick, it is also used when zeta is set.

                                                            Apply beta-reduction, zeta-reduction (i.e., unfold let local-decls), iota-reduction, expand let-expressions, expand assigned meta-variables, unfold aux declarations.

                                                            Equations
                                                              Instances For

                                                                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

                                                                Equations
                                                                  Instances For

                                                                    Auxiliary method for unfolding a class projection.

                                                                    Auxiliary method for unfolding a class projection when transparency is set to TransparencyMode.instances. Recall that class instance projections are not marked with [reducible] because we want them to be in "reducible canonical form".

                                                                    partial def Lean.Meta.unfoldDefinition? (e : Expr) (ignoreTransparency : Bool := false) :

                                                                    Unfold definition using "smart unfolding" if possible. If ignoreTransparency = true, then the definition is unfolded even if the transparency setting does not allow it.

                                                                    Equations
                                                                      Instances For
                                                                        @[specialize #[]]
                                                                        partial def Lean.Meta.whnfHeadPred (e : Expr) (pred : ExprMetaM Bool) :
                                                                        def Lean.Meta.whnfUntil (e : Expr) (declName : Name) :
                                                                        Equations
                                                                          Instances For

                                                                            Applies whnfCore while unfolding type annotations (outParam/optParam/etc.).

                                                                            Equations
                                                                              Instances For

                                                                                Try to reduce matcher/recursor/quot applications. We say they are all "morally" recursor applications.

                                                                                Equations
                                                                                  Instances For
                                                                                    Equations
                                                                                      Instances For
                                                                                        unsafe def Lean.Meta.reduceNatNativeUnsafe (constName : Name) :
                                                                                        Equations
                                                                                          Instances For
                                                                                            @[implemented_by Lean.Meta.reduceBoolNativeUnsafe]
                                                                                            @[implemented_by Lean.Meta.reduceNatNativeUnsafe]
                                                                                            opaque Lean.Meta.reduceNatNative (constName : Name) :
                                                                                            Equations
                                                                                              Instances For
                                                                                                @[inline]
                                                                                                def Lean.Meta.withNatValue {α : Type} (a : Expr) (k : NatMetaM (Option α)) :
                                                                                                Equations
                                                                                                  Instances For
                                                                                                    Equations
                                                                                                      Instances For
                                                                                                        def Lean.Meta.reduceBinNatOp (f : NatNatNat) (a b : Expr) :
                                                                                                        Equations
                                                                                                          Instances For
                                                                                                            Equations
                                                                                                              Instances For
                                                                                                                Equations
                                                                                                                  Instances For
                                                                                                                    Equations
                                                                                                                      Instances For
                                                                                                                        @[export lean_whnf]
                                                                                                                        partial def Lean.Meta.whnfImp (e : Expr) :

                                                                                                                        If e is a projection function that satisfies p, then reduce it

                                                                                                                        Equations
                                                                                                                          Instances For