This module provides functions for "closing" open terms and creating auxiliary definitions. Here, we say a term is "open" if it contains free/meta-variables.
The "closure" is performed by lambda abstracting the free/meta-variables. Recall that in dependent type theory lambda abstracting a let-variable may produce type incorrect terms. For example, given the context
(n : Nat := 20)
(x : Vector α n)
(y : Vector α 20)
the term x = y
is correct. However, its closure using lambda abstractions
is not.
fun (n : Nat) (x : Vector α n) (y : Vector α 20) => x = y
A previous version of this module would address this issue by always use let-expressions to abstract let-vars. In the example above, it would produce
let n : Nat := 20; fun (x : Vector α n) (y : Vector α 20) => x = y
This approach produces correct result, but produces unsatisfactory results when we want to create auxiliary definitions. For example, consider the context
(x : Nat)
(y : Nat := fact x)
and the term h (g y)
, now suppose we want to create an auxiliary definition for y
.
The previous version of this module would compute the auxiliary definition
def aux := fun (x : Nat) => let y : Nat := fact x; h (g y)
and would return the term aux x
as a substitute for h (g y)
.
This is correct, but we will re-evaluate fact x
whenever we use aux
.
In this module, we produce
def aux := fun (y : Nat) => h (g y)
Note that in this particular case, it is safe to lambda abstract the let-varible y
.
This module uses the following approach to decide whether it is safe or not to lambda
abstract a let-variable.
- We enable zetaDelta-expansion tracking in
MetaM
. That is, whenever we perform type checking if a let-variable needs to zetaDelta expanded, we store it in the setzetaDeltaFVarIds
. We say a let-variable is zetaDelta expanded when we replace it with its value. - We use the
MetaM
type checkercheck
to type check the expression we want to close, and the type of the binders. - If a let-variable is not in
zetaDeltaFVarIds
, we lambda abstract it.
Remark: We still use let-expressions for let-variables in zetaDeltaFVarIds
, but we move the
let
inside the lambdas. The idea is to make sure the auxiliary definition does not have
an interleaving of lambda
and let
expressions. Thus, if the let-variable occurs in
the type of one of the lambdas, we simply zeta-expand it there.
As a final example consider the context
(x_1 : Nat)
(x_2 : Nat)
(x_3 : Nat)
(x : Nat := fact (10 + x_1 + x_2 + x_3))
(ty : Type := Nat → Nat)
(f : ty := fun x => x)
(n : Nat := 20)
(z : f 10)
and we use this module to compute an auxiliary definition for the term
(let y : { v : Nat // v = n } := ⟨20, rfl⟩; y.1 + n + f x, z + 10)
we obtain
def aux (x : Nat) (f : Nat → Nat) (z : Nat) : Nat×Nat :=
let n : Nat := 20;
(let y : {v // v=n} := {val := 20, property := ex._proof_1}; y.val+n+f x, z+10)
BTW, this module also provides the zetaDelta : Bool
flag. When set to true, it
expands all let-variables occurring in the target expression.
- fvarId : Lean.FVarId
- newFVarId : Lean.FVarId
Instances For
Equations
- Lean.Meta.Closure.instInhabitedToProcessElement = { default := { fvarId := default, newFVarId := default } }
- visitedLevel : Lean.LevelMap Lean.Level
- visitedExpr : Lean.ExprStructMap Lean.Expr
- nextLevelIdx : Nat
- levelArgs : Array Lean.Level
- newLocalDecls : Array Lean.LocalDecl
- newLocalDeclsForMVars : Array Lean.LocalDecl
- newLetDecls : Array Lean.LocalDecl
- nextExprIdx : Nat
- toProcess : Array Lean.Meta.Closure.ToProcessElement
Instances For
Equations
Instances For
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
Remark: This method does not guarantee unique user names. The correctness of the procedure does not rely on unique user names. Recall that the pretty printer takes care of unintended collisions.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
Instances For
Instances For
Instances For
Equations
- Lean.Meta.Closure.mkLambda decls b = Lean.Meta.Closure.mkBinding true decls b
Instances For
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
Instances For
Create an auxiliary definition with the given name, type and value.
The parameters type
and value
may contain free and meta variables.
A "closure" is computed, and a term of the form name.{u_1 ... u_n} t_1 ... t_m
is
returned where u_i
s are universe parameters and metavariables type
and value
depend on,
and t_j
s are free and meta variables type
and value
depend on.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Similar to mkAuxDefinition
, but infers the type of value
.
Equations
- Lean.Meta.mkAuxDefinitionFor name value zetaDelta = do let type ← Lean.Meta.inferType value let type : Lean.Expr := type.headBeta Lean.Meta.mkAuxDefinition name type value zetaDelta
Instances For
Create an auxiliary theorem with the given name, type and value. It is similar to mkAuxDefinition
.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Similar to mkAuxTheorem
, but infers the type of value
.