feat(frontends/lean/find_cmd): add options for controlling find_decl
This commit is contained in:
parent
f1e915a188
commit
d81a6259e8
4 changed files with 53 additions and 5 deletions
|
@ -5,6 +5,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
|||
Author: Leonardo de Moura
|
||||
*/
|
||||
#include <string>
|
||||
#include "util/sexpr/option_declarations.h"
|
||||
#include "kernel/instantiate.h"
|
||||
#include "library/unifier.h"
|
||||
#include "library/type_util.h"
|
||||
|
@ -13,8 +14,43 @@ Author: Leonardo de Moura
|
|||
#include "frontends/lean/util.h"
|
||||
#include "frontends/lean/tokens.h"
|
||||
|
||||
#ifndef LEAN_DEFAULT_FIND_MAX_STEPS
|
||||
#define LEAN_DEFAULT_FIND_MAX_STEPS 128
|
||||
#endif
|
||||
|
||||
#ifndef LEAN_DEFAULT_FIND_EXPENSIVE
|
||||
#define LEAN_DEFAULT_FIND_EXPENSIVE false
|
||||
#endif
|
||||
|
||||
|
||||
namespace lean {
|
||||
bool match_pattern(type_checker & tc, expr const & pattern, declaration const & d) {
|
||||
static name * g_find_max_steps = nullptr;
|
||||
static name * g_find_expensive = nullptr;
|
||||
|
||||
void initialize_find_cmd() {
|
||||
g_find_max_steps = new name{"find_decl", "max_steps"};
|
||||
g_find_expensive = new name{"find_decl", "expensive"};
|
||||
register_unsigned_option(*g_find_max_steps, LEAN_DEFAULT_FIND_MAX_STEPS,
|
||||
"(find_decl) maximum number of steps to be performed when trying to match the type of a declaration");
|
||||
register_bool_option(*g_find_expensive, LEAN_DEFAULT_FIND_EXPENSIVE,
|
||||
"(find_decl) if true, then matcher will unfold definitions, perform reductions, and higher-order matching");
|
||||
}
|
||||
|
||||
void finalize_find_cmd() {
|
||||
delete g_find_max_steps;
|
||||
delete g_find_expensive;
|
||||
}
|
||||
|
||||
unsigned get_find_max_steps(options const & opts) {
|
||||
return opts.get_unsigned(*g_find_max_steps, LEAN_DEFAULT_FIND_MAX_STEPS);
|
||||
}
|
||||
|
||||
bool get_find_expensive(options const & opts) {
|
||||
return opts.get_bool(*g_find_expensive, LEAN_DEFAULT_FIND_EXPENSIVE);
|
||||
}
|
||||
|
||||
|
||||
bool match_pattern(type_checker & tc, expr const & pattern, declaration const & d, unsigned max_steps, bool cheap) {
|
||||
name_generator ngen = tc.mk_ngen();
|
||||
buffer<level> ls;
|
||||
unsigned num_ls = length(d.get_univ_params());
|
||||
|
@ -33,8 +69,8 @@ bool match_pattern(type_checker & tc, expr const & pattern, declaration const &
|
|||
}
|
||||
try {
|
||||
unifier_config cfg;
|
||||
cfg.m_max_steps = 128;
|
||||
cfg.m_cheap = true;
|
||||
cfg.m_max_steps = max_steps;
|
||||
cfg.m_cheap = cheap;
|
||||
cfg.m_ignore_context_check = true;
|
||||
auto r = unify(tc.env(), pattern, dt, tc.mk_ngen(), true, substitution(), cfg);
|
||||
return static_cast<bool>(r.pull());
|
||||
|
@ -67,13 +103,16 @@ environment find_cmd(parser & p) {
|
|||
environment env = p.env();
|
||||
auto tc = mk_opaque_type_checker(env, p.mk_ngen());
|
||||
p.regular_stream() << "find_decl result:\n";
|
||||
|
||||
unsigned max_steps = get_find_max_steps(p.get_options());
|
||||
bool cheap = !get_find_expensive(p.get_options());
|
||||
bool found = false;
|
||||
env.for_each_declaration([&](declaration const & d) {
|
||||
if (std::all_of(pos_names.begin(), pos_names.end(),
|
||||
[&](std::string const & pos) { return is_part_of(pos, d.get_name()); }) &&
|
||||
std::all_of(neg_names.begin(), neg_names.end(),
|
||||
[&](std::string const & neg) { return !is_part_of(neg, d.get_name()); }) &&
|
||||
match_pattern(*tc.get(), e, d)) {
|
||||
match_pattern(*tc.get(), e, d, max_steps, cheap)) {
|
||||
found = true;
|
||||
p.regular_stream() << " " << get_decl_short_name(d.get_name(), env) << " : " << d.get_type() << endl;
|
||||
}
|
||||
|
|
|
@ -9,4 +9,6 @@ Author: Leonardo de Moura
|
|||
namespace lean {
|
||||
class parser;
|
||||
environment find_cmd(parser & p);
|
||||
void initialize_find_cmd();
|
||||
void finalize_find_cmd();
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ Author: Leonardo de Moura
|
|||
#include "frontends/lean/info_tactic.h"
|
||||
#include "frontends/lean/placeholder_elaborator.h"
|
||||
#include "frontends/lean/calc_proof_elaborator.h"
|
||||
#include "frontends/lean/find_cmd.h"
|
||||
#include "frontends/lean/scanner.h"
|
||||
#include "frontends/lean/pp.h"
|
||||
#include "frontends/lean/server.h"
|
||||
|
@ -55,8 +56,10 @@ void initialize_frontend_lean_module() {
|
|||
initialize_placeholder_elaborator();
|
||||
initialize_calc_proof_elaborator();
|
||||
initialize_server();
|
||||
initialize_find_cmd();
|
||||
}
|
||||
void finalize_frontend_lean_module() {
|
||||
finalize_find_cmd();
|
||||
finalize_server();
|
||||
finalize_calc_proof_elaborator();
|
||||
finalize_placeholder_elaborator();
|
||||
|
|
|
@ -9,4 +9,8 @@ find_decl _ = succ _
|
|||
|
||||
find_decl _ < succ _, +pos
|
||||
|
||||
find_decl _ < succ _, pos
|
||||
find_decl zero < succ _, pos
|
||||
|
||||
set_option find_decl.expensive true
|
||||
-- Now, nat.zero will match 0 (i.e., (of_num num.zero))
|
||||
find_decl zero < succ _, pos
|
||||
|
|
Loading…
Reference in a new issue