refactor(kernel/converter): replace extra_opaque_set with predicate
It gives us more flexibility.
This commit is contained in:
parent
1fbb554a16
commit
ea1bae0143
8 changed files with 97 additions and 56 deletions
|
@ -23,31 +23,36 @@ namespace lean {
|
||||||
We also believe it increases the modularity of Lean developments by minimizing the dependency on how things are defined.
|
We also believe it increases the modularity of Lean developments by minimizing the dependency on how things are defined.
|
||||||
We should view non-opaque definitions as "inline definitions" used in programming languages such as C++.
|
We should view non-opaque definitions as "inline definitions" used in programming languages such as C++.
|
||||||
|
|
||||||
2) Whenever type checking an expression, the user can provide an additional set of definition names (m_extra_opaque) that
|
2) Whenever type checking an expression, the user can provide a predicate that is true for for additional definitions that
|
||||||
should be considered opaque. Note that, if \c t type checks when using an extra_opaque set S, then t also type checks
|
should be considered opaque. Note that, if \c t type checks when using predicate P, then t also type checks
|
||||||
(modulo resource constraints) with the empty set. Again, the purpose of extra_opaque is to mimimize the number
|
(modulo resource constraints) without it. Again, the purpose of the predicate is to mimimize the number
|
||||||
of delta-reduction steps.
|
of delta-reduction steps.
|
||||||
|
|
||||||
3) To be able to prove theorems about an opaque definition, we treat an opaque definition D in a module M as
|
3) To be able to prove theorems about an opaque definition, we treat an opaque definition D in a module M as
|
||||||
transparent when we are type checking another definition/theorem D' also in M. This rule only applies if
|
transparent when we are type checking another definition/theorem D' also in M. This rule only applies if
|
||||||
D is not a theorem, nor D is in the set m_extra_opaque. To implement this feature, this class has a field
|
D is not a theorem, nor pred(D) is true. To implement this feature, this class has a field
|
||||||
m_module_idx that is not none when this rule should be applied.
|
m_module_idx that is not none when this rule should be applied.
|
||||||
*/
|
*/
|
||||||
bool is_opaque(declaration const & d, name_set const & extra_opaque, optional<module_idx> const & mod_idx) {
|
bool is_opaque(declaration const & d, extra_opaque_pred const & pred, optional<module_idx> const & mod_idx) {
|
||||||
lean_assert(d.is_definition());
|
lean_assert(d.is_definition());
|
||||||
if (d.is_theorem()) return true; // theorems are always opaque
|
if (d.is_theorem()) return true; // theorems are always opaque
|
||||||
if (extra_opaque.contains(d.get_name())) return true; // extra_opaque set overrides opaque flag
|
if (pred(d.get_name())) return true; // extra_opaque predicate overrides opaque flag
|
||||||
if (!d.is_opaque()) return false; // d is a transparent definition
|
if (!d.is_opaque()) return false; // d is a transparent definition
|
||||||
if (mod_idx && d.get_module_idx() == *mod_idx) return false; // the opaque definitions in mod_idx are considered transparent
|
if (mod_idx && d.get_module_idx() == *mod_idx) return false; // the opaque definitions in mod_idx are considered transparent
|
||||||
return true; // d is opaque
|
return true; // d is opaque
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extra_opaque_pred g_always_false([](name const &) { return false; });
|
||||||
|
extra_opaque_pred const & no_extra_opaque() {
|
||||||
|
return g_always_false;
|
||||||
|
}
|
||||||
|
|
||||||
/** \brief Auxiliary method for \c is_delta */
|
/** \brief Auxiliary method for \c is_delta */
|
||||||
static optional<declaration> is_delta_core(environment const & env, expr const & e, name_set const & extra_opaque,
|
static optional<declaration> is_delta_core(environment const & env, expr const & e, extra_opaque_pred const & pred,
|
||||||
optional<module_idx> const & mod_idx) {
|
optional<module_idx> const & mod_idx) {
|
||||||
if (is_constant(e)) {
|
if (is_constant(e)) {
|
||||||
if (auto d = env.find(const_name(e)))
|
if (auto d = env.find(const_name(e)))
|
||||||
if (d->is_definition() && !is_opaque(*d, extra_opaque, mod_idx))
|
if (d->is_definition() && !is_opaque(*d, pred, mod_idx))
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
return none_declaration();
|
return none_declaration();
|
||||||
|
@ -57,15 +62,21 @@ static optional<declaration> is_delta_core(environment const & env, expr const &
|
||||||
\brief Return some definition \c d iff \c e is a target for delta-reduction, and the given definition is the one
|
\brief Return some definition \c d iff \c e is a target for delta-reduction, and the given definition is the one
|
||||||
to be expanded.
|
to be expanded.
|
||||||
*/
|
*/
|
||||||
optional<declaration> is_delta(environment const & env, expr const & e, name_set const & extra_opaque, optional<module_idx> const & mod_idx) {
|
optional<declaration> is_delta(environment const & env, expr const & e,
|
||||||
return is_delta_core(env, get_app_fn(e), extra_opaque, mod_idx);
|
extra_opaque_pred const & pred, optional<module_idx> const & mod_idx) {
|
||||||
|
return is_delta_core(env, get_app_fn(e), pred, mod_idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
static optional<module_idx> g_opt_main_module_idx(g_main_module_idx);
|
static optional<module_idx> g_opt_main_module_idx(g_main_module_idx);
|
||||||
optional<declaration> is_delta(environment const & env, expr const & e, name_set const & extra_opaque) {
|
optional<declaration> is_delta(environment const & env, expr const & e, extra_opaque_pred const & pred) {
|
||||||
return is_delta(env, e, extra_opaque, g_opt_main_module_idx);
|
return is_delta(env, e, pred, g_opt_main_module_idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
optional<declaration> is_delta(environment const & env, expr const & e) {
|
||||||
|
return is_delta(env, e, g_always_false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static no_delayed_justification g_no_delayed_jst;
|
static no_delayed_justification g_no_delayed_jst;
|
||||||
pair<bool, constraint_seq> converter::is_def_eq(expr const & t, expr const & s, type_checker & c) {
|
pair<bool, constraint_seq> converter::is_def_eq(expr const & t, expr const & s, type_checker & c) {
|
||||||
return is_def_eq(t, s, c, g_no_delayed_jst);
|
return is_def_eq(t, s, c, g_no_delayed_jst);
|
||||||
|
@ -95,12 +106,13 @@ struct default_converter : public converter {
|
||||||
environment m_env;
|
environment m_env;
|
||||||
optional<module_idx> m_module_idx;
|
optional<module_idx> m_module_idx;
|
||||||
bool m_memoize;
|
bool m_memoize;
|
||||||
name_set m_extra_opaque;
|
extra_opaque_pred m_extra_pred;
|
||||||
expr_struct_map<expr> m_whnf_core_cache;
|
expr_struct_map<expr> m_whnf_core_cache;
|
||||||
expr_struct_map<pair<expr, constraint_seq>> m_whnf_cache;
|
expr_struct_map<pair<expr, constraint_seq>> m_whnf_cache;
|
||||||
|
|
||||||
default_converter(environment const & env, optional<module_idx> mod_idx, bool memoize, name_set const & extra_opaque):
|
default_converter(environment const & env, optional<module_idx> mod_idx, bool memoize,
|
||||||
m_env(env), m_module_idx(mod_idx), m_memoize(memoize), m_extra_opaque(extra_opaque) {
|
extra_opaque_pred const & pred):
|
||||||
|
m_env(env), m_module_idx(mod_idx), m_memoize(memoize), m_extra_pred(pred) {
|
||||||
}
|
}
|
||||||
|
|
||||||
constraint mk_eq_cnstr(expr const & lhs, expr const & rhs, justification const & j) {
|
constraint mk_eq_cnstr(expr const & lhs, expr const & rhs, justification const & j) {
|
||||||
|
@ -211,7 +223,7 @@ struct default_converter : public converter {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_opaque(declaration const & d) const {
|
bool is_opaque(declaration const & d) const {
|
||||||
return ::lean::is_opaque(d, m_extra_opaque, m_module_idx);
|
return ::lean::is_opaque(d, m_extra_pred, m_module_idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \brief Expand \c e if it is non-opaque constant with weight >= w */
|
/** \brief Expand \c e if it is non-opaque constant with weight >= w */
|
||||||
|
@ -252,7 +264,7 @@ struct default_converter : public converter {
|
||||||
to be expanded.
|
to be expanded.
|
||||||
*/
|
*/
|
||||||
optional<declaration> is_delta(expr const & e) {
|
optional<declaration> is_delta(expr const & e) {
|
||||||
return ::lean::is_delta(m_env, get_app_fn(e), m_extra_opaque, m_module_idx);
|
return ::lean::is_delta(m_env, get_app_fn(e), m_extra_pred, m_module_idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -632,14 +644,21 @@ struct default_converter : public converter {
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unique_ptr<converter> mk_default_converter(environment const & env, optional<module_idx> mod_idx,
|
std::unique_ptr<converter> mk_default_converter(environment const & env, optional<module_idx> mod_idx,
|
||||||
bool memoize, name_set const & extra_opaque) {
|
bool memoize, extra_opaque_pred const & pred) {
|
||||||
return std::unique_ptr<converter>(new default_converter(env, mod_idx, memoize, extra_opaque));
|
return std::unique_ptr<converter>(new default_converter(env, mod_idx, memoize, pred));
|
||||||
|
}
|
||||||
|
std::unique_ptr<converter> mk_default_converter(environment const & env, optional<module_idx> mod_idx,
|
||||||
|
bool memoize) {
|
||||||
|
return mk_default_converter(env, mod_idx, memoize, g_always_false);
|
||||||
}
|
}
|
||||||
std::unique_ptr<converter> mk_default_converter(environment const & env, bool unfold_opaque_main, bool memoize,
|
std::unique_ptr<converter> mk_default_converter(environment const & env, bool unfold_opaque_main, bool memoize,
|
||||||
name_set const & extra_opaque) {
|
extra_opaque_pred const & pred) {
|
||||||
if (unfold_opaque_main)
|
if (unfold_opaque_main)
|
||||||
return mk_default_converter(env, optional<module_idx>(0), memoize, extra_opaque);
|
return mk_default_converter(env, optional<module_idx>(0), memoize, pred);
|
||||||
else
|
else
|
||||||
return mk_default_converter(env, optional<module_idx>(), memoize, extra_opaque);
|
return mk_default_converter(env, optional<module_idx>(), memoize, pred);
|
||||||
|
}
|
||||||
|
std::unique_ptr<converter> mk_default_converter(environment const & env, bool unfold_opaque_main, bool memoize) {
|
||||||
|
return mk_default_converter(env, unfold_opaque_main, memoize, g_always_false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
||||||
Author: Leonardo de Moura
|
Author: Leonardo de Moura
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include <functional>
|
||||||
#include "kernel/environment.h"
|
#include "kernel/environment.h"
|
||||||
|
|
||||||
namespace lean {
|
namespace lean {
|
||||||
|
@ -24,13 +25,17 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unique_ptr<converter> mk_dummy_converter();
|
std::unique_ptr<converter> mk_dummy_converter();
|
||||||
std::unique_ptr<converter> mk_default_converter(environment const & env,
|
std::unique_ptr<converter> mk_default_converter(environment const & env, optional<module_idx> mod_idx = optional<module_idx>(),
|
||||||
optional<module_idx> mod_idx = optional<module_idx>(),
|
bool memoize = true);
|
||||||
bool memoize = true, name_set const & extra_opaque = name_set());
|
std::unique_ptr<converter> mk_default_converter(environment const & env, optional<module_idx> mod_idx,
|
||||||
|
bool memoize, extra_opaque_pred const & pred);
|
||||||
std::unique_ptr<converter> mk_default_converter(environment const & env, bool unfold_opaque_main,
|
std::unique_ptr<converter> mk_default_converter(environment const & env, bool unfold_opaque_main,
|
||||||
bool memoize = true, name_set const & extra_opaque = name_set());
|
bool memoize = true);
|
||||||
|
std::unique_ptr<converter> mk_default_converter(environment const & env, bool unfold_opaque_main,
|
||||||
|
bool memoize, extra_opaque_pred const & pred);
|
||||||
|
|
||||||
bool is_opaque(declaration const & d, name_set const & extra_opaque, optional<module_idx> const & mod_idx);
|
bool is_opaque(declaration const & d, extra_opaque_pred const & pred, optional<module_idx> const & mod_idx);
|
||||||
optional<declaration> is_delta(environment const & env, expr const & e, name_set const & extra_opaque, optional<module_idx> const & mod_idx);
|
optional<declaration> is_delta(environment const & env, expr const & e, extra_opaque_pred const & pred, optional<module_idx> const & mod_idx);
|
||||||
optional<declaration> is_delta(environment const & env, expr const & e, name_set const & extra_opaque = name_set());
|
optional<declaration> is_delta(environment const & env, expr const & e, extra_opaque_pred const & pred);
|
||||||
|
optional<declaration> is_delta(environment const & env, expr const & e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,9 @@ class type_checker;
|
||||||
class environment;
|
class environment;
|
||||||
class certified_declaration;
|
class certified_declaration;
|
||||||
|
|
||||||
|
typedef std::function<bool(name const &)> extra_opaque_pred;
|
||||||
|
extra_opaque_pred const & no_extra_opaque();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief The header of an environment is created when we create the empty environment.
|
\brief The header of an environment is created when we create the empty environment.
|
||||||
Moreover if environment B is an extension of environment A, then A and B share the same header.
|
Moreover if environment B is an extension of environment A, then A and B share the same header.
|
||||||
|
@ -223,7 +226,8 @@ class name_generator;
|
||||||
Only the type_checker class can create certified declarations.
|
Only the type_checker class can create certified declarations.
|
||||||
*/
|
*/
|
||||||
class certified_declaration {
|
class certified_declaration {
|
||||||
friend certified_declaration check(environment const & env, declaration const & d, name_generator const & g, name_set const & extra_opaque, bool memoize);
|
friend certified_declaration check(environment const & env, declaration const & d,
|
||||||
|
name_generator const & g, extra_opaque_pred const & extra_opaque);
|
||||||
environment_id m_id;
|
environment_id m_id;
|
||||||
declaration m_declaration;
|
declaration m_declaration;
|
||||||
certified_declaration(environment_id const & id, declaration const & d):m_id(id), m_declaration(d) {}
|
certified_declaration(environment_id const & id, declaration const & d):m_id(id), m_declaration(d) {}
|
||||||
|
|
|
@ -453,20 +453,22 @@ static void check_duplicated_params(environment const & env, declaration const &
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
certified_declaration check(environment const & env, declaration const & d, name_generator const & g, name_set const & extra_opaque, bool memoize) {
|
certified_declaration check(environment const & env, declaration const & d, name_generator const & g,
|
||||||
|
extra_opaque_pred const & pred) {
|
||||||
if (d.is_definition())
|
if (d.is_definition())
|
||||||
check_no_mlocal(env, d.get_name(), d.get_value(), false);
|
check_no_mlocal(env, d.get_name(), d.get_value(), false);
|
||||||
check_no_mlocal(env, d.get_name(), d.get_type(), true);
|
check_no_mlocal(env, d.get_name(), d.get_type(), true);
|
||||||
check_name(env, d.get_name());
|
check_name(env, d.get_name());
|
||||||
check_duplicated_params(env, d);
|
check_duplicated_params(env, d);
|
||||||
type_checker checker1(env, g, mk_default_converter(env, optional<module_idx>(), memoize, extra_opaque));
|
bool memoize = true;
|
||||||
|
type_checker checker1(env, g, mk_default_converter(env, optional<module_idx>(), memoize, pred));
|
||||||
expr sort = checker1.check(d.get_type(), d.get_univ_params()).first;
|
expr sort = checker1.check(d.get_type(), d.get_univ_params()).first;
|
||||||
checker1.ensure_sort(sort, d.get_type());
|
checker1.ensure_sort(sort, d.get_type());
|
||||||
if (d.is_definition()) {
|
if (d.is_definition()) {
|
||||||
optional<module_idx> midx;
|
optional<module_idx> midx;
|
||||||
if (d.is_opaque())
|
if (d.is_opaque())
|
||||||
midx = optional<module_idx>(d.get_module_idx());
|
midx = optional<module_idx>(d.get_module_idx());
|
||||||
type_checker checker2(env, g, mk_default_converter(env, midx, memoize, extra_opaque));
|
type_checker checker2(env, g, mk_default_converter(env, midx, memoize, pred));
|
||||||
expr val_type = checker2.check(d.get_value(), d.get_univ_params()).first;
|
expr val_type = checker2.check(d.get_value(), d.get_univ_params()).first;
|
||||||
if (!checker2.is_def_eq(val_type, d.get_type()).first) {
|
if (!checker2.is_def_eq(val_type, d.get_type()).first) {
|
||||||
throw_kernel_exception(env, d.get_value(), [=](formatter const & fmt) {
|
throw_kernel_exception(env, d.get_value(), [=](formatter const & fmt) {
|
||||||
|
@ -477,7 +479,15 @@ certified_declaration check(environment const & env, declaration const & d, name
|
||||||
return certified_declaration(env.get_id(), d);
|
return certified_declaration(env.get_id(), d);
|
||||||
}
|
}
|
||||||
|
|
||||||
certified_declaration check(environment const & env, declaration const & d, name_set const & extra_opaque, bool memoize) {
|
certified_declaration check(environment const & env, declaration const & d, name_generator const & g) {
|
||||||
return check(env, d, name_generator(g_tmp_prefix), extra_opaque, memoize);
|
return check(env, d, g, no_extra_opaque());
|
||||||
|
}
|
||||||
|
|
||||||
|
certified_declaration check(environment const & env, declaration const & d, extra_opaque_pred const & pred) {
|
||||||
|
return check(env, d, name_generator(g_tmp_prefix), pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
certified_declaration check(environment const & env, declaration const & d) {
|
||||||
|
return check(env, d, no_extra_opaque());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -209,9 +209,11 @@ void check_no_metavar(environment const & env, name const & n, expr const & e, b
|
||||||
\brief Type check the given declaration, and return a certified declaration if it is type correct.
|
\brief Type check the given declaration, and return a certified declaration if it is type correct.
|
||||||
Throw an exception if the declaration is type incorrect.
|
Throw an exception if the declaration is type incorrect.
|
||||||
*/
|
*/
|
||||||
certified_declaration check(environment const & env, declaration const & d,
|
certified_declaration check(environment const & env, declaration const & d, name_generator const & g,
|
||||||
name_generator const & g, name_set const & extra_opaque = name_set(), bool memoize = true);
|
extra_opaque_pred const & pred);
|
||||||
certified_declaration check(environment const & env, declaration const & d, name_set const & extra_opaque = name_set(), bool memoize = true);
|
certified_declaration check(environment const & env, declaration const & d, name_generator const & g);
|
||||||
|
certified_declaration check(environment const & env, declaration const & d, extra_opaque_pred const & pred);
|
||||||
|
certified_declaration check(environment const & env, declaration const & d);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief Create a justification for an application \c e where the expected type must be \c d_type and
|
\brief Create a justification for an application \c e where the expected type must be \c d_type and
|
||||||
|
|
|
@ -1842,9 +1842,10 @@ static int mk_type_checker(lua_State * L) {
|
||||||
return push_type_checker_ref(L, std::make_shared<type_checker>(to_environment(L, 1), to_name_generator(L, 2)));
|
return push_type_checker_ref(L, std::make_shared<type_checker>(to_environment(L, 1), to_name_generator(L, 2)));
|
||||||
} else {
|
} else {
|
||||||
optional<module_idx> mod_idx; bool memoize; name_set extra_opaque;
|
optional<module_idx> mod_idx; bool memoize; name_set extra_opaque;
|
||||||
|
extra_opaque_pred pred([=](name const & n) { return extra_opaque.contains(n); });
|
||||||
get_type_checker_args(L, 3, mod_idx, memoize, extra_opaque);
|
get_type_checker_args(L, 3, mod_idx, memoize, extra_opaque);
|
||||||
auto t = std::make_shared<type_checker>(to_environment(L, 1), to_name_generator(L, 2),
|
auto t = std::make_shared<type_checker>(to_environment(L, 1), to_name_generator(L, 2),
|
||||||
mk_default_converter(to_environment(L, 1), mod_idx, memoize, extra_opaque),
|
mk_default_converter(to_environment(L, 1), mod_idx, memoize, pred),
|
||||||
memoize);
|
memoize);
|
||||||
return push_type_checker_ref(L, t);
|
return push_type_checker_ref(L, t);
|
||||||
}
|
}
|
||||||
|
@ -1905,28 +1906,29 @@ static const struct luaL_Reg type_checker_ref_m[] = {
|
||||||
// type_check procedure
|
// type_check procedure
|
||||||
static int type_check(lua_State * L) {
|
static int type_check(lua_State * L) {
|
||||||
int nargs = lua_gettop(L);
|
int nargs = lua_gettop(L);
|
||||||
if (nargs == 2)
|
if (nargs == 2) {
|
||||||
return push_certified_declaration(L, check(to_environment(L, 1), to_declaration(L, 2)));
|
return push_certified_declaration(L, check(to_environment(L, 1), to_declaration(L, 2)));
|
||||||
else if (nargs == 3)
|
} else if (nargs == 3) {
|
||||||
return push_certified_declaration(L, check(to_environment(L, 1), to_declaration(L, 2), to_name_generator(L, 3)));
|
return push_certified_declaration(L, check(to_environment(L, 1), to_declaration(L, 2), to_name_generator(L, 3)));
|
||||||
else if (nargs == 4)
|
} else {
|
||||||
return push_certified_declaration(L, check(to_environment(L, 1), to_declaration(L, 2), to_name_generator(L, 3), to_name_set(L, 4)));
|
name_set extra_opaque = to_name_set(L, 4);
|
||||||
else
|
extra_opaque_pred pred([=](name const & n) { return extra_opaque.contains(n); });
|
||||||
return push_certified_declaration(L, check(to_environment(L, 1), to_declaration(L, 2), to_name_generator(L, 3), to_name_set(L, 4),
|
return push_certified_declaration(L, check(to_environment(L, 1), to_declaration(L, 2), to_name_generator(L, 3), pred));
|
||||||
lua_toboolean(L, 5)));
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int add_declaration(lua_State * L) {
|
static int add_declaration(lua_State * L) {
|
||||||
int nargs = lua_gettop(L);
|
int nargs = lua_gettop(L);
|
||||||
optional<certified_declaration> d;
|
optional<certified_declaration> d;
|
||||||
if (nargs == 2)
|
if (nargs == 2) {
|
||||||
d = check(to_environment(L, 1), to_declaration(L, 2));
|
d = check(to_environment(L, 1), to_declaration(L, 2));
|
||||||
else if (nargs == 3)
|
} else if (nargs == 3) {
|
||||||
d = check(to_environment(L, 1), to_declaration(L, 2), to_name_generator(L, 3));
|
d = check(to_environment(L, 1), to_declaration(L, 2), to_name_generator(L, 3));
|
||||||
else if (nargs == 4)
|
} else {
|
||||||
d = check(to_environment(L, 1), to_declaration(L, 2), to_name_generator(L, 3), to_name_set(L, 4));
|
name_set extra_opaque = to_name_set(L, 4);
|
||||||
else
|
extra_opaque_pred pred([=](name const & n) { return extra_opaque.contains(n); });
|
||||||
d = check(to_environment(L, 1), to_declaration(L, 2), to_name_generator(L, 3), to_name_set(L, 4), lua_toboolean(L, 5));
|
d = check(to_environment(L, 1), to_declaration(L, 2), to_name_generator(L, 3), pred);
|
||||||
|
}
|
||||||
return push_environment(L, module::add(to_environment(L, 1), *d));
|
return push_environment(L, module::add(to_environment(L, 1), *d));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -56,8 +56,10 @@ bool get_hide_main_opaque(environment const & env) {
|
||||||
std::unique_ptr<type_checker> mk_type_checker_with_hints(environment const & env, name_generator const & ngen,
|
std::unique_ptr<type_checker> mk_type_checker_with_hints(environment const & env, name_generator const & ngen,
|
||||||
bool relax_main_opaque) {
|
bool relax_main_opaque) {
|
||||||
auto const & ext = get_extension(env);
|
auto const & ext = get_extension(env);
|
||||||
|
name_set extra_opaque = ext.m_extra_opaque;
|
||||||
|
extra_opaque_pred pred([=](name const & n) { return extra_opaque.contains(n); });
|
||||||
return std::unique_ptr<type_checker>(new type_checker(env, ngen, mk_default_converter(env,
|
return std::unique_ptr<type_checker>(new type_checker(env, ngen, mk_default_converter(env,
|
||||||
!ext.m_hide_module && relax_main_opaque,
|
!ext.m_hide_module && relax_main_opaque,
|
||||||
true, ext.m_extra_opaque)));
|
true, pred)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,9 +106,6 @@ static void tst2() {
|
||||||
lean_assert(checker.is_def_eq(f98(c1, id(Prop, id(Prop, c2))), f97(f97(c1, id(Prop, c2)), f97(c2, c1))).first);
|
lean_assert(checker.is_def_eq(f98(c1, id(Prop, id(Prop, c2))), f97(f97(c1, id(Prop, c2)), f97(c2, c1))).first);
|
||||||
name_set s;
|
name_set s;
|
||||||
s.insert(name(base, 96));
|
s.insert(name(base, 96));
|
||||||
type_checker checker2(env, name_generator("tmp"), mk_default_converter(env, optional<module_idx>(), true, s));
|
|
||||||
lean_assert_eq(checker2.whnf(f98(c1, c2)).first,
|
|
||||||
f96(f96(f97(c1, c2), f97(c2, c1)), f96(f97(c2, c1), f97(c1, c2))));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class normalizer_extension_tst : public normalizer_extension {
|
class normalizer_extension_tst : public normalizer_extension {
|
||||||
|
|
Loading…
Reference in a new issue