feat(library/blast): basic sanity checking for blast data-structures
This commit is contained in:
parent
465a939146
commit
48e8b8b866
6 changed files with 78 additions and 9 deletions
|
@ -195,6 +195,7 @@ class context {
|
||||||
expr new_target = to_blast_expr(g.get_type());
|
expr new_target = to_blast_expr(g.get_type());
|
||||||
s.set_target(new_target);
|
s.set_target(new_target);
|
||||||
init_mvar2mref(mvar2meta_mref);
|
init_mvar2mref(mvar2meta_mref);
|
||||||
|
lean_assert(s.check_invariant());
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -99,6 +99,14 @@ expr branch::add_hypothesis(expr const & type, optional<expr> const & value, opt
|
||||||
return add_hypothesis(name(*g_prefix, m_next), type, value, jst);
|
return add_hypothesis(name(*g_prefix, m_next), type, value, jst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool branch::hidx_depends_on(unsigned hidx_user, unsigned hidx_provider) const {
|
||||||
|
if (auto s = m_forward_deps.find(hidx_provider)) {
|
||||||
|
return s->contains(hidx_user);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void branch::set_target(expr const & t) {
|
void branch::set_target(expr const & t) {
|
||||||
m_target = t;
|
m_target = t;
|
||||||
m_target_deps.clear();
|
m_target_deps.clear();
|
||||||
|
|
|
@ -40,21 +40,29 @@ class branch {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
branch():m_next(0) {}
|
branch():m_next(0) {}
|
||||||
/** \brief Store in \c r the hypotheses in this branch sorted by depth */
|
|
||||||
void get_sorted_hypotheses(hypothesis_idx_buffer & r) const;
|
|
||||||
|
|
||||||
expr add_hypothesis(name const & n, expr const & type, optional<expr> const & value, optional<expr> const & jst);
|
expr add_hypothesis(name const & n, expr const & type, optional<expr> const & value, optional<expr> const & jst);
|
||||||
expr add_hypothesis(expr const & type, optional<expr> const & value, optional<expr> const & jst);
|
expr add_hypothesis(expr const & type, optional<expr> const & value, optional<expr> const & jst);
|
||||||
|
|
||||||
void set_target(expr const & t);
|
/** \brief Return true iff the hypothesis with index \c hidx_user depends on the hypothesis with index
|
||||||
|
\c hidx_provider. */
|
||||||
|
bool hidx_depends_on(unsigned hidx_user, unsigned hidx_provider) const;
|
||||||
|
|
||||||
hypothesis const * get(unsigned idx) const { return m_context.find(idx); }
|
hypothesis const * get(unsigned hidx) const { return m_context.find(hidx); }
|
||||||
hypothesis const * get(expr const & e) const {
|
hypothesis const * get(expr const & h) const {
|
||||||
lean_assert(is_lref(e));
|
lean_assert(is_lref(h));
|
||||||
return get(lref_index(e));
|
return get(lref_index(h));
|
||||||
}
|
}
|
||||||
|
void for_each_hypothesis(std::function<void(unsigned, hypothesis const &)> const & fn) const { m_context.for_each(fn); }
|
||||||
|
/** \brief Store in \c r the hypotheses in this branch sorted by depth */
|
||||||
|
void get_sorted_hypotheses(hypothesis_idx_buffer & r) const;
|
||||||
|
|
||||||
|
void set_target(expr const & t);
|
||||||
expr const & get_target() const { return m_target; }
|
expr const & get_target() const { return m_target; }
|
||||||
|
/** \brief Return true iff the target depends on the given hypothesis */
|
||||||
|
bool target_depends_on(expr const & h) const { return m_target_deps.contains(lref_index(h)); }
|
||||||
|
|
||||||
|
bool has_mvar(expr const & e) const { return m_mvar_idxs.contains(mref_index(e)); }
|
||||||
};
|
};
|
||||||
|
|
||||||
void initialize_branch();
|
void initialize_branch();
|
||||||
|
|
|
@ -7,7 +7,7 @@ Author: Leonardo de Moura
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "util/rc.h"
|
#include "util/rc.h"
|
||||||
#include "util/rb_map.h"
|
#include "util/rb_map.h"
|
||||||
#include "kernel/expr.h"
|
#include "library/blast/expr.h"
|
||||||
|
|
||||||
namespace lean {
|
namespace lean {
|
||||||
namespace blast {
|
namespace blast {
|
||||||
|
@ -41,5 +41,7 @@ public:
|
||||||
optional<expr> const & get_value() const { return m_value; }
|
optional<expr> const & get_value() const { return m_value; }
|
||||||
optional<expr> const & get_justification() const { return m_justification; }
|
optional<expr> const & get_justification() const { return m_justification; }
|
||||||
void mark_fixed() { m_fixed = true; }
|
void mark_fixed() { m_fixed = true; }
|
||||||
|
/** \brief Return true iff this hypothesis depends on \c h. */
|
||||||
|
bool depends_on(expr const & h) const { return m_deps.contains(lref_index(h)); }
|
||||||
};
|
};
|
||||||
}}
|
}}
|
||||||
|
|
|
@ -93,4 +93,46 @@ goal state::to_goal(branch const & b) const {
|
||||||
goal state::to_goal() const {
|
goal state::to_goal() const {
|
||||||
return to_goal(m_main);
|
return to_goal(m_main);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef LEAN_DEBUG
|
||||||
|
bool state::check_deps(expr const & e, branch const & b, unsigned hidx, hypothesis const & h) const {
|
||||||
|
for_each(e, [&](expr const & n, unsigned) {
|
||||||
|
if (is_lref(n)) {
|
||||||
|
lean_assert(h.depends_on(n));
|
||||||
|
lean_assert(b.hidx_depends_on(hidx, lref_index(n)));
|
||||||
|
} else if (is_mref(n)) {
|
||||||
|
// metavariable is in the set of used metavariables
|
||||||
|
lean_assert(b.has_mvar(n));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool state::check_deps(branch const & b, unsigned hidx, hypothesis const & h) const {
|
||||||
|
lean_assert(check_deps(h.get_type(), b, hidx, h));
|
||||||
|
lean_assert(!h.get_value() || check_deps(*h.get_value(), b, hidx, h));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool state::check_invariant(branch const & b) const {
|
||||||
|
b.for_each_hypothesis([&](unsigned hidx, hypothesis const & h) {
|
||||||
|
lean_assert(check_deps(b, hidx, h));
|
||||||
|
});
|
||||||
|
for_each(b.get_target(), [&](expr const & n, unsigned) {
|
||||||
|
if (is_lref(n)) {
|
||||||
|
lean_assert(b.target_depends_on(n));
|
||||||
|
} else if (is_mref(n)) {
|
||||||
|
// metavariable is in the set of used metavariables
|
||||||
|
lean_assert(b.has_mvar(n));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool state::check_invariant() const {
|
||||||
|
return check_invariant(m_main);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}}
|
}}
|
||||||
|
|
|
@ -37,6 +37,11 @@ class state {
|
||||||
unsigned add_metavar_decl(metavar_decl const & decl);
|
unsigned add_metavar_decl(metavar_decl const & decl);
|
||||||
goal to_goal(branch const &) const;
|
goal to_goal(branch const &) const;
|
||||||
|
|
||||||
|
#ifdef LEAN_DEBUG
|
||||||
|
bool check_deps(expr const & e, branch const & b, unsigned hidx, hypothesis const & h) const;
|
||||||
|
bool check_deps(branch const & b, unsigned hidx, hypothesis const & h) const;
|
||||||
|
bool check_invariant(branch const &) const;
|
||||||
|
#endif
|
||||||
public:
|
public:
|
||||||
state();
|
state();
|
||||||
/** \brief Create a new metavariable using the given type and context.
|
/** \brief Create a new metavariable using the given type and context.
|
||||||
|
@ -63,12 +68,15 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
metavar_decl const * get_metavar_decl(unsigned idx) const { return m_metavar_decls.find(idx); }
|
metavar_decl const * get_metavar_decl(unsigned idx) const { return m_metavar_decls.find(idx); }
|
||||||
|
|
||||||
metavar_decl const * get_metavar_decl(expr const & e) const { return get_metavar_decl(mref_index(e)); }
|
metavar_decl const * get_metavar_decl(expr const & e) const { return get_metavar_decl(mref_index(e)); }
|
||||||
|
|
||||||
/** \brief Convert main branch to a goal.
|
/** \brief Convert main branch to a goal.
|
||||||
This is mainly used for pretty printing. However, in the future, we may use this capability
|
This is mainly used for pretty printing. However, in the future, we may use this capability
|
||||||
to invoke the tactic framework from the blast tactic. */
|
to invoke the tactic framework from the blast tactic. */
|
||||||
goal to_goal() const;
|
goal to_goal() const;
|
||||||
|
|
||||||
|
#ifdef LEAN_DEBUG
|
||||||
|
bool check_invariant() const;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
}}
|
}}
|
||||||
|
|
Loading…
Add table
Reference in a new issue