refactor(kernel/normalizer): normalizer only needs read access to metavariable environment

Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
Leonardo de Moura 2014-01-27 17:03:30 -08:00
parent 3b152d1a9e
commit 05b4d8411b
5 changed files with 42 additions and 27 deletions

View file

@ -428,9 +428,10 @@ metavar_env::metavar_env(ro_metavar_env const & s):m_ptr(s.m_ptr) {
if (m_ptr) m_ptr->inc_ref(); if (m_ptr) m_ptr->inc_ref();
} }
bool cached_metavar_env::update(optional<metavar_env> const & menv) { template<typename MEnv>
bool cached_metavar_env_tpl<MEnv>::update(optional<MEnv> const & menv) {
if (!menv) { if (!menv) {
m_menv = none_menv(); m_menv = optional<MEnv>();
if (m_timestamp != 0) { if (m_timestamp != 0) {
m_timestamp = 0; m_timestamp = 0;
return true; return true;
@ -448,6 +449,8 @@ bool cached_metavar_env::update(optional<metavar_env> const & menv) {
} }
} }
} }
template class cached_metavar_env_tpl<metavar_env>;
template class cached_metavar_env_tpl<ro_metavar_env>;
local_context add_lift(local_context const & lctx, unsigned s, unsigned n) { local_context add_lift(local_context const & lctx, unsigned s, unsigned n) {
if (n == 0) if (n == 0)

View file

@ -221,6 +221,7 @@ public:
metavar_env copy() const { return metavar_env(new metavar_env_cell(*m_ptr)); } metavar_env copy() const { return metavar_env(new metavar_env_cell(*m_ptr)); }
friend bool is_eqp(metavar_env const & menv1, metavar_env const & menv2) { return menv1.m_ptr == menv2.m_ptr; } friend bool is_eqp(metavar_env const & menv1, metavar_env const & menv2) { return menv1.m_ptr == menv2.m_ptr; }
friend bool operator==(metavar_env const & menv1, metavar_env const & menv2) { return is_eqp(menv1, menv2); } friend bool operator==(metavar_env const & menv1, metavar_env const & menv2) { return is_eqp(menv1, menv2); }
typedef metavar_env_cell * ptr;
}; };
SPECIALIZE_OPTIONAL_FOR_SMART_PTR(metavar_env) SPECIALIZE_OPTIONAL_FOR_SMART_PTR(metavar_env)
@ -263,6 +264,7 @@ public:
metavar_env copy() const { return metavar_env(new metavar_env_cell(*m_ptr)); } metavar_env copy() const { return metavar_env(new metavar_env_cell(*m_ptr)); }
friend bool is_eqp(ro_metavar_env const & menv1, ro_metavar_env const & menv2) { return menv1.m_ptr == menv2.m_ptr; } friend bool is_eqp(ro_metavar_env const & menv1, ro_metavar_env const & menv2) { return menv1.m_ptr == menv2.m_ptr; }
friend bool operator==(ro_metavar_env const & menv1, ro_metavar_env const & menv2) { return is_eqp(menv1, menv2); } friend bool operator==(ro_metavar_env const & menv1, ro_metavar_env const & menv2) { return is_eqp(menv1, menv2); }
typedef metavar_env_cell const * ptr;
}; };
SPECIALIZE_OPTIONAL_FOR_SMART_PTR(ro_metavar_env) SPECIALIZE_OPTIONAL_FOR_SMART_PTR(ro_metavar_env)
@ -272,29 +274,39 @@ inline optional<ro_metavar_env> some_ro_menv(ro_metavar_env && e) { return optio
inline optional<ro_metavar_env> const & to_ro_menv(optional<metavar_env> const & menv) { return reinterpret_cast<optional<ro_metavar_env> const &>(menv); } inline optional<ro_metavar_env> const & to_ro_menv(optional<metavar_env> const & menv) { return reinterpret_cast<optional<ro_metavar_env> const &>(menv); }
/** /**
\brief A cached weak reference to a metavariable environment + timestamp at the time of \brief Template for creating a cached reference to a metavariable
the caching. This object may also cache optional references. environment + timestamp at the time of the caching. This object may
also cache optional references.
We use this template for cached_metavar_env and cached_ro_metavar_env
*/ */
class cached_metavar_env { template<typename MEnv>
optional<metavar_env> m_menv; class cached_metavar_env_tpl {
unsigned m_timestamp; optional<MEnv> m_menv;
unsigned m_timestamp;
public: public:
cached_metavar_env():m_timestamp(0) {} cached_metavar_env_tpl():m_timestamp(0) {}
void clear() { m_menv = none_menv(); m_timestamp = 0; } void clear() { m_menv = optional<MEnv>(); m_timestamp = 0; }
/** /**
\brief Updated the cached value with menv. \brief Updated the cached value with menv.
Return true if menv is different from the the cached metavar_env, or if Return true if menv is different from the the cached metavar_env, or if
the timestamp is different. the timestamp is different.
*/ */
bool update(optional<metavar_env> const & menv); bool update(optional<MEnv> const & menv);
bool update(metavar_env const & menv) { return update(some(menv)); } bool update(MEnv const & menv) { return update(optional<MEnv>(menv)); }
explicit operator bool() const { return static_cast<bool>(m_menv); } explicit operator bool() const { return static_cast<bool>(m_menv); }
optional<metavar_env> const & to_some_menv() const { return m_menv; } optional<MEnv> const & to_some_menv() const { return m_menv; }
optional<ro_metavar_env> const & to_some_ro_menv() const { return to_ro_menv(m_menv); } MEnv operator*() const { return *m_menv; }
metavar_env operator*() const { return *m_menv; } typename MEnv::ptr operator->() const { lean_assert(m_menv); return (*m_menv).operator->(); }
metavar_env_cell * operator->() const { lean_assert(m_menv); return (*m_menv).operator->(); }
}; };
class cached_metavar_env : public cached_metavar_env_tpl<metavar_env> {
public:
optional<ro_metavar_env> const & to_some_ro_menv() const { return to_ro_menv(to_some_menv()); }
};
typedef cached_metavar_env_tpl<ro_metavar_env> cached_ro_metavar_env;
/** /**
\brief Apply the changes in \c lctx to \c a. \brief Apply the changes in \c lctx to \c a.
*/ */

View file

@ -78,7 +78,7 @@ class normalizer::imp {
ro_environment::weak_ref m_env; ro_environment::weak_ref m_env;
context m_ctx; context m_ctx;
cached_metavar_env m_menv; cached_ro_metavar_env m_menv;
cache m_cache; cache m_cache;
bool m_unfold_opaque; bool m_unfold_opaque;
unsigned m_max_depth; unsigned m_max_depth;
@ -87,11 +87,11 @@ class normalizer::imp {
ro_environment env() const { return ro_environment(m_env); } ro_environment env() const { return ro_environment(m_env); }
expr instantiate(expr const & e, unsigned n, expr const * s) { expr instantiate(expr const & e, unsigned n, expr const * s) {
return ::lean::instantiate(e, n, s, m_menv.to_some_ro_menv()); return ::lean::instantiate(e, n, s, m_menv.to_some_menv());
} }
expr add_lift(expr const & m, unsigned s, unsigned n) { expr add_lift(expr const & m, unsigned s, unsigned n) {
return ::lean::add_lift(m, s, n, m_menv.to_some_ro_menv()); return ::lean::add_lift(m, s, n, m_menv.to_some_menv());
} }
expr lookup(value_stack const & s, unsigned i) { expr lookup(value_stack const & s, unsigned i) {
@ -338,7 +338,7 @@ public:
m_unfold_opaque = false; m_unfold_opaque = false;
} }
expr operator()(expr const & e, context const & ctx, optional<metavar_env> const & menv, bool unfold_opaque) { expr operator()(expr const & e, context const & ctx, optional<ro_metavar_env> const & menv, bool unfold_opaque) {
if (m_unfold_opaque != unfold_opaque) if (m_unfold_opaque != unfold_opaque)
m_cache.clear(); m_cache.clear();
m_unfold_opaque = unfold_opaque; m_unfold_opaque = unfold_opaque;
@ -356,14 +356,14 @@ normalizer::normalizer(ro_environment const & env, unsigned max_depth):m_ptr(new
normalizer::normalizer(ro_environment const & env):normalizer(env, std::numeric_limits<unsigned>::max()) {} normalizer::normalizer(ro_environment const & env):normalizer(env, std::numeric_limits<unsigned>::max()) {}
normalizer::normalizer(ro_environment const & env, options const & opts):normalizer(env, get_normalizer_max_depth(opts)) {} normalizer::normalizer(ro_environment const & env, options const & opts):normalizer(env, get_normalizer_max_depth(opts)) {}
normalizer::~normalizer() {} normalizer::~normalizer() {}
expr normalizer::operator()(expr const & e, context const & ctx, optional<metavar_env> const & menv, bool unfold_opaque) { expr normalizer::operator()(expr const & e, context const & ctx, optional<ro_metavar_env> const & menv, bool unfold_opaque) {
return (*m_ptr)(e, ctx, menv, unfold_opaque); return (*m_ptr)(e, ctx, menv, unfold_opaque);
} }
expr normalizer::operator()(expr const & e, context const & ctx, metavar_env const & menv, bool unfold_opaque) { expr normalizer::operator()(expr const & e, context const & ctx, ro_metavar_env const & menv, bool unfold_opaque) {
return operator()(e, ctx, some_menv(menv), unfold_opaque); return operator()(e, ctx, some_ro_menv(menv), unfold_opaque);
} }
expr normalizer::operator()(expr const & e, context const & ctx, bool unfold_opaque) { expr normalizer::operator()(expr const & e, context const & ctx, bool unfold_opaque) {
return operator()(e, ctx, none_menv(), unfold_opaque); return operator()(e, ctx, none_ro_menv(), unfold_opaque);
} }
void normalizer::clear() { m_ptr->clear(); } void normalizer::clear() { m_ptr->clear(); }

View file

@ -13,7 +13,7 @@ Author: Leonardo de Moura
namespace lean { namespace lean {
class environment; class environment;
class options; class options;
class metavar_env; class ro_metavar_env;
/** \brief Functional object for normalizing expressions */ /** \brief Functional object for normalizing expressions */
class normalizer { class normalizer {
class imp; class imp;
@ -24,8 +24,8 @@ public:
normalizer(ro_environment const & env, options const & opts); normalizer(ro_environment const & env, options const & opts);
~normalizer(); ~normalizer();
expr operator()(expr const & e, context const & ctx, optional<metavar_env> const & menv, bool unfold_opaque = false); expr operator()(expr const & e, context const & ctx, optional<ro_metavar_env> const & menv, bool unfold_opaque = false);
expr operator()(expr const & e, context const & ctx, metavar_env const & menv, bool unfold_opaque = false); expr operator()(expr const & e, context const & ctx, ro_metavar_env const & menv, bool unfold_opaque = false);
expr operator()(expr const & e, context const & ctx = context(), bool unfold_opaque = false); expr operator()(expr const & e, context const & ctx = context(), bool unfold_opaque = false);
void clear(); void clear();

View file

@ -48,7 +48,7 @@ class type_checker::imp {
expr lower_free_vars(expr const & e, unsigned s, unsigned n) { return ::lean::lower_free_vars(e, s, n, m_menv.to_some_ro_menv()); } expr lower_free_vars(expr const & e, unsigned s, unsigned n) { return ::lean::lower_free_vars(e, s, n, m_menv.to_some_ro_menv()); }
expr instantiate_with_closed(expr const & e, expr const & v) { return ::lean::instantiate_with_closed(e, v, m_menv.to_some_ro_menv()); } expr instantiate_with_closed(expr const & e, expr const & v) { return ::lean::instantiate_with_closed(e, v, m_menv.to_some_ro_menv()); }
expr instantiate(expr const & e, expr const & v) { return ::lean::instantiate(e, v, m_menv.to_some_ro_menv()); } expr instantiate(expr const & e, expr const & v) { return ::lean::instantiate(e, v, m_menv.to_some_ro_menv()); }
expr normalize(expr const & e, context const & ctx, bool unfold_opaque) { return m_normalizer(e, ctx, m_menv.to_some_menv(), unfold_opaque); } expr normalize(expr const & e, context const & ctx, bool unfold_opaque) { return m_normalizer(e, ctx, m_menv.to_some_ro_menv(), unfold_opaque); }
expr check_type(expr const & e, expr const & s, context const & ctx) { expr check_type(expr const & e, expr const & s, context const & ctx) {
if (is_type(e) || is_bool(e)) if (is_type(e) || is_bool(e))