- default : binder_info
- implicit : binder_info
- strict_implicit : binder_info
- inst_implicit : binder_info
- aux_decl : binder_info
Auxiliary annotation for binders (Lambda and Pi).
This information is only used for elaboration.
The difference between {}
and ⦃⦄
is how implicit arguments are treated that are not followed by explicit arguments.
{}
arguments are applied eagerly, while ⦃⦄
arguments are left partially applied:
def foo {x : ℕ} : ℕ := x
def bar ⦃x : ℕ⦄ : ℕ := x
#check foo -- foo : ℕ
#check bar -- bar : Π ⦃x : ℕ⦄, ℕ
Equations
- binder_info.has_repr = {repr := λ (bi : binder_info), binder_info.has_repr._match_1 bi}
- binder_info.has_repr._match_1 binder_info.aux_decl = "aux_decl"
- binder_info.has_repr._match_1 binder_info.inst_implicit = "inst_implicit"
- binder_info.has_repr._match_1 binder_info.strict_implicit = "strict_implicit"
- binder_info.has_repr._match_1 binder_info.implicit = "implicit"
- binder_info.has_repr._match_1 binder_info.default = "default"
Macros are basically "promises" to build an expr by some C++ code, you can't build them in Lean. You can unfold a macro and force it to evaluate. They are used for
sorry
.- Term placeholders (
_
) inpexpr
s. - Expression annotations. See
expr.is_annotation
. - Meta-recursive calls. Eg:
lean meta def Y : (α → α) → α | f := f (Y f)
TheY
that appears inf (Y f)
is a macro. - Builtin projections:
lean structure foo := (mynat : ℕ) #print foo.mynat -- @[reducible] -- def foo.mynat : foo → ℕ := -- λ (c : foo), [foo.mynat c]
The thing in square brackets is a macro. - Ephemeral structures inside certain specialised C++ implemented tactics.
- var : Π (elaborated : bool := bool.tt), ℕ → expr elaborated
- sort : Π (elaborated : bool := bool.tt), level → expr elaborated
- const : Π (elaborated : bool := bool.tt), name → list level → expr elaborated
- mvar : Π (elaborated : bool := bool.tt), name → name → expr elaborated → expr elaborated
- local_const : Π (elaborated : bool := bool.tt), name → name → binder_info → expr elaborated → expr elaborated
- app : Π (elaborated : bool := bool.tt), expr elaborated → expr elaborated → expr elaborated
- lam : Π (elaborated : bool := bool.tt), name → binder_info → expr elaborated → expr elaborated → expr elaborated
- pi : Π (elaborated : bool := bool.tt), name → binder_info → expr elaborated → expr elaborated → expr elaborated
- elet : Π (elaborated : bool := bool.tt), name → expr elaborated → expr elaborated → expr elaborated → expr elaborated
- macro : Π (elaborated : bool := bool.tt), macro_def → list (expr elaborated) → expr elaborated
An expression. eg (4+5)
.
The elab
flag is indicates whether the expr
has been elaborated and doesn't contain any placeholder macros.
For example the equality x = x
is represented in expr ff
as app (app (const `eq _) x) x
while in expr tt
it is represented as app (app (app (const `eq _) t) x) x
(one more argument).
The VM replaces instances of this datatype with the C++ implementation.
Expressions can be annotated using an annotation macro during compilation.
For example, a have x:X, from p, q
expression will be compiled to (λ x:X,q)(p)
, but nested in an annotation macro with the name "have"
.
These annotations have no real semantic meaning, but are useful for helping Lean's pretty printer.
Compares expressions, including binder names.
Compares expressions while ignoring binder names.
Coercion for letting users write (f a) instead of (expr.app f a)
Each expression created by Lean carries a hash. This is calculated upon creation of the expression. Two structurally equal expressions will have the same hash.
expr.replace e f
Traverse over an expr e
with a function f
which can decide to replace subexpressions or not.
For each subexpression s
in the expression tree, f s n
is called where n
is how many binders are present above the given subexpression s
.
If f s n
returns none
, the children of s
will be traversed.
Otherwise if some s'
is returned, s'
will replace s
and this subexpression will not be traversed further.
abstract_local e n
replaces each instance of the local constant with unique (not pretty) name n
in e
with a de-Bruijn variable.
Multi version of abstract_local
. Note that the given expression will only be traversed once, so this is not the same as list.foldl expr.abstract_local
.
abstract e x
Abstracts the expression e
over the local constant x
.
Expressions depend on level
s, and these may depend on universe parameters which have names.
instantiate_univ_params e [(n₁,l₁), ...]
will traverse e
and replace any universe parameters with name nᵢ
with the corresponding level lᵢ
.
instantiate_var a b
takes the 0th de-Bruijn variable in a
and replaces each occurrence with b
.
Same as instantiate_vars
except lifts and shifts the vars by the given amount.
instantiate_vars_core `(#0 #1 #2 #3) 0 [x,y] = `(x y #0 #1)
instantiate_vars_core `(#0 #1 #2 #3) 1 [x,y] = `(#0 x y #1)
instantiate_vars_core `(#0 #1 #2 #3) 2 [x,y] = `(#0 #1 x y)
Perform beta-reduction if the left expression is a lambda, or construct an application otherwise.
That is: expr.subst `(λ x, %%Y) Z = Y[x/Z]
, and
expr.subst X Z = X.app Z
otherwise
get_free_var_range e
returns one plus the maximum de-Bruijn value in e
. Eg get_free_var_range
(#1 #0)yields
2`
has_var_idx e n
returns true iff e
has a free variable with de-Bruijn index n
.
has_local e
returns true if e
contains a local constant.
has_meta_var e
returns true iff e
contains a metavariable.
copy_pos_info src tgt
copies position information from src
to tgt
.
There is a macro called a "nat_value_macro" holding a natural number which are used during compilation. This function extracts that to a natural number. [NOTE] This is not used anywhere in Lean.
Get a list of all of the universe parameters that the given expression depends on.
occurs e t
returns tt
iff e
occurs in t
up to α-equivalence. Purely structural: no unification or definitional equality.
Computes the maximum depth of the expression (constant time).
(reflected a) is a special opaque container for a closed expr
representing a
.
It can only be obtained via type class inference, which will use the representation
of a
in the calling context. Local constants in the representation are replaced
by nested inference of reflected
instances.
The quotation expression `(a)
(outside of patterns) is equivalent to reflect a
and thus can be used as an explicit way of inferring an instance of reflected a
.
Instances
Compares expressions, ignoring binder names, and sorting by hash.
Checks whether e is sorry, and returns its type.
(bind_lambda e l) abstracts and lambda-binds the local l
in e