feat(library/kernel_bindings): add sugar for level expressions in the Lua API

Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
Leonardo de Moura 2014-05-17 08:09:27 -07:00
parent 5fc0f06a8d
commit 4ec89e8561
2 changed files with 61 additions and 6 deletions

View file

@ -28,6 +28,14 @@ Author: Leonardo de Moura
// Lua Bindings for the Kernel classes. We do not include the Lua
// bindings in the kernel because we do not want to inflate the Kernel.
// In Lua, we can use the notations
// - l + k for succ^k(l)
// - k for succ^k(zero)
// The following definition is a limit on the k's that are considered.
#ifndef LEAN_MAX_LEVEL_OFFSET_IN_LUA
#define LEAN_MAX_LEVEL_OFFSET_IN_LUA 1024
#endif
namespace lean {
static environment get_global_environment(lua_State * L);
io_state * get_io_state(lua_State * L);
@ -38,6 +46,28 @@ DEFINE_LUA_LIST(level, push_level, to_level)
int push_optional_level(lua_State * L, optional<level> const & l) { return l ? push_level(L, *l) : push_nil(L); }
static level mk_offset(level const & l, int k) {
if (k < 0) throw exception(sstream() << "invalid level offset " << k << ", offsets must be nonnegative");
else if (k > LEAN_MAX_LEVEL_OFFSET_IN_LUA) throw exception(sstream() << "invalid level offset " << k << ", offset is too big");
level r = l;
while (k > 0) {
k--;
r = mk_succ(r);
}
return r;
}
static level to_level_ext(lua_State * L, int idx) {
if (lua_isnumber(L, idx))
return mk_offset(mk_level_zero(), lua_tonumber(L, idx));
else
return to_level(L, idx);
}
static int level_add(lua_State * L) {
return push_level(L, mk_offset(to_level(L, 1), luaL_checkinteger(L, 2)));
}
static int level_tostring(lua_State * L) {
std::ostringstream out;
options opts = get_global_options(L);
@ -53,9 +83,9 @@ static int level_lt(lua_State * L) {
}
static int mk_level_zero(lua_State * L) { return push_level(L, mk_level_zero()); }
static int mk_level_one(lua_State * L) { return push_level(L, mk_level_one()); }
static int mk_level_succ(lua_State * L) { return push_level(L, mk_succ(to_level(L, 1))); }
static int mk_level_max(lua_State * L) { return push_level(L, mk_max(to_level(L, 1), to_level(L, 2))); }
static int mk_level_imax(lua_State * L) { return push_level(L, mk_imax(to_level(L, 1), to_level(L, 2))); }
static int mk_level_succ(lua_State * L) { return push_level(L, mk_succ(to_level_ext(L, 1))); }
static int mk_level_max(lua_State * L) { return push_level(L, mk_max(to_level_ext(L, 1), to_level_ext(L, 2))); }
static int mk_level_imax(lua_State * L) { return push_level(L, mk_imax(to_level_ext(L, 1), to_level_ext(L, 2))); }
static int mk_param_univ(lua_State * L) { return push_level(L, mk_param_univ(to_name_ext(L, 1))); }
static int mk_global_univ(lua_State * L) { return push_level(L, mk_global_univ(to_name_ext(L, 1))); }
static int mk_meta_univ(lua_State * L) { return push_level(L, mk_meta_univ(to_name_ext(L, 1))); }
@ -73,7 +103,7 @@ LEVEL_PRED(has_param)
LEVEL_PRED(is_not_zero)
static int level_normalize(lua_State * L) { return push_level(L, normalize(to_level(L, 1))); }
static int level_get_kind(lua_State * L) { return push_integer(L, static_cast<int>(kind(to_level(L, 1)))); }
static int level_is_equivalent(lua_State * L) { return push_boolean(L, is_equivalent(to_level(L, 1), to_level(L, 2))); }
static int level_is_equivalent(lua_State * L) { return push_boolean(L, is_equivalent(to_level(L, 1), to_level_ext(L, 2))); }
static int level_is_eqp(lua_State * L) { return push_boolean(L, is_eqp(to_level(L, 1), to_level(L, 2))); }
static int level_id(lua_State * L) {
@ -117,6 +147,7 @@ static const struct luaL_Reg level_m[] = {
{"__tostring", safe_function<level_tostring>},
{"__eq", safe_function<level_eq>},
{"__lt", safe_function<level_lt>},
{"__add", safe_function<level_add>},
{"succ", safe_function<mk_level_succ>},
{"kind", safe_function<level_get_kind>},
{"is_zero", safe_function<level_is_zero>},
@ -381,7 +412,7 @@ static int expr_abst(lua_State * L) {
static int expr_fun(lua_State * L) { return expr_abst<false>(L); }
static int expr_pi(lua_State * L) { return expr_abst<true>(L); }
static int expr_mk_sort(lua_State * L) { return push_expr(L, mk_sort(to_level(L, 1))); }
static int expr_mk_sort(lua_State * L) { return push_expr(L, mk_sort(to_level_ext(L, 1))); }
static int expr_mk_metavar(lua_State * L) { return push_expr(L, mk_metavar(to_name_ext(L, 1), to_expr(L, 2))); }
static int expr_mk_local(lua_State * L) {
int nargs = lua_gettop(L);
@ -1365,7 +1396,8 @@ static int constraint_tostring(lua_State * L) {
return push_string(L, out.str().c_str());
}
static int mk_eq_cnstr(lua_State * L) { return push_constraint(L, mk_eq_cnstr(to_expr(L, 1), to_expr(L, 2), to_justification(L, 3))); }
static int mk_level_cnstr(lua_State * L) { return push_constraint(L, mk_level_cnstr(to_level(L, 1), to_level(L, 2), to_justification(L, 3))); }
static int mk_level_cnstr(lua_State * L) { return push_constraint(L, mk_level_cnstr(to_level_ext(L, 1), to_level_ext(L, 2),
to_justification(L, 3))); }
static int mk_choice_cnstr(lua_State * L) { return push_constraint(L, mk_choice_cnstr(to_expr(L, 1), to_list_expr_ext(L, 2), to_justification(L, 3))); }
static const struct luaL_Reg constraint_m[] = {

23
tests/lua/level6.lua Normal file
View file

@ -0,0 +1,23 @@
local l = mk_param_univ("l")
print(mk_sort(0))
print(mk_sort(1))
print(mk_sort(2))
print(mk_sort(l+2))
print(mk_sort(mk_level_max(l, 2)))
print(mk_sort(mk_level_imax(l, 2)))
assert(not pcall(function()
print(mk_sort(1000000000))
end
))
assert(not pcall(function()
print(mk_sort(-10))
end
))
print(mk_sort(l+0))
assert(not pcall(function()
print(mk_sort(0+l))
end
))
local z = mk_level_zero()
assert(is_level(z))
assert(z:is_equivalent(0))