/* Copyright (c) 2013 Microsoft Corporation. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Author: Leonardo de Moura */ #pragma once #include #include "util/buffer.h" #include "util/interrupt.h" #include "kernel/expr.h" #include "kernel/expr_maps.h" namespace lean { /** \brief Default replace_fn postprocessor functional object. It is a do-nothing object. */ class default_replace_postprocessor { public: void operator()(expr const &, expr const &) {} }; /** \brief Functional for applying F to the subexpressions of a given expression. The signature of \c F is expr const &, unsigned -> optional(expr) F is invoked for each subexpression \c s of the input expression e. In a call F(s, n), n is the scope level, i.e., the number of bindings operators that enclosing \c s. The replaces only visits children of \c e if F return none_expr P is a "post-processing" functional object that is applied to each pair (old, new) */ class replace_fn { struct frame { expr m_expr; unsigned m_offset; bool m_shared; unsigned m_index; frame(expr const & e, unsigned o, bool s):m_expr(e), m_offset(o), m_shared(s), m_index(0) {} }; typedef buffer frame_stack; typedef buffer result_stack; expr_cell_offset_map m_cache; std::function(expr const &, unsigned)> m_f; std::function m_post; frame_stack m_fs; result_stack m_rs; void save_result(expr const & e, expr const & r, unsigned offset, bool shared); bool visit(expr const & e, unsigned offset); bool check_index(frame & f, unsigned idx); expr const & rs(int i); void pop_rs(unsigned num); public: template replace_fn(F const & f, P const & p = P()): m_f(f), m_post(p) {} expr operator()(expr const & e); void clear(); }; template expr replace(expr const & e, F const & f) { return replace_fn(f)(e); } template expr replace(expr const & e, F const & f, P const & p) { return replace_fn(f, p)(e); } }