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:
parent
2dd44bdf1a
commit
57d9d23bd4
5 changed files with 14 additions and 5 deletions
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue