feat(library/local_context): add well_formed debugging methods

This commit is contained in:
Leonardo de Moura 2016-03-05 13:09:36 -08:00
parent 4543dc4a7f
commit 66d583d279
2 changed files with 61 additions and 0 deletions

View file

@ -6,6 +6,7 @@ Author: Leonardo de Moura
*/
#include <limits>
#include "util/fresh_name.h"
#include "kernel/for_each_fn.h"
#include "library/local_context.h"
namespace lean {
@ -87,6 +88,52 @@ void local_context::for_each_after(local_decl const & d, std::function<void(loca
m_idx2local_decl.for_each_greater(d.get_idx(), [&](unsigned, local_decl const & d) { return fn(d); });
}
/* Return true iff all local_decl references in \c e are in \c s. */
static bool locals_subset_of(expr const & e, name_set const & s) {
bool ok = true;
for_each(e, [&](expr const & e, unsigned) {
if (!ok) return false; // stop search
if (is_local_decl_ref(e) && !s.contains(mlocal_name(e))) {
ok = false;
return false;
}
return true;
});
return ok;
}
bool local_context::well_formed() const {
bool ok = true;
name_set found_locals;
for_each([&](local_decl const & d) {
if (!locals_subset_of(d.get_type(), found_locals)) {
ok = false;
lean_unreachable();
}
if (auto v = d.get_value()) {
if (!locals_subset_of(*v, found_locals)) {
ok = false;
lean_unreachable();
}
}
found_locals.insert(d.get_name());
});
return ok;
}
bool local_context::well_formed(expr const & e) const {
bool ok = true;
::lean::for_each(e, [&](expr const & e, unsigned) {
if (!ok) return false;
if (is_local_decl_ref(e) && !get_local_decl(e)) {
ok = false;
lean_unreachable();
}
return true;
});
return ok;
}
void local_context::freeze(name const & n) {
lean_assert(m_name2local_decl.contains(n));
m_frozen_decls.insert(n);

View file

@ -95,9 +95,23 @@ public:
optional<local_decl> find_if(std::function<bool(local_decl const &)> const & pred) const; // NOLINT
/** \brief Execute fn for each local declaration created after \c d. */
void for_each_after(local_decl const & d, std::function<void(local_decl const &)> const & fn) const;
local_decls to_local_decls() const { return local_decls(m_name2local_decl); }
void freeze(name const & n);
bool is_frozen(name const & n) const { return m_frozen_decls.contains(n); }
/** \brief We say a local context is well-formed iff all local declarations only
contain local_decl references that were defined before them.
\remark This method is for debugging purposes. */
bool well_formed() const;
/** \brief Return true iff \c e is well-formed with respect to this local context.
That is, all local_decl references in \c e are defined in this context.
\remark This method is for debugging purposes. */
bool well_formed(expr const & e) const;
};
void initialize_local_context();