feat(frontends/lean/placeholder_elaborator): add option 'elaborator.instance_max_depth'
This commit is contained in:
parent
9b9ae128d5
commit
1d9a0a6265
1 changed files with 27 additions and 0 deletions
|
@ -30,13 +30,19 @@ Author: Leonardo de Moura
|
||||||
#define LEAN_DEFAULT_ELABORATOR_TRACE_INSTANCES false
|
#define LEAN_DEFAULT_ELABORATOR_TRACE_INSTANCES false
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef LEAN_DEFAULT_ELABORATOR_INSTANCE_MAX_DEPTH
|
||||||
|
#define LEAN_DEFAULT_ELABORATOR_INSTANCE_MAX_DEPTH 32
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace lean {
|
namespace lean {
|
||||||
static name * g_elaborator_unique_class_instances = nullptr;
|
static name * g_elaborator_unique_class_instances = nullptr;
|
||||||
static name * g_elaborator_trace_instances = nullptr;
|
static name * g_elaborator_trace_instances = nullptr;
|
||||||
|
static name * g_elaborator_instance_max_depth = nullptr;
|
||||||
|
|
||||||
void initialize_placeholder_elaborator() {
|
void initialize_placeholder_elaborator() {
|
||||||
g_elaborator_unique_class_instances = new name{"elaborator", "unique_class_instances"};
|
g_elaborator_unique_class_instances = new name{"elaborator", "unique_class_instances"};
|
||||||
g_elaborator_trace_instances = new name{"elaborator", "trace_instances"};
|
g_elaborator_trace_instances = new name{"elaborator", "trace_instances"};
|
||||||
|
g_elaborator_instance_max_depth = new name{"elaborator", "instance_max_depth"};
|
||||||
|
|
||||||
register_bool_option(*g_elaborator_unique_class_instances, LEAN_DEFAULT_ELABORATOR_UNIQUE_CLASS_INSTANCES,
|
register_bool_option(*g_elaborator_unique_class_instances, LEAN_DEFAULT_ELABORATOR_UNIQUE_CLASS_INSTANCES,
|
||||||
"(elaborator) generate an error if there is more than one solution "
|
"(elaborator) generate an error if there is more than one solution "
|
||||||
|
@ -44,11 +50,15 @@ void initialize_placeholder_elaborator() {
|
||||||
|
|
||||||
register_bool_option(*g_elaborator_trace_instances, LEAN_DEFAULT_ELABORATOR_TRACE_INSTANCES,
|
register_bool_option(*g_elaborator_trace_instances, LEAN_DEFAULT_ELABORATOR_TRACE_INSTANCES,
|
||||||
"(elaborator) display messages showing the class-instances resolution execution trace");
|
"(elaborator) display messages showing the class-instances resolution execution trace");
|
||||||
|
|
||||||
|
register_unsigned_option(*g_elaborator_instance_max_depth, LEAN_DEFAULT_ELABORATOR_INSTANCE_MAX_DEPTH,
|
||||||
|
"(elaborator) max allowed depth in class-instance resolution");
|
||||||
}
|
}
|
||||||
|
|
||||||
void finalize_placeholder_elaborator() {
|
void finalize_placeholder_elaborator() {
|
||||||
delete g_elaborator_unique_class_instances;
|
delete g_elaborator_unique_class_instances;
|
||||||
delete g_elaborator_trace_instances;
|
delete g_elaborator_trace_instances;
|
||||||
|
delete g_elaborator_instance_max_depth;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool get_elaborator_unique_class_instances(options const & o) {
|
bool get_elaborator_unique_class_instances(options const & o) {
|
||||||
|
@ -59,14 +69,20 @@ bool get_elaborator_trace_instances(options const & o) {
|
||||||
return o.get_bool(*g_elaborator_trace_instances, LEAN_DEFAULT_ELABORATOR_TRACE_INSTANCES);
|
return o.get_bool(*g_elaborator_trace_instances, LEAN_DEFAULT_ELABORATOR_TRACE_INSTANCES);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned get_elaborator_instance_max_depth(options const & o) {
|
||||||
|
return o.get_unsigned(*g_elaborator_instance_max_depth, LEAN_DEFAULT_ELABORATOR_INSTANCE_MAX_DEPTH);
|
||||||
|
}
|
||||||
|
|
||||||
/** \brief Context for handling placeholder metavariable choice constraint */
|
/** \brief Context for handling placeholder metavariable choice constraint */
|
||||||
struct placeholder_context {
|
struct placeholder_context {
|
||||||
io_state m_ios;
|
io_state m_ios;
|
||||||
name_generator m_ngen;
|
name_generator m_ngen;
|
||||||
type_checker_ptr m_tc;
|
type_checker_ptr m_tc;
|
||||||
|
expr m_main_meta;
|
||||||
bool m_relax;
|
bool m_relax;
|
||||||
bool m_use_local_instances;
|
bool m_use_local_instances;
|
||||||
bool m_trace_instances;
|
bool m_trace_instances;
|
||||||
|
unsigned m_max_depth;
|
||||||
char const * m_fname;
|
char const * m_fname;
|
||||||
optional<pos_info> m_pos;
|
optional<pos_info> m_pos;
|
||||||
placeholder_context(environment const & env, io_state const & ios,
|
placeholder_context(environment const & env, io_state const & ios,
|
||||||
|
@ -78,6 +94,7 @@ struct placeholder_context {
|
||||||
m_use_local_instances(use_local_instances) {
|
m_use_local_instances(use_local_instances) {
|
||||||
m_fname = nullptr;
|
m_fname = nullptr;
|
||||||
m_trace_instances = get_elaborator_trace_instances(ios.get_options());
|
m_trace_instances = get_elaborator_trace_instances(ios.get_options());
|
||||||
|
m_max_depth = get_elaborator_instance_max_depth(ios.get_options());
|
||||||
options opts = m_ios.get_options();
|
options opts = m_ios.get_options();
|
||||||
opts = opts.update(get_pp_purify_metavars_name(), false);
|
opts = opts.update(get_pp_purify_metavars_name(), false);
|
||||||
opts = opts.update(get_pp_implicit_name(), true);
|
opts = opts.update(get_pp_implicit_name(), true);
|
||||||
|
@ -89,12 +106,15 @@ struct placeholder_context {
|
||||||
bool use_local_instances() const { return m_use_local_instances; }
|
bool use_local_instances() const { return m_use_local_instances; }
|
||||||
type_checker & tc() const { return *m_tc; }
|
type_checker & tc() const { return *m_tc; }
|
||||||
bool trace_instances() const { return m_trace_instances; }
|
bool trace_instances() const { return m_trace_instances; }
|
||||||
|
void set_main_meta(expr const & meta) { m_main_meta = meta; }
|
||||||
|
expr const & get_main_meta() const { return m_main_meta; }
|
||||||
void set_pos(char const * fname, optional<pos_info> const & pos) {
|
void set_pos(char const * fname, optional<pos_info> const & pos) {
|
||||||
m_fname = fname;
|
m_fname = fname;
|
||||||
m_pos = pos;
|
m_pos = pos;
|
||||||
}
|
}
|
||||||
optional<pos_info> const & get_pos() const { return m_pos; }
|
optional<pos_info> const & get_pos() const { return m_pos; }
|
||||||
char const * get_file_name() const { return m_fname; }
|
char const * get_file_name() const { return m_fname; }
|
||||||
|
unsigned get_max_depth() const { return m_max_depth; }
|
||||||
};
|
};
|
||||||
|
|
||||||
pair<expr, constraint> mk_placeholder_elaborator(std::shared_ptr<placeholder_context> const & C, local_context const & ctx,
|
pair<expr, constraint> mk_placeholder_elaborator(std::shared_ptr<placeholder_context> const & C, local_context const & ctx,
|
||||||
|
@ -132,6 +152,12 @@ struct placeholder_elaborator : public choice_iterator {
|
||||||
justification const & j, unsigned depth):
|
justification const & j, unsigned depth):
|
||||||
choice_iterator(), m_C(C), m_ctx(ctx), m_meta(meta), m_meta_type(meta_type),
|
choice_iterator(), m_C(C), m_ctx(ctx), m_meta(meta), m_meta_type(meta_type),
|
||||||
m_local_instances(local_insts), m_instances(instances), m_jst(j), m_depth(depth) {
|
m_local_instances(local_insts), m_instances(instances), m_jst(j), m_depth(depth) {
|
||||||
|
if (m_depth > m_C->get_max_depth()) {
|
||||||
|
throw_elaborator_exception(C->env(), "maximum class-instance resolution depth has been reached "
|
||||||
|
"(the limit can be increased by setting option 'elaborator.instance_max_depth') "
|
||||||
|
"(the class-instance resolution trace can be visualized by setting option 'elaborator.trace_instances')",
|
||||||
|
C->get_main_meta());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
constraints mk_constraints(constraint const & c, buffer<constraint> const & cs) {
|
constraints mk_constraints(constraint const & c, buffer<constraint> const & cs) {
|
||||||
|
@ -388,6 +414,7 @@ pair<expr, constraint> mk_placeholder_elaborator(
|
||||||
pos_info_provider const * pip) {
|
pos_info_provider const * pip) {
|
||||||
auto C = std::make_shared<placeholder_context>(env, ios, prefix, relax, use_local_instances);
|
auto C = std::make_shared<placeholder_context>(env, ios, prefix, relax, use_local_instances);
|
||||||
expr m = ctx.mk_meta(C->m_ngen, suffix, type, g);
|
expr m = ctx.mk_meta(C->m_ngen, suffix, type, g);
|
||||||
|
C->set_main_meta(m);
|
||||||
if (pip)
|
if (pip)
|
||||||
C->set_pos(pip->get_file_name(), pip->get_pos_info(m));
|
C->set_pos(pip->get_file_name(), pip->get_pos_info(m));
|
||||||
constraint c = mk_placeholder_root_cnstr(C, ctx, m, is_strict, cfg, delay_factor());
|
constraint c = mk_placeholder_root_cnstr(C, ctx, m, is_strict, cfg, delay_factor());
|
||||||
|
|
Loading…
Reference in a new issue