This flag was used by the kernel to decide whether the following
heuristic should be used to avoid unfolding `f` at `is_def_eq`.
f a =?= f b
-----------
a =?= b
This heuristic was introduced at Lean1 after a discussion with
Georges Gontier. Since this discussion, we added support for
caching failures of this heuristic. This proved to be much more
effective to attack the performance problems.
Moreover, we do not even use this flag in the `type_context::is_def_eq`
used during elaboration.
The current codebase contains only one place where this flag was set to
`false`: coercions generated at structure_cmd. This change was
made at commit
1c70514231
in the Lean2 codebase when we were not caching failures and
the kernel type checker was also used during elaboration.
142 lines
5.8 KiB
C++
142 lines
5.8 KiB
C++
/*
|
|
Copyright (c) 2014 Microsoft Corporation. All rights reserved.
|
|
Released under Apache 2.0 license as described in the file LICENSE.
|
|
|
|
Author: Leonardo de Moura
|
|
*/
|
|
#include "kernel/declaration.h"
|
|
#include "kernel/environment.h"
|
|
#include "kernel/for_each_fn.h"
|
|
|
|
namespace lean {
|
|
int compare(reducibility_hints const & h1, reducibility_hints const & h2) {
|
|
if (h1.m_kind == h2.m_kind) {
|
|
if (h1.m_kind == reducibility_hints::Regular) {
|
|
if (h1.m_height == h2.m_height)
|
|
return 0; /* unfold both */
|
|
else if (h1.m_height > h2.m_height)
|
|
return -1; /* unfold f1 */
|
|
else
|
|
return 1; /* unfold f2 */
|
|
return h1.m_height > h2.m_height ? -1 : 1;
|
|
} else {
|
|
return 0; /* reduce both */
|
|
}
|
|
} else {
|
|
if (h1.m_kind == reducibility_hints::Opaque) {
|
|
return 1; /* reduce f2 */
|
|
} else if (h2.m_kind == reducibility_hints::Opaque) {
|
|
return -1; /* reduce f1 */
|
|
} else if (h1.m_kind == reducibility_hints::Abbreviation) {
|
|
return -1; /* reduce f1 */
|
|
} else if (h2.m_kind == reducibility_hints::Abbreviation) {
|
|
return 1; /* reduce f2 */
|
|
} else {
|
|
lean_unreachable();
|
|
}
|
|
}
|
|
}
|
|
|
|
static declaration * g_dummy = nullptr;
|
|
|
|
declaration::declaration():declaration(*g_dummy) {}
|
|
declaration::declaration(cell * ptr):m_ptr(ptr) {}
|
|
declaration::declaration(declaration const & s):m_ptr(s.m_ptr) { if (m_ptr) m_ptr->inc_ref(); }
|
|
declaration::declaration(declaration && s):m_ptr(s.m_ptr) { s.m_ptr = nullptr; }
|
|
declaration::~declaration() { if (m_ptr) m_ptr->dec_ref(); }
|
|
|
|
declaration & declaration::operator=(declaration const & s) { LEAN_COPY_REF(s); }
|
|
declaration & declaration::operator=(declaration && s) { LEAN_MOVE_REF(s); }
|
|
|
|
bool declaration::is_definition() const { return static_cast<bool>(m_ptr->m_value); }
|
|
bool declaration::is_constant_assumption() const { return !is_definition(); }
|
|
bool declaration::is_axiom() const { return is_constant_assumption() && m_ptr->m_theorem; }
|
|
bool declaration::is_theorem() const { return is_definition() && m_ptr->m_theorem; }
|
|
bool declaration::is_meta() const { return m_ptr->m_meta; }
|
|
|
|
name const & declaration::get_name() const { return m_ptr->m_name; }
|
|
level_param_names const & declaration::get_univ_params() const { return m_ptr->m_params; }
|
|
unsigned declaration::get_num_univ_params() const { return length(get_univ_params()); }
|
|
expr const & declaration::get_type() const { return m_ptr->m_type; }
|
|
|
|
expr const & declaration::get_value() const {
|
|
lean_assert(is_definition());
|
|
return *(m_ptr->m_value);
|
|
}
|
|
reducibility_hints const & declaration::get_hints() const { return m_ptr->m_hints; }
|
|
|
|
declaration mk_definition(name const & n, level_param_names const & params, expr const & t, expr const & v,
|
|
reducibility_hints const & h, bool meta) {
|
|
return declaration(new declaration::cell(n, params, t, v, h, meta));
|
|
}
|
|
static unsigned get_max_height(environment const & env, expr const & v) {
|
|
unsigned h = 0;
|
|
for_each(v, [&](expr const & e, unsigned) {
|
|
if (is_constant(e)) {
|
|
auto d = env.find(const_name(e));
|
|
if (d && d->get_hints().get_height() > h)
|
|
h = d->get_hints().get_height();
|
|
}
|
|
return true;
|
|
});
|
|
return h;
|
|
}
|
|
|
|
declaration mk_definition(environment const & env, name const & n, level_param_names const & params, expr const & t,
|
|
expr const & v, bool meta) {
|
|
unsigned h = get_max_height(env, v);
|
|
return mk_definition(n, params, t, v, reducibility_hints::mk_regular(h+1), meta);
|
|
}
|
|
declaration mk_theorem(name const & n, level_param_names const & params, expr const & t, expr const & v) {
|
|
return declaration(new declaration::cell(n, params, t, v));
|
|
}
|
|
declaration mk_axiom(name const & n, level_param_names const & params, expr const & t) {
|
|
return declaration(new declaration::cell(n, params, t, true, false));
|
|
}
|
|
declaration mk_constant_assumption(name const & n, level_param_names const & params, expr const & t, bool meta) {
|
|
return declaration(new declaration::cell(n, params, t, false, meta));
|
|
}
|
|
|
|
bool use_meta(environment const & env, expr const & e) {
|
|
bool found = false;
|
|
for_each(e, [&](expr const & e, unsigned) {
|
|
if (found) return false;
|
|
if (is_constant(e)) {
|
|
if (auto d = env.find(const_name(e))) {
|
|
if (d->is_meta()) {
|
|
found = true;
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
});
|
|
return found;
|
|
}
|
|
|
|
declaration mk_definition_inferring_meta(environment const & env, name const & n, level_param_names const & params,
|
|
expr const & t, expr const & v, reducibility_hints const & hints) {
|
|
bool meta = use_meta(env, t) || use_meta(env, v);
|
|
return mk_definition(n, params, t, v, hints, meta);
|
|
}
|
|
|
|
declaration mk_definition_inferring_meta(environment const & env, name const & n, level_param_names const & params,
|
|
expr const & t, expr const & v) {
|
|
bool meta = use_meta(env, t) && use_meta(env, v);
|
|
unsigned h = get_max_height(env, v);
|
|
return mk_definition(n, params, t, v, reducibility_hints::mk_regular(h+1), meta);
|
|
}
|
|
|
|
declaration mk_constant_assumption_inferring_meta(environment const & env, name const & n,
|
|
level_param_names const & params, expr const & t) {
|
|
return mk_constant_assumption(n, params, t, use_meta(env, t));
|
|
}
|
|
|
|
void initialize_declaration() {
|
|
g_dummy = new declaration(mk_axiom(name(), level_param_names(), expr()));
|
|
}
|
|
|
|
void finalize_declaration() {
|
|
delete g_dummy;
|
|
}
|
|
}
|