perf(kernel/replace_fn): use 'recursive' replace_fn for "small" terms
This commit is contained in:
parent
c21c8c582f
commit
b6afbcb7f5
1 changed files with 59 additions and 1 deletions
|
@ -197,7 +197,65 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
class replace_rec_fn {
|
||||
replace_cache_ref m_cache;
|
||||
std::function<optional<expr>(expr const &, unsigned)> m_f;
|
||||
|
||||
expr save_result(expr const & e, unsigned offset, expr const & r, bool shared) {
|
||||
if (shared)
|
||||
m_cache->insert(e, offset, r);
|
||||
return r;
|
||||
}
|
||||
|
||||
expr apply(expr const & e, unsigned offset) {
|
||||
bool shared = false;
|
||||
if (is_shared(e)) {
|
||||
if (auto r = m_cache->find(e, offset))
|
||||
return *r;
|
||||
shared = true;
|
||||
}
|
||||
|
||||
if (optional<expr> r = m_f(e, offset)) {
|
||||
return save_result(e, offset, *r, shared);
|
||||
} else {
|
||||
switch (e.kind()) {
|
||||
case expr_kind::Constant: case expr_kind::Sort: case expr_kind::Var:
|
||||
return save_result(e, offset, e, shared);
|
||||
case expr_kind::Meta: case expr_kind::Local: {
|
||||
expr new_t = apply(mlocal_type(e), offset);
|
||||
return save_result(e, offset, update_mlocal(e, new_t), shared);
|
||||
}
|
||||
case expr_kind::App: {
|
||||
expr new_f = apply(app_fn(e), offset);
|
||||
expr new_a = apply(app_arg(e), offset);
|
||||
return save_result(e, offset, update_app(e, new_f, new_a), shared);
|
||||
}
|
||||
case expr_kind::Pi: case expr_kind::Lambda: {
|
||||
expr new_d = apply(binding_domain(e), offset);
|
||||
expr new_b = apply(binding_body(e), offset+1);
|
||||
return save_result(e, offset, update_binding(e, new_d, new_b), shared);
|
||||
}
|
||||
case expr_kind::Macro: {
|
||||
buffer<expr> new_args;
|
||||
unsigned nargs = macro_num_args(e);
|
||||
for (unsigned i = 0; i < nargs; i++)
|
||||
new_args.push_back(apply(macro_arg(e, i), offset));
|
||||
return save_result(e, offset, update_macro(e, new_args.size(), new_args.data()), shared);
|
||||
}}
|
||||
lean_unreachable();
|
||||
}
|
||||
}
|
||||
public:
|
||||
template<typename F>
|
||||
replace_rec_fn(F const & f):m_f(f) {}
|
||||
|
||||
expr operator()(expr const & e) { return apply(e, 0); }
|
||||
};
|
||||
|
||||
expr replace(expr const & e, std::function<optional<expr>(expr const &, unsigned)> const & f) {
|
||||
if (get_weight(e) < 10000)
|
||||
return replace_rec_fn(f)(e);
|
||||
else
|
||||
return replace_fn(f)(e);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue