feat(kernel/for_each): allow function F to interrupt for_each search

Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
Leonardo de Moura 2013-10-25 14:58:02 -07:00
parent 2dd44bdf1a
commit 57d9d23bd4
5 changed files with 14 additions and 5 deletions

View file

@ -1113,6 +1113,7 @@ class pp_fn {
} else if (is_let(e)) { } else if (is_let(e)) {
if (is_prefix_of(prefix, let_name(e))) throw found_prefix(); if (is_prefix_of(prefix, let_name(e))) throw found_prefix();
} }
return true;
}; };
try { try {
for_each_fn<decltype(f)> visitor(f); for_each_fn<decltype(f)> visitor(f);

View file

@ -44,6 +44,7 @@ struct environment::imp {
if (obj) if (obj)
w = std::max(w, obj.get_weight()); w = std::max(w, obj.get_weight());
} }
return true;
}; };
for_each_fn<decltype(proc)> visitor(proc); for_each_fn<decltype(proc)> visitor(proc);
visitor(e); visitor(e);

View file

@ -22,8 +22,8 @@ template<typename F>
class for_each_fn { class for_each_fn {
std::unique_ptr<expr_cell_offset_set> m_visited; std::unique_ptr<expr_cell_offset_set> m_visited;
F m_f; F m_f;
static_assert(std::is_same<typename std::result_of<F(expr const &, unsigned)>::type, void>::value, static_assert(std::is_same<typename std::result_of<F(expr const &, unsigned)>::type, bool>::value,
"for_each_fn: return type of m_f is not void"); "for_each_fn: return type of m_f is not bool");
void apply(expr const & e, unsigned offset) { void apply(expr const & e, unsigned offset) {
if (is_shared(e)) { if (is_shared(e)) {
@ -35,7 +35,8 @@ class for_each_fn {
m_visited->insert(p); m_visited->insert(p);
} }
m_f(e, offset); if (!m_f(e, offset))
return;
switch (e.kind()) { switch (e.kind()) {
case expr_kind::Constant: case expr_kind::Type: case expr_kind::Value: case expr_kind::Constant: case expr_kind::Type: case expr_kind::Value:

View file

@ -262,8 +262,11 @@ bool has_assigned_metavar(expr const & e, substitution const & s) {
return false; return false;
} else { } else {
auto proc = [&](expr const & n, unsigned) { auto proc = [&](expr const & n, unsigned) {
if (!has_metavar(n))
return false;
if (is_metavar(n) && s.is_assigned(n)) if (is_metavar(n) && s.is_assigned(n))
throw found_assigned(); throw found_assigned();
return true;
}; };
for_each_fn<decltype(proc)> visitor(proc); for_each_fn<decltype(proc)> visitor(proc);
try { try {
@ -342,6 +345,7 @@ bool has_metavar(expr const & e, expr const & m, substitution const & s) {
has_metavar(s.get_subst(m2), m, s)) has_metavar(s.get_subst(m2), m, s))
throw found_metavar(); throw found_metavar();
} }
return true;
}; };
try { try {
for_each_fn<decltype(f)> proc(f); for_each_fn<decltype(f)> proc(f);

View file

@ -27,11 +27,12 @@ namespace occurs_ns {
struct found {}; struct found {};
} }
bool occurs(name const & n, context const * c, unsigned sz, expr const * es) { bool occurs(name const & n, context const * c, unsigned sz, expr const * es) {
auto visitor = [&](expr const & e, unsigned) -> void { auto visitor = [&](expr const & e, unsigned) -> bool {
if (is_constant(e)) { if (is_constant(e)) {
if (const_name(e) == n) if (const_name(e) == n)
throw occurs_ns::found(); throw occurs_ns::found();
} }
return true;
}; };
try { try {
for_each(visitor, c, sz, es); for_each(visitor, c, sz, es);
@ -42,9 +43,10 @@ bool occurs(name const & n, context const * c, unsigned sz, expr const * es) {
} }
bool occurs(expr const & n, context const * c, unsigned sz, expr const * es) { bool occurs(expr const & n, context const * c, unsigned sz, expr const * es) {
auto visitor = [&](expr const & e, unsigned) -> void { auto visitor = [&](expr const & e, unsigned) -> bool {
if (e == n) if (e == n)
throw occurs_ns::found(); throw occurs_ns::found();
return true;
}; };
try { try {
for_each(visitor, c, sz, es); for_each(visitor, c, sz, es);