feat(frontends/lean): add 'include' and 'omit' commands, closes #184
This commit is contained in:
parent
6950b4aa9b
commit
284f300440
9 changed files with 96 additions and 9 deletions
|
@ -15,7 +15,7 @@
|
||||||
"options" "precedence" "postfix" "prefix" "calc_trans" "calc_subst" "calc_refl"
|
"options" "precedence" "postfix" "prefix" "calc_trans" "calc_subst" "calc_refl"
|
||||||
"infix" "infixl" "infixr" "notation" "eval" "check" "exit" "coercion" "end"
|
"infix" "infixl" "infixr" "notation" "eval" "check" "exit" "coercion" "end"
|
||||||
"using" "namespace" "including" "instance" "class" "section"
|
"using" "namespace" "including" "instance" "class" "section"
|
||||||
"set_option" "add_rewrite" "extends")
|
"set_option" "add_rewrite" "extends" "include" "omit")
|
||||||
"lean keywords")
|
"lean keywords")
|
||||||
|
|
||||||
(defconst lean-syntax-table
|
(defconst lean-syntax-table
|
||||||
|
|
|
@ -334,9 +334,6 @@ environment definition_cmd_core(parser & p, bool is_theorem, bool is_opaque, boo
|
||||||
erase_local_binder_info(ps);
|
erase_local_binder_info(ps);
|
||||||
value = Fun(ps, value, p);
|
value = Fun(ps, value, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
update_univ_parameters(ls_buffer, collect_univ_params(value, collect_univ_params(type)), p);
|
|
||||||
ls = to_list(ls_buffer.begin(), ls_buffer.end());
|
|
||||||
}
|
}
|
||||||
unsigned end_line = p.pos().first;
|
unsigned end_line = p.pos().first;
|
||||||
|
|
||||||
|
@ -361,6 +358,8 @@ environment definition_cmd_core(parser & p, bool is_theorem, bool is_opaque, boo
|
||||||
section_value_ps.append(section_ps);
|
section_value_ps.append(section_ps);
|
||||||
erase_local_binder_info(section_value_ps);
|
erase_local_binder_info(section_value_ps);
|
||||||
value = Fun_as_is(section_value_ps, value, p);
|
value = Fun_as_is(section_value_ps, value, p);
|
||||||
|
update_univ_parameters(ls_buffer, collect_univ_params(value, collect_univ_params(type)), p);
|
||||||
|
ls = to_list(ls_buffer.begin(), ls_buffer.end());
|
||||||
levels section_ls = collect_section_levels(ls, p);
|
levels section_ls = collect_section_levels(ls, p);
|
||||||
while (!section_ps.empty() && p.is_section_variable(section_ps.back()))
|
while (!section_ps.empty() && p.is_section_variable(section_ps.back()))
|
||||||
section_ps.pop_back(); // we do not fix section variables
|
section_ps.pop_back(); // we do not fix section variables
|
||||||
|
@ -368,6 +367,9 @@ environment definition_cmd_core(parser & p, bool is_theorem, bool is_opaque, boo
|
||||||
param = mk_explicit(param);
|
param = mk_explicit(param);
|
||||||
expr ref = mk_implicit(mk_app(mk_explicit(mk_constant(real_n, section_ls)), section_ps));
|
expr ref = mk_implicit(mk_app(mk_explicit(mk_constant(real_n, section_ls)), section_ps));
|
||||||
p.add_local_expr(n, ref);
|
p.add_local_expr(n, ref);
|
||||||
|
} else {
|
||||||
|
update_univ_parameters(ls_buffer, collect_univ_params(value, collect_univ_params(type)), p);
|
||||||
|
ls = to_list(ls_buffer.begin(), ls_buffer.end());
|
||||||
}
|
}
|
||||||
expr pre_type = type;
|
expr pre_type = type;
|
||||||
expr pre_value = value;
|
expr pre_value = value;
|
||||||
|
@ -488,6 +490,36 @@ environment protected_definition_cmd(parser & p) {
|
||||||
return definition_cmd_core(p, is_theorem, is_opaque, false, true);
|
return definition_cmd_core(p, is_theorem, is_opaque, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
environment include_cmd_core(parser & p, bool include) {
|
||||||
|
if (!p.curr_is_identifier())
|
||||||
|
throw parser_error(sstream() << "invalid include/omit command, identifier expected", p.pos());
|
||||||
|
while (p.curr_is_identifier()) {
|
||||||
|
auto pos = p.pos();
|
||||||
|
name n = p.get_name_val();
|
||||||
|
p.next();
|
||||||
|
if (!p.get_local(n))
|
||||||
|
throw parser_error(sstream() << "invalid include/omit command, '" << n << "' is not a section parameter/variable", pos);
|
||||||
|
if (include) {
|
||||||
|
if (p.is_include_variable(n))
|
||||||
|
throw parser_error(sstream() << "invalid include command, '" << n << "' has already been included", pos);
|
||||||
|
p.include_variable(n);
|
||||||
|
} else {
|
||||||
|
if (!p.is_include_variable(n))
|
||||||
|
throw parser_error(sstream() << "invalid omit command, '" << n << "' has not been included", pos);
|
||||||
|
p.omit_variable(n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return p.env();
|
||||||
|
}
|
||||||
|
|
||||||
|
environment include_cmd(parser & p) {
|
||||||
|
return include_cmd_core(p, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
environment omit_cmd(parser & p) {
|
||||||
|
return include_cmd_core(p, false);
|
||||||
|
}
|
||||||
|
|
||||||
void register_decl_cmds(cmd_table & r) {
|
void register_decl_cmds(cmd_table & r) {
|
||||||
add_cmd(r, cmd_info("universe", "declare a global universe level", universe_cmd));
|
add_cmd(r, cmd_info("universe", "declare a global universe level", universe_cmd));
|
||||||
add_cmd(r, cmd_info("variable", "declare a new variable", variable_cmd));
|
add_cmd(r, cmd_info("variable", "declare a new variable", variable_cmd));
|
||||||
|
@ -502,5 +534,7 @@ void register_decl_cmds(cmd_table & r) {
|
||||||
add_cmd(r, cmd_info("private", "add new private definition/theorem", private_definition_cmd));
|
add_cmd(r, cmd_info("private", "add new private definition/theorem", private_definition_cmd));
|
||||||
add_cmd(r, cmd_info("protected", "add new protected definition/theorem", protected_definition_cmd));
|
add_cmd(r, cmd_info("protected", "add new protected definition/theorem", protected_definition_cmd));
|
||||||
add_cmd(r, cmd_info("theorem", "add new theorem", theorem_cmd));
|
add_cmd(r, cmd_info("theorem", "add new theorem", theorem_cmd));
|
||||||
|
add_cmd(r, cmd_info("include", "force section parameter/variable to be included", include_cmd));
|
||||||
|
add_cmd(r, cmd_info("omit", "undo 'include' command", omit_cmd));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -413,6 +413,12 @@ struct inductive_cmd_fn {
|
||||||
|
|
||||||
/** \brief Collect section local parameters used in the inductive decls */
|
/** \brief Collect section local parameters used in the inductive decls */
|
||||||
void collect_section_locals(buffer<inductive_decl> const & decls, expr_struct_set & ls) {
|
void collect_section_locals(buffer<inductive_decl> const & decls, expr_struct_set & ls) {
|
||||||
|
buffer<expr> include_vars;
|
||||||
|
m_p.get_include_variables(include_vars);
|
||||||
|
for (expr const & param : include_vars) {
|
||||||
|
collect_locals(mlocal_type(param), ls);
|
||||||
|
ls.insert(param);
|
||||||
|
}
|
||||||
for (auto const & d : decls) {
|
for (auto const & d : decls) {
|
||||||
collect_locals(inductive_decl_type(d), ls);
|
collect_locals(inductive_decl_type(d), ls);
|
||||||
for (auto const & ir : inductive_decl_intros(d))
|
for (auto const & ir : inductive_decl_intros(d))
|
||||||
|
@ -665,9 +671,9 @@ struct inductive_cmd_fn {
|
||||||
parser::local_scope scope(m_p);
|
parser::local_scope scope(m_p);
|
||||||
parse_inductive_decls(decls);
|
parse_inductive_decls(decls);
|
||||||
}
|
}
|
||||||
include_section_levels(decls);
|
|
||||||
buffer<expr> section_params;
|
buffer<expr> section_params;
|
||||||
abstract_section_locals(decls, section_params);
|
abstract_section_locals(decls, section_params);
|
||||||
|
include_section_levels(decls);
|
||||||
m_num_params += section_params.size();
|
m_num_params += section_params.size();
|
||||||
declare_inductive_types(decls);
|
declare_inductive_types(decls);
|
||||||
unsigned num_univ_params = m_levels.size();
|
unsigned num_univ_params = m_levels.size();
|
||||||
|
|
|
@ -96,6 +96,7 @@ parser::parser(environment const & env, io_state const & ios,
|
||||||
m_local_level_decls = s->m_lds;
|
m_local_level_decls = s->m_lds;
|
||||||
m_local_decls = s->m_eds;
|
m_local_decls = s->m_eds;
|
||||||
m_variables = s->m_vars;
|
m_variables = s->m_vars;
|
||||||
|
m_include_vars = s->m_include_vars;
|
||||||
m_options_stack = s->m_options_stack;
|
m_options_stack = s->m_options_stack;
|
||||||
}
|
}
|
||||||
m_num_threads = num_threads;
|
m_num_threads = num_threads;
|
||||||
|
@ -445,6 +446,12 @@ unsigned parser::get_local_index(name const & n) const {
|
||||||
return m_local_decls.find_idx(n);
|
return m_local_decls.find_idx(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void parser::get_include_variables(buffer<expr> & vars) const {
|
||||||
|
m_include_vars.for_each([&](name const & n) {
|
||||||
|
vars.push_back(*get_local(n));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
static unsigned g_level_add_prec = 10;
|
static unsigned g_level_add_prec = 10;
|
||||||
static unsigned g_level_cup_prec = 5;
|
static unsigned g_level_cup_prec = 5;
|
||||||
|
|
||||||
|
@ -1352,7 +1359,7 @@ void parser::save_snapshot() {
|
||||||
if (!m_snapshot_vector)
|
if (!m_snapshot_vector)
|
||||||
return;
|
return;
|
||||||
if (m_snapshot_vector->empty() || static_cast<int>(m_snapshot_vector->back().m_line) != m_scanner.get_line())
|
if (m_snapshot_vector->empty() || static_cast<int>(m_snapshot_vector->back().m_line) != m_scanner.get_line())
|
||||||
m_snapshot_vector->push_back(snapshot(m_env, m_local_level_decls, m_local_decls, m_variables,
|
m_snapshot_vector->push_back(snapshot(m_env, m_local_level_decls, m_local_decls, m_variables, m_include_vars,
|
||||||
m_options_stack, m_ios.get_options(), m_scanner.get_line()));
|
m_options_stack, m_ios.get_options(), m_scanner.get_line()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,15 +52,17 @@ struct snapshot {
|
||||||
local_level_decls m_lds;
|
local_level_decls m_lds;
|
||||||
local_expr_decls m_eds;
|
local_expr_decls m_eds;
|
||||||
name_set m_vars; // subset of m_eds that is tagged as section variables
|
name_set m_vars; // subset of m_eds that is tagged as section variables
|
||||||
|
name_set m_include_vars; // subset of m_eds that must be includes
|
||||||
options_stack m_options_stack;
|
options_stack m_options_stack;
|
||||||
options m_options;
|
options m_options;
|
||||||
unsigned m_line;
|
unsigned m_line;
|
||||||
snapshot():m_line(0) {}
|
snapshot():m_line(0) {}
|
||||||
snapshot(environment const & env, options const & o):m_env(env), m_options(o), m_line(1) {}
|
snapshot(environment const & env, options const & o):m_env(env), m_options(o), m_line(1) {}
|
||||||
snapshot(environment const & env, local_level_decls const & lds, local_expr_decls const & eds,
|
snapshot(environment const & env, local_level_decls const & lds, local_expr_decls const & eds,
|
||||||
name_set const & vars, options_stack const & os, options const & opts,
|
name_set const & vars, name_set const & includes, options_stack const & os, options const & opts,
|
||||||
unsigned line):
|
unsigned line):
|
||||||
m_env(env), m_lds(lds), m_eds(eds), m_vars(vars), m_options_stack(os), m_options(opts), m_line(line) {}
|
m_env(env), m_lds(lds), m_eds(eds), m_vars(vars), m_include_vars(includes),
|
||||||
|
m_options_stack(os), m_options(opts), m_line(line) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector<snapshot> snapshot_vector;
|
typedef std::vector<snapshot> snapshot_vector;
|
||||||
|
@ -78,6 +80,7 @@ class parser {
|
||||||
local_level_decls m_local_level_decls;
|
local_level_decls m_local_level_decls;
|
||||||
local_expr_decls m_local_decls;
|
local_expr_decls m_local_decls;
|
||||||
name_set m_variables; // subset of m_local_decls that is marked as variables
|
name_set m_variables; // subset of m_local_decls that is marked as variables
|
||||||
|
name_set m_include_vars; // subset of m_local_decls that is marked as include
|
||||||
options_stack m_options_stack;
|
options_stack m_options_stack;
|
||||||
pos_info m_last_cmd_pos;
|
pos_info m_last_cmd_pos;
|
||||||
pos_info m_last_script_pos;
|
pos_info m_last_script_pos;
|
||||||
|
@ -316,6 +319,10 @@ public:
|
||||||
void add_local(expr const & p) { return add_local_expr(local_pp_name(p), p); }
|
void add_local(expr const & p) { return add_local_expr(local_pp_name(p), p); }
|
||||||
bool is_section_variable(name const & n) const { return m_variables.contains(n); }
|
bool is_section_variable(name const & n) const { return m_variables.contains(n); }
|
||||||
bool is_section_variable(expr const & e) const { return is_section_variable(local_pp_name(e)); }
|
bool is_section_variable(expr const & e) const { return is_section_variable(local_pp_name(e)); }
|
||||||
|
void include_variable(name const & n) { m_include_vars.insert(n); }
|
||||||
|
void omit_variable(name const & n) { m_include_vars.erase(n); }
|
||||||
|
bool is_include_variable(name const & n) const { return m_include_vars.contains(n); }
|
||||||
|
void get_include_variables(buffer<expr> & vars) const;
|
||||||
/** \brief Position of the local level declaration named \c n in the sequence of local level decls. */
|
/** \brief Position of the local level declaration named \c n in the sequence of local level decls. */
|
||||||
unsigned get_local_level_index(name const & n) const;
|
unsigned get_local_level_index(name const & n) const;
|
||||||
/** \brief Position of the local declaration named \c n in the sequence of local decls. */
|
/** \brief Position of the local declaration named \c n in the sequence of local decls. */
|
||||||
|
|
|
@ -86,7 +86,8 @@ void init_token_table(token_table & t) {
|
||||||
"inductive", "record", "renaming", "extends", "structure", "module", "universe",
|
"inductive", "record", "renaming", "extends", "structure", "module", "universe",
|
||||||
"precedence", "infixl", "infixr", "infix", "postfix", "prefix", "notation", "context",
|
"precedence", "infixl", "infixr", "infix", "postfix", "prefix", "notation", "context",
|
||||||
"exit", "set_option", "open", "export", "calc_subst", "calc_refl", "calc_trans", "tactic_hint",
|
"exit", "set_option", "open", "export", "calc_subst", "calc_refl", "calc_trans", "tactic_hint",
|
||||||
"add_begin_end_tactic", "set_begin_end_tactic", "instance", "class", "#erase_cache", nullptr};
|
"add_begin_end_tactic", "set_begin_end_tactic", "instance", "class",
|
||||||
|
"include", "omit", "#erase_cache", nullptr};
|
||||||
|
|
||||||
pair<char const *, char const *> aliases[] =
|
pair<char const *, char const *> aliases[] =
|
||||||
{{g_lambda_unicode, "fun"}, {"forall", "Pi"}, {g_forall_unicode, "Pi"}, {g_pi_unicode, "Pi"},
|
{{g_lambda_unicode, "fun"}, {"forall", "Pi"}, {g_forall_unicode, "Pi"}, {g_pi_unicode, "Pi"},
|
||||||
|
|
|
@ -75,6 +75,12 @@ levels collect_section_levels(level_param_names const & ls, parser & p) {
|
||||||
// Collect local (section) constants occurring in type and value, sort them, and store in section_ps
|
// Collect local (section) constants occurring in type and value, sort them, and store in section_ps
|
||||||
void collect_section_locals(expr const & type, expr const & value, parser const & p, buffer<expr> & section_ps) {
|
void collect_section_locals(expr const & type, expr const & value, parser const & p, buffer<expr> & section_ps) {
|
||||||
expr_struct_set ls;
|
expr_struct_set ls;
|
||||||
|
buffer<expr> include_vars;
|
||||||
|
p.get_include_variables(include_vars);
|
||||||
|
for (expr const & param : include_vars) {
|
||||||
|
collect_locals(mlocal_type(param), ls);
|
||||||
|
ls.insert(param);
|
||||||
|
}
|
||||||
collect_locals(type, ls);
|
collect_locals(type, ls);
|
||||||
collect_locals(value, ls);
|
collect_locals(value, ls);
|
||||||
sort_section_params(ls, p, section_ps);
|
sort_section_params(ls, p, section_ps);
|
||||||
|
|
22
tests/lean/omit.lean
Normal file
22
tests/lean/omit.lean
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
section
|
||||||
|
parameter A : Type
|
||||||
|
parameter a : A
|
||||||
|
parameter c : A
|
||||||
|
omit A
|
||||||
|
include A
|
||||||
|
include A
|
||||||
|
omit A
|
||||||
|
parameter B : Type
|
||||||
|
parameter b : B
|
||||||
|
parameter d : B
|
||||||
|
include A
|
||||||
|
include a
|
||||||
|
include c
|
||||||
|
definition foo := b
|
||||||
|
|
||||||
|
inductive tst (C : Type) :=
|
||||||
|
mk : tst C
|
||||||
|
end
|
||||||
|
|
||||||
|
check foo
|
||||||
|
check tst
|
4
tests/lean/omit.lean.expected.out
Normal file
4
tests/lean/omit.lean.expected.out
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
omit.lean:5:7: error: invalid omit command, 'A' has not been included
|
||||||
|
omit.lean:7:10: error: invalid include command, 'A' has already been included
|
||||||
|
foo : Π (A : Type), A → A → (Π (B : Type), B → B)
|
||||||
|
tst : Π (A : Type), A → A → Type → Type
|
Loading…
Add table
Reference in a new issue