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) {
|
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);
|
return replace_fn(f)(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue