feat(library/fun_info_manager): update interface
This commit is contained in:
parent
12571c92d8
commit
a992bb46a6
3 changed files with 66 additions and 14 deletions
|
@ -348,7 +348,7 @@ public:
|
|||
if (r != m_simp_cache.end())
|
||||
return optional<result>(r->second);
|
||||
fun_info finfo = m_fmanager.get(fn, nargs);
|
||||
list<unsigned> const & result_deps = finfo.get_dependencies();
|
||||
list<unsigned> const & result_deps = finfo.get_result_dependencies();
|
||||
buffer<congr_arg_kind> kinds;
|
||||
buffer<param_info> pinfos;
|
||||
to_buffer(finfo.get_params_info(), pinfos);
|
||||
|
|
|
@ -33,7 +33,7 @@ list<unsigned> fun_info_manager::collect_deps(expr const & type, buffer<expr> co
|
|||
return to_list(deps);
|
||||
}
|
||||
|
||||
auto fun_info_manager::get(expr const & e) -> fun_info {
|
||||
fun_info fun_info_manager::get(expr const & e) {
|
||||
if (auto r = m_fun_info.find(e))
|
||||
return *r;
|
||||
expr type = m_ctx.relaxed_try_to_pi(m_ctx.infer(e));
|
||||
|
@ -43,6 +43,7 @@ auto fun_info_manager::get(expr const & e) -> fun_info {
|
|||
expr local = m_ctx.mk_tmp_local_from_binding(type);
|
||||
expr local_type = m_ctx.infer(local);
|
||||
expr new_type = m_ctx.relaxed_try_to_pi(instantiate(binding_body(type), local));
|
||||
bool spec = false;
|
||||
bool is_prop = m_ctx.is_prop(local_type);
|
||||
bool is_sub = is_prop;
|
||||
bool is_dep = !closed(binding_body(type));
|
||||
|
@ -50,7 +51,8 @@ auto fun_info_manager::get(expr const & e) -> fun_info {
|
|||
// TODO(Leo): check if the following line is a performance bottleneck.
|
||||
is_sub = static_cast<bool>(m_ctx.mk_subsingleton_instance(local_type));
|
||||
}
|
||||
info.emplace_back(binding_info(type).is_implicit(),
|
||||
info.emplace_back(spec,
|
||||
binding_info(type).is_implicit(),
|
||||
binding_info(type).is_inst_implicit(),
|
||||
is_prop, is_sub, is_dep, collect_deps(local_type, locals));
|
||||
locals.push_back(local);
|
||||
|
@ -61,7 +63,7 @@ auto fun_info_manager::get(expr const & e) -> fun_info {
|
|||
return r;
|
||||
}
|
||||
|
||||
auto fun_info_manager::get(expr const & e, unsigned nargs) -> fun_info {
|
||||
fun_info fun_info_manager::get(expr const & e, unsigned nargs) {
|
||||
auto r = get(e);
|
||||
lean_assert(nargs <= r.get_arity());
|
||||
if (nargs == r.get_arity()) {
|
||||
|
@ -70,7 +72,7 @@ auto fun_info_manager::get(expr const & e, unsigned nargs) -> fun_info {
|
|||
buffer<param_info> pinfos;
|
||||
to_buffer(r.get_params_info(), pinfos);
|
||||
buffer<unsigned> rdeps;
|
||||
to_buffer(r.get_dependencies(), rdeps);
|
||||
to_buffer(r.get_result_dependencies(), rdeps);
|
||||
for (unsigned i = nargs; i < pinfos.size(); i++) {
|
||||
for (auto d : pinfos[i].get_dependencies()) {
|
||||
if (std::find(rdeps.begin(), rdeps.end(), d) == rdeps.end())
|
||||
|
@ -82,6 +84,11 @@ auto fun_info_manager::get(expr const & e, unsigned nargs) -> fun_info {
|
|||
}
|
||||
}
|
||||
|
||||
fun_info fun_info_manager::get_specialization(expr const &) {
|
||||
// TODO(Leo)
|
||||
lean_unreachable();
|
||||
}
|
||||
|
||||
struct replace_fn : public replace_visitor {
|
||||
fun_info_manager & m_infom;
|
||||
type_context & m_ctx;
|
||||
|
|
|
@ -9,7 +9,30 @@ Author: Leonardo de Moura
|
|||
#include "library/type_context.h"
|
||||
|
||||
namespace lean {
|
||||
/** \brief Function parameter information. It is used by \c fun_info_manager. */
|
||||
class param_info {
|
||||
/* m_specialized is true if the result of fun_info has been specifialized
|
||||
using this argument.
|
||||
For example, consider the function
|
||||
|
||||
f : Pi (A : Type), A -> A
|
||||
|
||||
Now, suppse we request get_specialize fun_info for the application
|
||||
|
||||
f unit a
|
||||
|
||||
fun_info_manager returns two param_info objects:
|
||||
1) m_specialized = true, m_is_dep = true
|
||||
2) m_subsingleton = true, m_deps = {0}
|
||||
|
||||
Note that, in general, the second argument of f is not a subsingleton,
|
||||
but it is in this particular case/specialization.
|
||||
|
||||
\remark This bit is only set if it is a dependent parameter (i.e., m_is_dep is true).
|
||||
|
||||
Moreover, we only set m_specialized IF another parameter
|
||||
becomes a subsingleton or proposition. */
|
||||
unsigned m_specialized:1;
|
||||
unsigned m_implicit:1;
|
||||
unsigned m_inst_implicit:1;
|
||||
unsigned m_prop:1;
|
||||
|
@ -17,30 +40,36 @@ class param_info {
|
|||
unsigned m_is_dep:1; // true if rest depends on this parameter
|
||||
list<unsigned> m_deps; // previous arguments it depends on
|
||||
public:
|
||||
param_info(bool imp, bool inst_imp, bool prop, bool sub, bool is_dep, list<unsigned> const & deps):
|
||||
m_implicit(imp), m_inst_implicit(inst_imp), m_prop(prop), m_subsingleton(sub),
|
||||
param_info(bool spec, bool imp, bool inst_imp, bool prop, bool sub, bool is_dep, list<unsigned> const & deps):
|
||||
m_specialized(spec), m_implicit(imp), m_inst_implicit(inst_imp), m_prop(prop), m_subsingleton(sub),
|
||||
m_is_dep(is_dep), m_deps(deps) {}
|
||||
list<unsigned> const & get_dependencies() const { return m_deps; }
|
||||
bool is_prop() const { return m_prop; }
|
||||
bool specialized() const { return m_specialized; }
|
||||
bool is_implicit() const { return m_implicit; }
|
||||
bool is_inst_implicit() const { return m_inst_implicit; }
|
||||
bool is_prop() const { return m_prop; }
|
||||
bool is_subsingleton() const { return m_subsingleton; }
|
||||
bool is_dep() const { return m_is_dep; }
|
||||
};
|
||||
|
||||
/** \brief Function information produced by \c fun_info_manager */
|
||||
class fun_info {
|
||||
unsigned m_arity;
|
||||
list<param_info> m_params_info;
|
||||
list<unsigned> m_deps;
|
||||
list<unsigned> m_deps; // resulting type dependencies
|
||||
public:
|
||||
fun_info():m_arity(0) {}
|
||||
fun_info(unsigned arity, list<param_info> const & info, list<unsigned> const & deps):
|
||||
m_arity(arity), m_params_info(info), m_deps(deps) {}
|
||||
unsigned get_arity() const { return m_arity; }
|
||||
list<param_info> const & get_params_info() const { return m_params_info; }
|
||||
list<unsigned> const & get_dependencies() const { return m_deps; }
|
||||
list<unsigned> const & get_result_dependencies() const { return m_deps; }
|
||||
};
|
||||
|
||||
/** \brief Helper object for retrieving a summary for the parameters
|
||||
of a given function or function application.
|
||||
We use the summary for quickly detecting which arguments are subsingletons and propositions,
|
||||
dependencies, implicit binder info, etc. */
|
||||
class fun_info_manager {
|
||||
type_context & m_ctx;
|
||||
rb_map<expr, fun_info, expr_quick_cmp> m_fun_info;
|
||||
|
@ -48,12 +77,28 @@ class fun_info_manager {
|
|||
public:
|
||||
fun_info_manager(type_context & ctx);
|
||||
type_context & ctx() { return m_ctx; }
|
||||
fun_info get(expr const & e);
|
||||
fun_info get(expr const & fn);
|
||||
/** \brief Return information assuming the function has only nargs.
|
||||
\pre nargs <= get(e).get_arity() */
|
||||
fun_info get(expr const & e, unsigned nargs);
|
||||
};
|
||||
\pre nargs <= get(fn).get_arity() */
|
||||
fun_info get(expr const & fn, unsigned nargs);
|
||||
/** \brief Return information for the function application.
|
||||
This is more precise than \c get methods for dependent functions.
|
||||
|
||||
Example: given (f : Pi (A : Type), A -> A), \c get_specialization for
|
||||
|
||||
f unit b
|
||||
|
||||
returns a \c fun_info with two param_info
|
||||
1) m_specialized = true, m_is_dep = true
|
||||
2) m_subsingleton = true, m_deps = {0}
|
||||
|
||||
The second argument is marked as subsingleton only because the resulting information
|
||||
is taking into account the first argument.
|
||||
|
||||
\remark \c get and \c get_specialization return the same result for all but
|
||||
is_prop and is_subsingleton. */
|
||||
fun_info get_specialization(expr const & app);
|
||||
};
|
||||
|
||||
/** \brief Given a term \c e of the form F[ts[0], ..., ts[n-1]],
|
||||
return F[rs[0], ..., rs[n-1]] only if the replacement does not produce type errors.
|
||||
|
|
Loading…
Reference in a new issue