remove(frontends/lean/server): FINDG command
This commit is contained in:
parent
22f3efc5be
commit
d84a20d68b
5 changed files with 1 additions and 195 deletions
|
@ -354,32 +354,3 @@ The entries are of the form
|
||||||
|
|
||||||
The types are printed without using line breaks.
|
The types are printed without using line breaks.
|
||||||
The command =FINDP= is mainly used to implement auto-completion.
|
The command =FINDP= is mainly used to implement auto-completion.
|
||||||
|
|
||||||
** Find declarations for "placeholder/goal"
|
|
||||||
|
|
||||||
A declaration may contain placeholders/goals =_=. Some of these placeholders are instantiated automatically by Lean.
|
|
||||||
Others, must be manually filled by the user. The command =FINDG= generates a sequence of declarations that may be used to
|
|
||||||
"fill" a particular placeholder. This command is only available if the declaration containing =_= is type correct, and
|
|
||||||
lean "knows" what is the expected type for =_=.
|
|
||||||
|
|
||||||
#+BEGIN_SRC
|
|
||||||
FINDG [line-number] [column-number]
|
|
||||||
[filters]*
|
|
||||||
#+END_SRC
|
|
||||||
|
|
||||||
The character at the given =[line-number]= and =[column-number]= must be a =_=.
|
|
||||||
The command also accepts a sequence of filters of the form =+[id_1]= and =-[id_2]=.
|
|
||||||
Lean will only consider declarations whose name contains =id_1= and does not contain =id_2=.
|
|
||||||
Here is an example:
|
|
||||||
|
|
||||||
#+BEGIN_SRC
|
|
||||||
FINDG 48 10
|
|
||||||
+intro -and -elim
|
|
||||||
#+END_SRC
|
|
||||||
|
|
||||||
For the command above, lean will print any declaration whose resultant type matches the type expected by =_=, and
|
|
||||||
whose name contains =intro= but does not contain =and= and =elim=.
|
|
||||||
Lean does not display "trivial" matches. We say a match is trivial if the resultant type of a declaration
|
|
||||||
matches anything.
|
|
||||||
|
|
||||||
The output produced by =FINDG= uses the same format used by =FINDP=.
|
|
||||||
|
|
|
@ -40,8 +40,7 @@ Author: Leonardo de Moura
|
||||||
|
|
||||||
#define LEAN_FUZZY_MAX_ERRORS 3
|
#define LEAN_FUZZY_MAX_ERRORS 3
|
||||||
#define LEAN_FUZZY_MAX_ERRORS_FACTOR 3
|
#define LEAN_FUZZY_MAX_ERRORS_FACTOR 3
|
||||||
#define LEAN_FIND_CONSUME_IMPLICIT true // lean will add metavariables for implicit arguments when printing the type of declarations in FINDP and FINDG
|
#define LEAN_FIND_CONSUME_IMPLICIT true // lean will add metavariables for implicit arguments when printing the type of declarations in FINDP
|
||||||
#define LEAN_FINDG_MAX_STEPS 128 // maximum number of steps per unification problem
|
|
||||||
|
|
||||||
namespace lean {
|
namespace lean {
|
||||||
static name * g_auto_completion_max_results = nullptr;
|
static name * g_auto_completion_max_results = nullptr;
|
||||||
|
@ -320,7 +319,6 @@ static std::string * g_show = nullptr;
|
||||||
static std::string * g_valid = nullptr;
|
static std::string * g_valid = nullptr;
|
||||||
static std::string * g_sleep = nullptr;
|
static std::string * g_sleep = nullptr;
|
||||||
static std::string * g_findp = nullptr;
|
static std::string * g_findp = nullptr;
|
||||||
static std::string * g_findg = nullptr;
|
|
||||||
|
|
||||||
static bool is_command(std::string const & cmd, std::string const & line) {
|
static bool is_command(std::string const & cmd, std::string const & line) {
|
||||||
return line.compare(0, cmd.size(), cmd) == 0;
|
return line.compare(0, cmd.size(), cmd) == 0;
|
||||||
|
@ -745,80 +743,6 @@ void consume_pos_neg_strs(std::string const & filters, buffer<std::string> & pos
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool match_type(type_checker & tc, expr const & meta, expr const & expected_type, declaration const & d) {
|
|
||||||
goal g(meta, expected_type);
|
|
||||||
buffer<level> ls;
|
|
||||||
unsigned num_ls = d.get_num_univ_params();
|
|
||||||
for (unsigned i = 0; i < num_ls; i++)
|
|
||||||
ls.push_back(mk_meta_univ(mk_fresh_name()));
|
|
||||||
expr dt = instantiate_type_univ_params(d, to_list(ls.begin(), ls.end()));
|
|
||||||
unsigned num_e = get_expect_num_args(tc, expected_type);
|
|
||||||
unsigned num_d = get_expect_num_args(tc, dt);
|
|
||||||
if (num_e > num_d)
|
|
||||||
return false;
|
|
||||||
for (unsigned i = 0; i < num_d - num_e; i++) {
|
|
||||||
dt = tc.whnf(dt).first;
|
|
||||||
expr meta = g.mk_meta(mk_fresh_name(), binding_domain(dt));
|
|
||||||
dt = instantiate(binding_body(dt), meta);
|
|
||||||
}
|
|
||||||
// Remark: we ignore declarations where the resultant type is of the form
|
|
||||||
// (?M ...) because they unify with almost everything. They produce a lot of noise in the output.
|
|
||||||
// Perhaps we should have an option to enable/disable this kind of declaration. For now, we
|
|
||||||
// just ingore them.
|
|
||||||
if (is_meta(dt))
|
|
||||||
return false; // matches anything
|
|
||||||
try {
|
|
||||||
unifier_config cfg;
|
|
||||||
cfg.m_max_steps = LEAN_FINDG_MAX_STEPS;
|
|
||||||
cfg.m_kind = unifier_kind::Cheap;
|
|
||||||
auto r = unify(tc.env(), dt, expected_type, substitution(), cfg);
|
|
||||||
return static_cast<bool>(r.pull());
|
|
||||||
} catch (exception&) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::unique_ptr<type_checker> mk_find_goal_type_checker(environment const & env) {
|
|
||||||
return mk_opaque_type_checker(env);
|
|
||||||
}
|
|
||||||
|
|
||||||
static name * g_tmp_prefix = nullptr;
|
|
||||||
void server::find_goal_matches(unsigned line_num, unsigned col_num, std::string const & filters) {
|
|
||||||
buffer<std::string> pos_names, neg_names;
|
|
||||||
consume_pos_neg_strs(filters, pos_names, neg_names);
|
|
||||||
m_out << "-- BEGINFINDG";
|
|
||||||
optional<pair<environment, options>> env_opts = m_file->infom().get_closest_env_opts(line_num);
|
|
||||||
if (!env_opts) {
|
|
||||||
m_out << " NAY" << std::endl;
|
|
||||||
m_out << "-- ENDFINDG" << std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (line_num >= m_file->infom().get_processed_upto())
|
|
||||||
m_out << " NAY";
|
|
||||||
m_out << std::endl;
|
|
||||||
environment const & env = env_opts->first;
|
|
||||||
options const & opts = env_opts->second;
|
|
||||||
std::unique_ptr<type_checker> tc = mk_find_goal_type_checker(env);
|
|
||||||
if (auto meta = m_file->infom().get_meta_at(line_num, col_num)) {
|
|
||||||
if (is_meta(*meta)) {
|
|
||||||
if (auto type = m_file->infom().get_type_at(line_num, col_num)) {
|
|
||||||
env.for_each_declaration([&](declaration const & d) {
|
|
||||||
if (!is_projection(env, d.get_name()) &&
|
|
||||||
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_type(*tc.get(), *meta, *type, d)) {
|
|
||||||
if (optional<name> alias = is_expr_aliased(env, d.get_name()))
|
|
||||||
display_decl(*alias, d.get_name(), env, opts);
|
|
||||||
else
|
|
||||||
display_decl(d.get_name(), d.get_name(), env, opts);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}}}
|
|
||||||
m_out << "-- ENDFINDG" << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
void server::wait(optional<unsigned> ms) {
|
void server::wait(optional<unsigned> ms) {
|
||||||
m_out << "-- BEGINWAIT" << std::endl;
|
m_out << "-- BEGINWAIT" << std::endl;
|
||||||
if (!m_worker.wait(ms))
|
if (!m_worker.wait(ms))
|
||||||
|
@ -910,10 +834,6 @@ bool server::operator()(std::istream & in) {
|
||||||
if (line.size() > 63)
|
if (line.size() > 63)
|
||||||
line.resize(63);
|
line.resize(63);
|
||||||
find_pattern(line_num, line);
|
find_pattern(line_num, line);
|
||||||
} else if (is_command(*g_findg, line)) {
|
|
||||||
pair<unsigned, unsigned> line_col_num = get_line_col_num(line, *g_findg);
|
|
||||||
read_line(in, line);
|
|
||||||
find_goal_matches(line_col_num.first, line_col_num.second, line);
|
|
||||||
} else {
|
} else {
|
||||||
throw exception(sstream() << "unexpected command line: " << line);
|
throw exception(sstream() << "unexpected command line: " << line);
|
||||||
}
|
}
|
||||||
|
@ -936,7 +856,6 @@ void initialize_server() {
|
||||||
g_auto_completion_max_results = new name{"auto_completion", "max_results"};
|
g_auto_completion_max_results = new name{"auto_completion", "max_results"};
|
||||||
register_unsigned_option(*g_auto_completion_max_results, LEAN_DEFAULT_AUTO_COMPLETION_MAX_RESULTS,
|
register_unsigned_option(*g_auto_completion_max_results, LEAN_DEFAULT_AUTO_COMPLETION_MAX_RESULTS,
|
||||||
"(auto-completion) maximum number of results returned");
|
"(auto-completion) maximum number of results returned");
|
||||||
g_tmp_prefix = new name(name::mk_internal_unique_name());
|
|
||||||
g_load = new std::string("LOAD");
|
g_load = new std::string("LOAD");
|
||||||
g_save = new std::string("SAVE");
|
g_save = new std::string("SAVE");
|
||||||
g_visit = new std::string("VISIT");
|
g_visit = new std::string("VISIT");
|
||||||
|
@ -955,11 +874,9 @@ void initialize_server() {
|
||||||
g_valid = new std::string("VALID");
|
g_valid = new std::string("VALID");
|
||||||
g_sleep = new std::string("SLEEP");
|
g_sleep = new std::string("SLEEP");
|
||||||
g_findp = new std::string("FINDP");
|
g_findp = new std::string("FINDP");
|
||||||
g_findg = new std::string("FINDG");
|
|
||||||
}
|
}
|
||||||
void finalize_server() {
|
void finalize_server() {
|
||||||
delete g_auto_completion_max_results;
|
delete g_auto_completion_max_results;
|
||||||
delete g_tmp_prefix;
|
|
||||||
delete g_load;
|
delete g_load;
|
||||||
delete g_save;
|
delete g_save;
|
||||||
delete g_visit;
|
delete g_visit;
|
||||||
|
@ -978,6 +895,5 @@ void finalize_server() {
|
||||||
delete g_valid;
|
delete g_valid;
|
||||||
delete g_sleep;
|
delete g_sleep;
|
||||||
delete g_findp;
|
delete g_findp;
|
||||||
delete g_findg;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
VISIT consume_args.lean
|
|
||||||
SYNC 9
|
|
||||||
import logic data.nat.basic
|
|
||||||
open nat eq.ops
|
|
||||||
|
|
||||||
definition a := true
|
|
||||||
|
|
||||||
theorem tst (a b c : nat) : a + b + c = a + c + b :=
|
|
||||||
calc a + b + c = a + (b + c) : _
|
|
||||||
... = a + (c + b) : {!add.comm}
|
|
||||||
... = a + c + b : (!add.assoc)⁻¹
|
|
||||||
WAIT
|
|
||||||
CLEAR_CACHE
|
|
||||||
WAIT
|
|
||||||
INFO 4
|
|
||||||
WAIT
|
|
||||||
INFO 4
|
|
||||||
FINDG 7 31
|
|
||||||
+assoc -symm
|
|
||||||
WAIT
|
|
||||||
SHOW
|
|
|
@ -1,43 +0,0 @@
|
||||||
-- BEGINWAIT
|
|
||||||
-- ENDWAIT
|
|
||||||
-- BEGINWAIT
|
|
||||||
-- ENDWAIT
|
|
||||||
-- BEGININFO
|
|
||||||
-- TYPE|4|13
|
|
||||||
Type₁
|
|
||||||
-- ACK
|
|
||||||
-- TYPE|4|16
|
|
||||||
Prop
|
|
||||||
-- ACK
|
|
||||||
-- IDENTIFIER|4|16
|
|
||||||
true
|
|
||||||
-- ACK
|
|
||||||
-- ENDINFO
|
|
||||||
-- BEGINWAIT
|
|
||||||
-- ENDWAIT
|
|
||||||
-- BEGININFO
|
|
||||||
-- TYPE|4|13
|
|
||||||
Type₁
|
|
||||||
-- ACK
|
|
||||||
-- TYPE|4|16
|
|
||||||
Prop
|
|
||||||
-- ACK
|
|
||||||
-- IDENTIFIER|4|16
|
|
||||||
true
|
|
||||||
-- ACK
|
|
||||||
-- ENDINFO
|
|
||||||
-- BEGINFINDG
|
|
||||||
-- ENDFINDG
|
|
||||||
-- BEGINWAIT
|
|
||||||
-- ENDWAIT
|
|
||||||
-- BEGINSHOW
|
|
||||||
import logic data.nat.basic
|
|
||||||
open nat eq.ops
|
|
||||||
|
|
||||||
definition a := true
|
|
||||||
|
|
||||||
theorem tst (a b c : nat) : a + b + c = a + c + b :=
|
|
||||||
calc a + b + c = a + (b + c) : _
|
|
||||||
... = a + (c + b) : {!add.comm}
|
|
||||||
... = a + c + b : (!add.assoc)⁻¹
|
|
||||||
-- ENDSHOW
|
|
|
@ -1,17 +0,0 @@
|
||||||
import logic
|
|
||||||
open tactic
|
|
||||||
|
|
||||||
notation `(` h `|` r:(foldl `|` (e r, tactic.or_else r e) h) `)` := r
|
|
||||||
|
|
||||||
definition basic_tac : tactic
|
|
||||||
:= repeat (apply @and.intro | assumption)
|
|
||||||
|
|
||||||
set_begin_end_tactic basic_tac -- basic_tac is automatically applied to each element of a proof-qed block
|
|
||||||
|
|
||||||
theorem tst (a b : Prop) (H : ¬ a ∨ ¬ b) (Hb : b) : ¬ a ∧ b :=
|
|
||||||
begin
|
|
||||||
assume Ha, or.elim H
|
|
||||||
(assume Hna, @absurd _ false Ha Hna)
|
|
||||||
(assume Hnb, @absurd _ false Hb Hnb),
|
|
||||||
now
|
|
||||||
end
|
|
Loading…
Reference in a new issue