feat(library/kernel_bindings): expr Lua API
Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
parent
305815cb56
commit
686c307976
1 changed files with 75 additions and 113 deletions
|
@ -10,6 +10,10 @@ Author: Leonardo de Moura
|
||||||
#include "util/script_state.h"
|
#include "util/script_state.h"
|
||||||
#include "util/list_lua.h"
|
#include "util/list_lua.h"
|
||||||
#include "kernel/abstract.h"
|
#include "kernel/abstract.h"
|
||||||
|
#include "kernel/for_each_fn.h"
|
||||||
|
#include "kernel/free_vars.h"
|
||||||
|
#include "kernel/instantiate.h"
|
||||||
|
#include "library/occurs.h"
|
||||||
#include "library/io_state_stream.h"
|
#include "library/io_state_stream.h"
|
||||||
#include "library/expr_lt.h"
|
#include "library/expr_lt.h"
|
||||||
#include "library/kernel_bindings.h"
|
#include "library/kernel_bindings.h"
|
||||||
|
@ -184,7 +188,14 @@ int push_optional_expr(lua_State * L, optional<expr> const & e) { return e ? pu
|
||||||
expr & to_app(lua_State * L, int idx) {
|
expr & to_app(lua_State * L, int idx) {
|
||||||
expr & r = to_expr(L, idx);
|
expr & r = to_expr(L, idx);
|
||||||
if (!is_app(r))
|
if (!is_app(r))
|
||||||
throw exception("Lean application expression expected");
|
throw exception(sstream() << "arg #" << idx << " must be an application");
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
expr & to_binder(lua_State * L, int idx) {
|
||||||
|
expr & r = to_expr(L, idx);
|
||||||
|
if (!is_binder(r))
|
||||||
|
throw exception(sstream() << "arg #" << idx << " must be a binder (i.e., lambda or Pi)");
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -310,37 +321,40 @@ EXPR_PRED(has_param_univ)
|
||||||
EXPR_PRED(has_free_vars)
|
EXPR_PRED(has_free_vars)
|
||||||
EXPR_PRED(closed)
|
EXPR_PRED(closed)
|
||||||
|
|
||||||
// static int expr_fields(lua_State * L) {
|
static int expr_fields(lua_State * L) {
|
||||||
// expr & e = to_expr(L, 1);
|
expr & e = to_expr(L, 1);
|
||||||
// switch (e.kind()) {
|
switch (e.kind()) {
|
||||||
// case expr_kind::Var: return pushinteger(L, var_idx(e));
|
case expr_kind::Var:
|
||||||
// case expr_kind::Constant: push_name(L, const_name(e));
|
return pushinteger(L, var_idx(e));
|
||||||
// case expr_kind::Sort: return push_level(L, ty_level(e));
|
case expr_kind::Constant:
|
||||||
// case expr_kind::Macro: return to_macro(e).push_lua(L);
|
push_name(L, const_name(e)); push_list_level(L, const_level_params(e)); return 2;
|
||||||
// case expr_kind::App: lua_pushinteger(L, num_args(e)); expr_args(L); return 2;
|
case expr_kind::Sort:
|
||||||
// case expr_kind::HEq: push_expr(L, heq_lhs(e)); push_expr(L, heq_rhs(e)); return 3;
|
return push_level(L, sort_level(e));
|
||||||
// case expr_kind::Pair: push_expr(L, pair_first(e)); push_expr(L, pair_second(e)); push_expr(L, pair_type(e)); return 3;
|
case expr_kind::Macro:
|
||||||
// case expr_kind::Proj: lua_pushboolean(L, proj_first(e)); push_expr(L, proj_arg(e)); return 2;
|
// TODO(Leo)
|
||||||
// case expr_kind::Lambda:
|
return 0;
|
||||||
// case expr_kind::Pi:
|
case expr_kind::App:
|
||||||
// case expr_kind::Sigma:
|
push_expr(L, app_fn(e)); push_expr(L, app_arg(e)); return 2;
|
||||||
// push_name(L, abst_name(e)); push_expr(L, abst_domain(e)); push_expr(L, abst_body(e)); return 3;
|
case expr_kind::Lambda:
|
||||||
// case expr_kind::Let:
|
case expr_kind::Pi:
|
||||||
// push_name(L, let_name(e)); push_optional_expr(L, let_type(e)); push_expr(L, let_value(e)); push_expr(L, let_body(e)); return 4;
|
push_name(L, binder_name(e)); push_expr(L, binder_domain(e)); push_expr(L, binder_body(e)); push_expr_binder_info(L, binder_info(e)); return 4;
|
||||||
// case expr_kind::MetaVar: push_name(L, metavar_name(e)); push_local_context(L, metavar_lctx(e)); return 2;
|
case expr_kind::Let:
|
||||||
// }
|
push_name(L, let_name(e)); push_expr(L, let_type(e)); push_expr(L, let_value(e)); push_expr(L, let_body(e)); return 4;
|
||||||
// lean_unreachable(); // LCOV_EXCL_LINE
|
case expr_kind::Meta:
|
||||||
// return 0; // LCOV_EXCL_LINE
|
case expr_kind::Local:
|
||||||
// }
|
push_name(L, mlocal_name(e)); push_expr(L, mlocal_type(e)); return 2;
|
||||||
|
}
|
||||||
|
lean_unreachable(); // LCOV_EXCL_LINE
|
||||||
|
return 0; // LCOV_EXCL_LINE
|
||||||
|
}
|
||||||
|
|
||||||
static int expr_fn(lua_State * L) { return push_expr(L, app_fn(to_app(L, 1))); }
|
static int expr_fn(lua_State * L) { return push_expr(L, app_fn(to_app(L, 1))); }
|
||||||
static int expr_arg(lua_State * L) { return push_expr(L, app_arg(to_app(L, 1))); }
|
static int expr_arg(lua_State * L) { return push_expr(L, app_arg(to_app(L, 1))); }
|
||||||
|
|
||||||
#if 0
|
|
||||||
static int expr_for_each(lua_State * L) {
|
static int expr_for_each(lua_State * L) {
|
||||||
expr & e = to_expr(L, 1); // expr
|
expr & e = to_expr(L, 1); // expr
|
||||||
luaL_checktype(L, 2, LUA_TFUNCTION); // user-fun
|
luaL_checktype(L, 2, LUA_TFUNCTION); // user-fun
|
||||||
auto f = [&](expr const & a, unsigned offset) {
|
for_each(e, [&](expr const & a, unsigned offset) {
|
||||||
lua_pushvalue(L, 2); // push user-fun
|
lua_pushvalue(L, 2); // push user-fun
|
||||||
push_expr(L, a);
|
push_expr(L, a);
|
||||||
lua_pushinteger(L, offset);
|
lua_pushinteger(L, offset);
|
||||||
|
@ -350,9 +364,7 @@ static int expr_for_each(lua_State * L) {
|
||||||
r = lua_toboolean(L, -1);
|
r = lua_toboolean(L, -1);
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
return r;
|
return r;
|
||||||
};
|
});
|
||||||
for_each_fn<decltype(f)> proc(f);
|
|
||||||
proc(e);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -415,63 +427,17 @@ static int expr_abstract(lua_State * L) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int expr_occurs(lua_State * L) {
|
static int binder_name(lua_State * L) { return push_name(L, binder_name(to_binder(L, 1))); }
|
||||||
lua_pushboolean(L, occurs(to_expr(L, 1), to_expr(L, 2)));
|
static int binder_domain(lua_State * L) { return push_expr(L, binder_domain(to_binder(L, 1))); }
|
||||||
return 1;
|
static int binder_body(lua_State * L) { return push_expr(L, binder_body(to_binder(L, 1))); }
|
||||||
}
|
static int binder_info(lua_State * L) { return push_expr_binder_info(L, binder_info(to_binder(L, 1))); }
|
||||||
|
|
||||||
static int expr_is_eqp(lua_State * L) {
|
static int expr_occurs(lua_State * L) { return pushboolean(L, occurs(to_expr(L, 1), to_expr(L, 2))); }
|
||||||
lua_pushboolean(L, is_eqp(to_expr(L, 1), to_expr(L, 2)));
|
static int expr_is_eqp(lua_State * L) { return pushboolean(L, is_eqp(to_expr(L, 1), to_expr(L, 2))); }
|
||||||
return 1;
|
static int expr_hash(lua_State * L) { return pushinteger(L, to_expr(L, 1).hash()); }
|
||||||
}
|
static int expr_depth(lua_State * L) { return pushinteger(L, get_depth(to_expr(L, 1))); }
|
||||||
|
static int expr_is_lt(lua_State * L) { return pushboolean(L, is_lt(to_expr(L, 1), to_expr(L, 2), false)); }
|
||||||
|
|
||||||
static int expr_hash(lua_State * L) {
|
|
||||||
lua_pushinteger(L, to_expr(L, 1).hash());
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int expr_head_beta_reduce(lua_State * L) {
|
|
||||||
return push_expr(L, head_beta_reduce(to_expr(L, 1)));
|
|
||||||
}
|
|
||||||
|
|
||||||
static int expr_beta_reduce(lua_State * L) {
|
|
||||||
return push_expr(L, beta_reduce(to_expr(L, 1)));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void check_abstraction(lua_State * L, int idx, char const * msg) {
|
|
||||||
if (!is_abstraction(to_expr(L, idx)))
|
|
||||||
throw exception(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int expr_abst_name(lua_State * L) {
|
|
||||||
check_abstraction(L, 1, "invalid abst_name call, expression is not an abstraction");
|
|
||||||
return push_name(L, abst_name(to_expr(L, 1)));
|
|
||||||
}
|
|
||||||
|
|
||||||
static int expr_abst_domain(lua_State * L) {
|
|
||||||
check_abstraction(L, 1, "invalid abst_domain call, expression is not an abstraction");
|
|
||||||
return push_expr(L, abst_domain(to_expr(L, 1)));
|
|
||||||
}
|
|
||||||
|
|
||||||
static int expr_abst_body(lua_State * L) {
|
|
||||||
check_abstraction(L, 1, "invalid abst_body call, expression is not an abstraction");
|
|
||||||
return push_expr(L, abst_body(to_expr(L, 1)));
|
|
||||||
}
|
|
||||||
|
|
||||||
static int expr_mk_eq(lua_State * L) {
|
|
||||||
return push_expr(L, mk_eq(to_expr(L, 1), to_expr(L, 2), to_expr(L, 3)));
|
|
||||||
}
|
|
||||||
|
|
||||||
static int expr_depth(lua_State * L) {
|
|
||||||
lua_pushinteger(L, get_depth(to_expr(L, 1)));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int expr_is_lt(lua_State * L) {
|
|
||||||
lua_pushboolean(L, is_lt(to_expr(L, 1), to_expr(L, 2), false));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static const struct luaL_Reg expr_m[] = {
|
static const struct luaL_Reg expr_m[] = {
|
||||||
{"__gc", expr_gc}, // never throws
|
{"__gc", expr_gc}, // never throws
|
||||||
|
@ -499,27 +465,23 @@ static const struct luaL_Reg expr_m[] = {
|
||||||
{"has_param_univ", safe_function<expr_has_param_univ>},
|
{"has_param_univ", safe_function<expr_has_param_univ>},
|
||||||
{"arg", safe_function<expr_arg>},
|
{"arg", safe_function<expr_arg>},
|
||||||
{"fn", safe_function<expr_fn>},
|
{"fn", safe_function<expr_fn>},
|
||||||
|
{"fields", safe_function<expr_fields>},
|
||||||
// {"fields", safe_function<expr_fields>},
|
{"data", safe_function<expr_fields>},
|
||||||
// {"data", safe_function<expr_fields>},
|
{"depth", safe_function<expr_depth>},
|
||||||
// {"args", safe_function<expr_args>},
|
{"binder_name", safe_function<binder_name>},
|
||||||
// {"num_args", safe_function<expr_num_args>},
|
{"binder_domain", safe_function<binder_domain>},
|
||||||
// {"depth", safe_function<expr_depth>},
|
{"binder_body", safe_function<binder_body>},
|
||||||
// {"abst_name", safe_function<expr_abst_name>},
|
{"binder_info", safe_function<binder_info>},
|
||||||
// {"abst_domain", safe_function<expr_abst_domain>},
|
{"for_each", safe_function<expr_for_each>},
|
||||||
// {"abst_body", safe_function<expr_abst_body>},
|
{"has_free_var", safe_function<expr_has_free_var>},
|
||||||
// {"for_each", safe_function<expr_for_each>},
|
{"lift_free_vars", safe_function<expr_lift_free_vars>},
|
||||||
// {"has_free_var", safe_function<expr_has_free_var>},
|
{"lower_free_vars", safe_function<expr_lower_free_vars>},
|
||||||
// {"lift_free_vars", safe_function<expr_lift_free_vars>},
|
{"instantiate", safe_function<expr_instantiate>},
|
||||||
// {"lower_free_vars", safe_function<expr_lower_free_vars>},
|
{"abstract", safe_function<expr_abstract>},
|
||||||
// {"instantiate", safe_function<expr_instantiate>},
|
{"occurs", safe_function<expr_occurs>},
|
||||||
// {"beta_reduce", safe_function<expr_beta_reduce>},
|
{"is_eqp", safe_function<expr_is_eqp>},
|
||||||
// {"head_beta_reduce", safe_function<expr_head_beta_reduce>},
|
{"is_lt", safe_function<expr_is_lt>},
|
||||||
// {"abstract", safe_function<expr_abstract>},
|
{"hash", safe_function<expr_hash>},
|
||||||
// {"occurs", safe_function<expr_occurs>},
|
|
||||||
// {"is_eqp", safe_function<expr_is_eqp>},
|
|
||||||
// {"is_lt", safe_function<expr_is_lt>},
|
|
||||||
// {"hash", safe_function<expr_hash>},
|
|
||||||
{0, 0}
|
{0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue