2014-06-18 17:36:21 +00:00
|
|
|
/*
|
|
|
|
Copyright (c) 2014 Microsoft Corporation. All rights reserved.
|
|
|
|
Released under Apache 2.0 license as described in the file LICENSE.
|
|
|
|
|
|
|
|
Author: Leonardo de Moura
|
|
|
|
*/
|
|
|
|
#include <algorithm>
|
|
|
|
#include "util/sstream.h"
|
|
|
|
#include "kernel/type_checker.h"
|
2014-07-14 04:41:44 +00:00
|
|
|
#include "kernel/abstract.h"
|
2014-10-03 00:29:22 +00:00
|
|
|
#include "kernel/for_each_fn.h"
|
2014-06-18 17:36:21 +00:00
|
|
|
#include "library/scoped_ext.h"
|
|
|
|
#include "library/aliases.h"
|
|
|
|
#include "library/private.h"
|
2014-09-03 22:01:13 +00:00
|
|
|
#include "library/protected.h"
|
2014-06-25 15:39:14 +00:00
|
|
|
#include "library/placeholder.h"
|
2014-06-18 17:36:21 +00:00
|
|
|
#include "library/locals.h"
|
2014-06-25 15:30:09 +00:00
|
|
|
#include "library/explicit.h"
|
2014-09-19 20:30:08 +00:00
|
|
|
#include "library/reducible.h"
|
2014-07-08 00:48:20 +00:00
|
|
|
#include "library/coercion.h"
|
2014-12-10 05:12:39 +00:00
|
|
|
#include "library/class.h"
|
2014-12-05 00:52:42 +00:00
|
|
|
#include "library/definitional/equations.h"
|
2014-06-18 17:36:21 +00:00
|
|
|
#include "frontends/lean/parser.h"
|
2014-07-04 21:25:44 +00:00
|
|
|
#include "frontends/lean/class.h"
|
2014-12-10 05:12:39 +00:00
|
|
|
#include "frontends/lean/util.h"
|
2014-09-23 17:00:36 +00:00
|
|
|
#include "frontends/lean/tokens.h"
|
2014-06-18 17:36:21 +00:00
|
|
|
|
|
|
|
namespace lean {
|
2014-10-11 17:58:15 +00:00
|
|
|
static environment declare_universe(parser & p, environment env, name const & n, bool local) {
|
2014-10-12 00:13:33 +00:00
|
|
|
if (in_context(env) || local) {
|
2014-10-30 02:47:14 +00:00
|
|
|
p.add_local_level(n, mk_param_univ(n), local);
|
2014-06-18 17:36:21 +00:00
|
|
|
} else {
|
|
|
|
name const & ns = get_namespace(env);
|
|
|
|
name full_n = ns + n;
|
|
|
|
env = module::add_universe(env, full_n);
|
|
|
|
if (!ns.is_anonymous())
|
2014-07-28 04:01:59 +00:00
|
|
|
env = add_level_alias(env, n, full_n);
|
2014-06-18 17:36:21 +00:00
|
|
|
}
|
|
|
|
return env;
|
|
|
|
}
|
|
|
|
|
2014-10-11 17:58:15 +00:00
|
|
|
static environment universes_cmd_core(parser & p, bool local) {
|
2014-10-10 15:45:59 +00:00
|
|
|
if (!p.curr_is_identifier())
|
|
|
|
throw parser_error("invalid 'universes' command, identifier expected", p.pos());
|
|
|
|
environment env = p.env();
|
|
|
|
while (p.curr_is_identifier()) {
|
|
|
|
name n = p.get_name_val();
|
|
|
|
p.next();
|
2014-10-11 17:58:15 +00:00
|
|
|
env = declare_universe(p, env, n, local);
|
2014-10-10 15:45:59 +00:00
|
|
|
}
|
|
|
|
return env;
|
|
|
|
}
|
|
|
|
|
2014-10-11 17:58:15 +00:00
|
|
|
static environment universe_cmd(parser & p) {
|
|
|
|
if (p.curr_is_token(get_variables_tk())) {
|
|
|
|
p.next();
|
|
|
|
return universes_cmd_core(p, true);
|
|
|
|
} else {
|
|
|
|
bool local = false;
|
|
|
|
if (p.curr_is_token(get_variable_tk())) {
|
|
|
|
p.next();
|
|
|
|
local = true;
|
|
|
|
}
|
|
|
|
name n = p.check_id_next("invalid 'universe' command, identifier expected");
|
|
|
|
return declare_universe(p, p.env(), n, local);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static environment universes_cmd(parser & p) {
|
|
|
|
return universes_cmd_core(p, false);
|
|
|
|
}
|
|
|
|
|
2014-06-18 20:55:48 +00:00
|
|
|
bool parse_univ_params(parser & p, buffer<name> & ps) {
|
2014-09-23 17:00:36 +00:00
|
|
|
if (p.curr_is_token(get_llevel_curly_tk())) {
|
2014-06-18 17:36:21 +00:00
|
|
|
p.next();
|
2014-09-23 17:00:36 +00:00
|
|
|
while (!p.curr_is_token(get_rcurly_tk())) {
|
2014-06-18 17:36:21 +00:00
|
|
|
name l = p.check_id_next("invalid universe parameter, identifier expected");
|
|
|
|
p.add_local_level(l, mk_param_univ(l));
|
|
|
|
ps.push_back(l);
|
|
|
|
}
|
|
|
|
p.next();
|
2014-06-18 20:55:48 +00:00
|
|
|
return true;
|
|
|
|
} else{
|
|
|
|
return false;
|
2014-06-18 17:36:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-06-18 20:55:48 +00:00
|
|
|
void update_univ_parameters(buffer<name> & ls_buffer, name_set const & found, parser const & p) {
|
2014-06-18 17:36:21 +00:00
|
|
|
unsigned old_sz = ls_buffer.size();
|
|
|
|
found.for_each([&](name const & n) {
|
|
|
|
if (std::find(ls_buffer.begin(), ls_buffer.begin() + old_sz, n) == ls_buffer.begin() + old_sz)
|
|
|
|
ls_buffer.push_back(n);
|
|
|
|
});
|
|
|
|
std::sort(ls_buffer.begin(), ls_buffer.end(), [&](name const & n1, name const & n2) {
|
|
|
|
return p.get_local_level_index(n1) < p.get_local_level_index(n2);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2014-10-02 23:20:52 +00:00
|
|
|
enum class variable_kind { Constant, Parameter, Variable, Axiom };
|
|
|
|
|
2014-10-03 00:29:22 +00:00
|
|
|
static void check_parameter_type(parser & p, name const & n, expr const & type, pos_info const & pos) {
|
|
|
|
for_each(type, [&](expr const & e, unsigned) {
|
2014-10-11 17:25:02 +00:00
|
|
|
if (is_local(e) && p.is_local_variable(e))
|
2014-10-03 00:29:22 +00:00
|
|
|
throw parser_error(sstream() << "invalid parameter declaration '" << n << "', it depends on " <<
|
2014-10-10 03:48:20 +00:00
|
|
|
"variable '" << local_pp_name(e) << "'", pos);
|
2014-10-03 00:29:22 +00:00
|
|
|
return true;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2014-06-18 17:36:21 +00:00
|
|
|
static environment declare_var(parser & p, environment env,
|
|
|
|
name const & n, level_param_names const & ls, expr const & type,
|
2014-10-02 23:20:52 +00:00
|
|
|
variable_kind k, optional<binder_info> const & _bi, pos_info const & pos) {
|
2014-06-30 23:52:20 +00:00
|
|
|
binder_info bi;
|
|
|
|
if (_bi) bi = *_bi;
|
2014-10-10 03:48:20 +00:00
|
|
|
if (k == variable_kind::Parameter || k == variable_kind::Variable) {
|
|
|
|
if (k == variable_kind::Parameter) {
|
2014-10-12 00:13:33 +00:00
|
|
|
check_in_context(p);
|
2014-10-03 00:29:22 +00:00
|
|
|
check_parameter_type(p, n, type, pos);
|
2014-10-10 03:48:20 +00:00
|
|
|
}
|
2014-10-03 01:29:41 +00:00
|
|
|
if (p.get_local(n))
|
2014-10-10 03:48:20 +00:00
|
|
|
throw parser_error(sstream() << "invalid parameter/variable declaration, '"
|
|
|
|
<< n << "' has already been declared", pos);
|
2014-09-11 23:37:23 +00:00
|
|
|
name u = p.mk_fresh_name();
|
|
|
|
expr l = p.save_pos(mk_local(u, n, type, bi), pos);
|
2014-10-03 00:29:22 +00:00
|
|
|
p.add_local_expr(n, l, k == variable_kind::Variable);
|
2014-06-18 17:36:21 +00:00
|
|
|
return env;
|
|
|
|
} else {
|
2014-10-03 00:29:22 +00:00
|
|
|
lean_assert(k == variable_kind::Constant || k == variable_kind::Axiom);
|
2014-06-18 17:36:21 +00:00
|
|
|
name const & ns = get_namespace(env);
|
|
|
|
name full_n = ns + n;
|
2014-10-02 23:20:52 +00:00
|
|
|
if (k == variable_kind::Axiom) {
|
2014-06-18 17:36:21 +00:00
|
|
|
env = module::add(env, check(env, mk_axiom(full_n, ls, type)));
|
2014-09-23 17:00:36 +00:00
|
|
|
p.add_decl_index(full_n, pos, get_axiom_tk(), type);
|
2014-08-23 19:39:59 +00:00
|
|
|
} else {
|
2014-10-02 23:54:56 +00:00
|
|
|
env = module::add(env, check(env, mk_constant_assumption(full_n, ls, type)));
|
2014-09-23 17:00:36 +00:00
|
|
|
p.add_decl_index(full_n, pos, get_variable_tk(), type);
|
2014-08-23 19:39:59 +00:00
|
|
|
}
|
2014-06-18 17:36:21 +00:00
|
|
|
if (!ns.is_anonymous())
|
2014-07-28 04:01:59 +00:00
|
|
|
env = add_expr_alias(env, n, full_n);
|
2014-06-18 17:36:21 +00:00
|
|
|
return env;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-06 23:46:34 +00:00
|
|
|
/** \brief If we are in a section, then add the new local levels to it. */
|
2014-10-10 03:48:20 +00:00
|
|
|
static void update_local_levels(parser & p, level_param_names const & new_ls, bool is_variable) {
|
|
|
|
for (auto const & l : new_ls)
|
|
|
|
p.add_local_level(l, mk_param_univ(l), is_variable);
|
2014-07-06 23:46:34 +00:00
|
|
|
}
|
|
|
|
|
2014-10-10 03:48:20 +00:00
|
|
|
optional<binder_info> parse_binder_info(parser & p, variable_kind k) {
|
2014-06-30 23:52:20 +00:00
|
|
|
optional<binder_info> bi = p.parse_optional_binder_info();
|
2014-10-10 03:48:20 +00:00
|
|
|
if (bi && k != variable_kind::Parameter && k != variable_kind::Variable)
|
|
|
|
parser_error("invalid binder annotation, it can only be used to declare variables/parameters", p.pos());
|
2014-06-30 23:52:20 +00:00
|
|
|
return bi;
|
|
|
|
}
|
|
|
|
|
2014-10-02 23:20:52 +00:00
|
|
|
static void check_variable_kind(parser & p, variable_kind k) {
|
2014-10-12 00:35:59 +00:00
|
|
|
if (in_context(p.env())) {
|
2014-10-02 23:20:52 +00:00
|
|
|
if (k == variable_kind::Axiom || k == variable_kind::Constant)
|
2014-10-13 14:17:33 +00:00
|
|
|
throw parser_error("invalid declaration, 'constant/axiom' cannot be used in contexts",
|
2014-10-02 23:20:52 +00:00
|
|
|
p.pos());
|
|
|
|
} else {
|
2014-10-10 03:48:20 +00:00
|
|
|
if (k == variable_kind::Parameter)
|
|
|
|
throw parser_error("invalid declaration, 'parameter/hypothesis/conjecture' "
|
2014-10-13 14:17:33 +00:00
|
|
|
"can only be used in contexts", p.pos());
|
2014-10-02 23:20:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-11-01 18:18:10 +00:00
|
|
|
static environment variable_cmd_core(parser & p, variable_kind k) {
|
2014-10-02 23:20:52 +00:00
|
|
|
check_variable_kind(p, k);
|
2014-06-18 17:36:21 +00:00
|
|
|
auto pos = p.pos();
|
2014-10-10 03:48:20 +00:00
|
|
|
optional<binder_info> bi = parse_binder_info(p, k);
|
2014-06-18 17:36:21 +00:00
|
|
|
name n = p.check_id_next("invalid declaration, identifier expected");
|
|
|
|
buffer<name> ls_buffer;
|
2014-10-10 03:48:20 +00:00
|
|
|
if (p.curr_is_token(get_llevel_curly_tk()) && (k == variable_kind::Parameter || k == variable_kind::Variable))
|
|
|
|
throw parser_error("invalid declaration, only constants/axioms can be universe polymorphic", p.pos());
|
2014-06-18 17:36:21 +00:00
|
|
|
optional<parser::local_scope> scope1;
|
2014-10-10 03:48:20 +00:00
|
|
|
if (k == variable_kind::Constant || k == variable_kind::Axiom)
|
2014-06-18 17:36:21 +00:00
|
|
|
scope1.emplace(p);
|
|
|
|
parse_univ_params(p, ls_buffer);
|
|
|
|
expr type;
|
2014-09-23 17:00:36 +00:00
|
|
|
if (!p.curr_is_token(get_colon_tk())) {
|
2014-06-30 16:14:55 +00:00
|
|
|
buffer<expr> ps;
|
2014-11-24 00:42:53 +00:00
|
|
|
unsigned rbp = 0;
|
|
|
|
auto lenv = p.parse_binders(ps, rbp);
|
2014-09-23 17:00:36 +00:00
|
|
|
p.check_token_next(get_colon_tk(), "invalid declaration, ':' expected");
|
2014-06-18 17:36:21 +00:00
|
|
|
type = p.parse_scoped_expr(ps, lenv);
|
2014-07-14 04:41:44 +00:00
|
|
|
type = Pi(ps, type, p);
|
2014-06-18 17:36:21 +00:00
|
|
|
} else {
|
|
|
|
p.next();
|
|
|
|
type = p.parse_expr();
|
|
|
|
}
|
2014-06-30 23:52:20 +00:00
|
|
|
p.parse_close_binder_info(bi);
|
2014-06-18 17:36:21 +00:00
|
|
|
level_param_names ls;
|
2014-10-10 03:48:20 +00:00
|
|
|
if (ls_buffer.empty()) {
|
2014-06-18 17:36:21 +00:00
|
|
|
ls = to_level_param_names(collect_univ_params(type));
|
|
|
|
} else {
|
2014-06-18 20:55:48 +00:00
|
|
|
update_univ_parameters(ls_buffer, collect_univ_params(type), p);
|
2014-06-18 17:36:21 +00:00
|
|
|
ls = to_list(ls_buffer.begin(), ls_buffer.end());
|
|
|
|
}
|
2014-07-06 23:46:34 +00:00
|
|
|
level_param_names new_ls;
|
2014-10-08 15:37:54 +00:00
|
|
|
list<expr> ctx = p.locals_to_context();
|
2014-07-14 04:04:01 +00:00
|
|
|
std::tie(type, new_ls) = p.elaborate_type(type, ctx);
|
2014-10-10 03:48:20 +00:00
|
|
|
if (k == variable_kind::Variable || k == variable_kind::Parameter)
|
|
|
|
update_local_levels(p, new_ls, k == variable_kind::Variable);
|
2014-10-02 23:20:52 +00:00
|
|
|
return declare_var(p, p.env(), n, append(ls, new_ls), type, k, bi, pos);
|
2014-06-18 17:36:21 +00:00
|
|
|
}
|
2014-11-01 18:18:10 +00:00
|
|
|
static environment variable_cmd(parser & p) {
|
2014-10-02 23:20:52 +00:00
|
|
|
return variable_cmd_core(p, variable_kind::Variable);
|
2014-06-18 17:36:21 +00:00
|
|
|
}
|
2014-11-01 18:18:10 +00:00
|
|
|
static environment axiom_cmd(parser & p) {
|
2014-10-02 23:20:52 +00:00
|
|
|
return variable_cmd_core(p, variable_kind::Axiom);
|
|
|
|
}
|
2014-11-01 18:18:10 +00:00
|
|
|
static environment constant_cmd(parser & p) {
|
2014-10-02 23:20:52 +00:00
|
|
|
return variable_cmd_core(p, variable_kind::Constant);
|
|
|
|
}
|
2014-11-01 18:18:10 +00:00
|
|
|
static environment parameter_cmd(parser & p) {
|
2014-10-02 23:20:52 +00:00
|
|
|
return variable_cmd_core(p, variable_kind::Parameter);
|
|
|
|
}
|
|
|
|
|
|
|
|
static environment variables_cmd_core(parser & p, variable_kind k) {
|
|
|
|
check_variable_kind(p, k);
|
|
|
|
auto pos = p.pos();
|
|
|
|
environment env = p.env();
|
|
|
|
while (true) {
|
2014-10-10 03:48:20 +00:00
|
|
|
optional<binder_info> bi = parse_binder_info(p, k);
|
2014-10-02 23:20:52 +00:00
|
|
|
buffer<name> ids;
|
|
|
|
while (!p.curr_is_token(get_colon_tk())) {
|
|
|
|
name id = p.check_id_next("invalid parameters declaration, identifier expected");
|
|
|
|
ids.push_back(id);
|
|
|
|
}
|
|
|
|
p.next();
|
|
|
|
optional<parser::local_scope> scope1;
|
2014-10-10 03:48:20 +00:00
|
|
|
if (k == variable_kind::Constant || k == variable_kind::Axiom)
|
2014-10-02 23:20:52 +00:00
|
|
|
scope1.emplace(p);
|
|
|
|
expr type = p.parse_expr();
|
|
|
|
p.parse_close_binder_info(bi);
|
|
|
|
level_param_names ls = to_level_param_names(collect_univ_params(type));
|
2014-10-08 20:12:42 +00:00
|
|
|
list<expr> ctx = p.locals_to_context();
|
2014-10-02 23:20:52 +00:00
|
|
|
for (auto id : ids) {
|
|
|
|
// Hack: to make sure we get different universe parameters for each parameter.
|
|
|
|
// Alternative: elaborate once and copy types replacing universes in new_ls.
|
|
|
|
level_param_names new_ls;
|
|
|
|
expr new_type;
|
|
|
|
std::tie(new_type, new_ls) = p.elaborate_type(type, ctx);
|
2014-10-10 03:48:20 +00:00
|
|
|
if (k == variable_kind::Variable || k == variable_kind::Parameter)
|
|
|
|
update_local_levels(p, new_ls, k == variable_kind::Variable);
|
2014-10-02 23:20:52 +00:00
|
|
|
new_ls = append(ls, new_ls);
|
|
|
|
env = declare_var(p, env, id, new_ls, new_type, k, bi, pos);
|
|
|
|
}
|
|
|
|
if (!p.curr_is_token(get_lparen_tk()) && !p.curr_is_token(get_lcurly_tk()) &&
|
|
|
|
!p.curr_is_token(get_ldcurly_tk()) && !p.curr_is_token(get_lbracket_tk()))
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return env;
|
|
|
|
}
|
|
|
|
static environment variables_cmd(parser & p) {
|
|
|
|
return variables_cmd_core(p, variable_kind::Variable);
|
|
|
|
}
|
|
|
|
static environment parameters_cmd(parser & p) {
|
|
|
|
return variables_cmd_core(p, variable_kind::Parameter);
|
|
|
|
}
|
|
|
|
static environment constants_cmd(parser & p) {
|
|
|
|
return variables_cmd_core(p, variable_kind::Constant);
|
2014-06-18 17:36:21 +00:00
|
|
|
}
|
|
|
|
|
2014-07-04 21:25:44 +00:00
|
|
|
struct decl_modifiers {
|
2014-09-28 19:20:42 +00:00
|
|
|
bool m_is_instance;
|
|
|
|
bool m_is_coercion;
|
|
|
|
bool m_is_reducible;
|
|
|
|
optional<unsigned> m_priority;
|
|
|
|
decl_modifiers():m_priority() {
|
2014-09-03 22:01:13 +00:00
|
|
|
m_is_instance = false;
|
|
|
|
m_is_coercion = false;
|
2014-09-19 20:30:08 +00:00
|
|
|
m_is_reducible = false;
|
2014-07-04 21:25:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void parse(parser & p) {
|
|
|
|
while (true) {
|
2014-09-28 19:20:42 +00:00
|
|
|
auto pos = p.pos();
|
2014-09-23 17:00:36 +00:00
|
|
|
if (p.curr_is_token(get_instance_tk())) {
|
2014-07-04 21:25:44 +00:00
|
|
|
m_is_instance = true;
|
|
|
|
p.next();
|
2014-09-23 17:00:36 +00:00
|
|
|
} else if (p.curr_is_token(get_coercion_tk())) {
|
2014-10-12 01:40:48 +00:00
|
|
|
auto pos = p.pos();
|
2014-07-08 00:48:20 +00:00
|
|
|
p.next();
|
2014-10-12 01:40:48 +00:00
|
|
|
if (in_context(p.env()))
|
|
|
|
throw parser_error("invalid '[coercion]' modifier, coercions cannot be defined in contexts", pos);
|
|
|
|
m_is_coercion = true;
|
2014-09-23 17:00:36 +00:00
|
|
|
} else if (p.curr_is_token(get_reducible_tk())) {
|
2014-09-19 20:30:08 +00:00
|
|
|
m_is_reducible = true;
|
|
|
|
p.next();
|
2014-09-28 19:20:42 +00:00
|
|
|
} else if (auto it = parse_instance_priority(p)) {
|
|
|
|
m_priority = *it;
|
|
|
|
if (!m_is_instance)
|
|
|
|
throw parser_error("invalid '[priority]' occurrence, declaration must be marked as an '[instance]'", pos);
|
2014-07-04 21:25:44 +00:00
|
|
|
} else {
|
|
|
|
break;
|
|
|
|
}
|
2014-06-18 17:36:21 +00:00
|
|
|
}
|
|
|
|
}
|
2014-07-04 21:25:44 +00:00
|
|
|
};
|
2014-06-18 17:36:21 +00:00
|
|
|
|
2014-08-18 00:03:54 +00:00
|
|
|
static void check_end_of_theorem(parser const & p) {
|
|
|
|
if (!p.curr_is_command_like())
|
|
|
|
throw parser_error("':=', '.', command, script, or end-of-file expected", p.pos());
|
|
|
|
}
|
|
|
|
|
2014-09-07 19:28:58 +00:00
|
|
|
static void erase_local_binder_info(buffer<expr> & ps) {
|
|
|
|
for (expr & p : ps)
|
|
|
|
p = update_local(p, binder_info());
|
|
|
|
}
|
|
|
|
|
2014-12-05 00:52:42 +00:00
|
|
|
static bool is_curr_with_or_comma(parser & p) {
|
|
|
|
return p.curr_is_token(get_with_tk()) || p.curr_is_token(get_comma_tk());
|
|
|
|
}
|
|
|
|
|
|
|
|
expr parse_equations(parser & p, name const & n, expr const & type, buffer<expr> & auxs) {
|
|
|
|
buffer<expr> eqns;
|
|
|
|
{
|
|
|
|
parser::local_scope scope1(p);
|
|
|
|
parser::undef_id_to_local_scope scope2(p);
|
|
|
|
lean_assert(is_curr_with_or_comma(p));
|
|
|
|
expr f = mk_local(n, type);
|
|
|
|
if (p.curr_is_token(get_with_tk())) {
|
|
|
|
while (p.curr_is_token(get_with_tk())) {
|
|
|
|
p.next();
|
|
|
|
name g_name = p.check_id_next("invalid declaration, identifier expected");
|
|
|
|
p.check_token_next(get_colon_tk(), "invalid declaration, ':' expected");
|
|
|
|
expr g_type = p.parse_expr();
|
|
|
|
expr g = mk_local(g_name, g_type);
|
|
|
|
auxs.push_back(g);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
p.check_token_next(get_comma_tk(), "invalid declaration, ',' expected");
|
|
|
|
p.add_local(f);
|
|
|
|
for (expr const & g : auxs)
|
|
|
|
p.add_local(g);
|
|
|
|
while (true) {
|
|
|
|
expr lhs = p.parse_expr();
|
|
|
|
p.check_token_next(get_assign_tk(), "invalid declaration, ':=' expected");
|
|
|
|
expr rhs = p.parse_expr();
|
|
|
|
eqns.push_back(mk_equation(lhs, rhs));
|
|
|
|
if (!p.curr_is_token(get_comma_tk()))
|
|
|
|
break;
|
|
|
|
p.next();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (p.curr_is_token(get_wf_tk())) {
|
|
|
|
p.next();
|
|
|
|
expr Hwf = p.parse_expr();
|
|
|
|
return mk_equations(eqns.size(), eqns.data(), Hwf);
|
|
|
|
} else {
|
|
|
|
return mk_equations(eqns.size(), eqns.data());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-11-01 18:35:38 +00:00
|
|
|
// An Lean example is not really a definition, but we use the definition infrastructure to simulate it.
|
|
|
|
enum def_cmd_kind { Theorem, Definition, Example };
|
|
|
|
|
2014-12-05 00:03:29 +00:00
|
|
|
class definition_cmd_fn {
|
|
|
|
parser & m_p;
|
|
|
|
environment m_env;
|
|
|
|
def_cmd_kind m_kind;
|
|
|
|
bool m_is_opaque;
|
|
|
|
bool m_is_private;
|
|
|
|
bool m_is_protected;
|
|
|
|
pos_info m_pos;
|
|
|
|
|
|
|
|
name m_name;
|
|
|
|
decl_modifiers m_modifiers;
|
|
|
|
name m_real_name; // real name for this declaration
|
|
|
|
buffer<name> m_ls_buffer;
|
2014-12-05 00:52:42 +00:00
|
|
|
buffer<expr> m_aux_decls;
|
2014-12-05 00:03:29 +00:00
|
|
|
expr m_type;
|
|
|
|
expr m_value;
|
|
|
|
level_param_names m_ls;
|
|
|
|
pos_info m_end_pos;
|
|
|
|
|
|
|
|
expr m_pre_type;
|
|
|
|
expr m_pre_value;
|
|
|
|
|
|
|
|
bool is_definition() const { return m_kind == Definition; }
|
|
|
|
unsigned start_line() const { return m_pos.first; }
|
|
|
|
unsigned end_line() const { return m_end_pos.first; }
|
|
|
|
|
|
|
|
void parse_name() {
|
|
|
|
if (m_kind == Example)
|
|
|
|
m_name = m_p.mk_fresh_name();
|
|
|
|
else
|
|
|
|
m_name = m_p.check_id_next("invalid declaration, identifier expected");
|
|
|
|
}
|
|
|
|
|
|
|
|
void parse_type_value() {
|
2014-07-06 04:49:32 +00:00
|
|
|
// Parse universe parameters
|
2014-12-05 00:03:29 +00:00
|
|
|
parser::local_scope scope1(m_p);
|
|
|
|
parse_univ_params(m_p, m_ls_buffer);
|
2014-07-06 04:49:32 +00:00
|
|
|
|
|
|
|
// Parse modifiers
|
2014-12-05 00:03:29 +00:00
|
|
|
m_modifiers.parse(m_p);
|
2014-07-06 04:49:32 +00:00
|
|
|
|
2014-12-05 00:03:29 +00:00
|
|
|
if (m_p.curr_is_token(get_assign_tk())) {
|
|
|
|
auto pos = m_p.pos();
|
|
|
|
m_p.next();
|
|
|
|
m_type = m_p.save_pos(mk_expr_placeholder(), pos);
|
|
|
|
m_value = m_p.parse_expr();
|
|
|
|
} else if (m_p.curr_is_token(get_colon_tk())) {
|
|
|
|
m_p.next();
|
|
|
|
auto pos = m_p.pos();
|
|
|
|
m_type = m_p.parse_expr();
|
2014-12-05 00:52:42 +00:00
|
|
|
if (is_curr_with_or_comma(m_p)) {
|
|
|
|
m_value = parse_equations(m_p, m_name, m_type, m_aux_decls);
|
|
|
|
} else if (!is_definition() && !m_p.curr_is_token(get_assign_tk())) {
|
2014-12-05 00:03:29 +00:00
|
|
|
check_end_of_theorem(m_p);
|
|
|
|
m_value = m_p.save_pos(mk_expr_placeholder(), pos);
|
2014-07-08 21:38:57 +00:00
|
|
|
} else {
|
2014-12-05 00:03:29 +00:00
|
|
|
m_p.check_token_next(get_assign_tk(), "invalid declaration, ':=' expected");
|
|
|
|
m_value = m_p.save_pos(m_p.parse_expr(), pos);
|
2014-07-08 21:38:57 +00:00
|
|
|
}
|
2014-06-25 15:39:14 +00:00
|
|
|
} else {
|
2014-06-30 16:14:55 +00:00
|
|
|
buffer<expr> ps;
|
2014-06-18 17:36:21 +00:00
|
|
|
optional<local_environment> lenv;
|
2014-10-11 01:08:03 +00:00
|
|
|
bool last_block_delimited = false;
|
2014-12-05 00:03:29 +00:00
|
|
|
lenv = m_p.parse_binders(ps, last_block_delimited);
|
|
|
|
auto pos = m_p.pos();
|
|
|
|
if (m_p.curr_is_token(get_colon_tk())) {
|
|
|
|
m_p.next();
|
|
|
|
m_type = m_p.parse_scoped_expr(ps, *lenv);
|
2014-12-05 00:52:42 +00:00
|
|
|
if (is_curr_with_or_comma(m_p)) {
|
|
|
|
m_value = parse_equations(m_p, m_name, m_type, m_aux_decls);
|
|
|
|
} else if (!is_definition() && !m_p.curr_is_token(get_assign_tk())) {
|
2014-12-05 00:03:29 +00:00
|
|
|
check_end_of_theorem(m_p);
|
|
|
|
m_value = m_p.save_pos(mk_expr_placeholder(), pos);
|
2014-07-08 21:38:57 +00:00
|
|
|
} else {
|
2014-12-05 00:03:29 +00:00
|
|
|
m_p.check_token_next(get_assign_tk(), "invalid declaration, ':=' expected");
|
|
|
|
m_value = m_p.parse_scoped_expr(ps, *lenv);
|
2014-07-08 21:38:57 +00:00
|
|
|
}
|
2014-07-06 23:46:34 +00:00
|
|
|
} else {
|
2014-10-11 01:08:03 +00:00
|
|
|
if (!last_block_delimited && !ps.empty() &&
|
|
|
|
!is_placeholder(mlocal_type(ps.back()))) {
|
|
|
|
throw parser_error("invalid declaration, ambiguous parameter declaration, "
|
|
|
|
"(solution: put parentheses around parameters)",
|
|
|
|
pos);
|
|
|
|
}
|
2014-12-05 00:03:29 +00:00
|
|
|
m_type = m_p.save_pos(mk_expr_placeholder(), m_p.pos());
|
|
|
|
m_p.check_token_next(get_assign_tk(), "invalid declaration, ':=' expected");
|
|
|
|
m_value = m_p.parse_scoped_expr(ps, *lenv);
|
2014-06-18 17:36:21 +00:00
|
|
|
}
|
2014-12-05 00:03:29 +00:00
|
|
|
m_type = Pi(ps, m_type, m_p);
|
2014-09-07 19:28:58 +00:00
|
|
|
erase_local_binder_info(ps);
|
2014-12-05 00:03:29 +00:00
|
|
|
m_value = Fun(ps, m_value, m_p);
|
2014-06-18 17:36:21 +00:00
|
|
|
}
|
2014-12-05 00:03:29 +00:00
|
|
|
m_end_pos = m_p.pos();
|
2014-06-18 17:36:21 +00:00
|
|
|
}
|
2014-08-01 01:35:57 +00:00
|
|
|
|
2014-12-05 00:03:29 +00:00
|
|
|
void mk_real_name() {
|
|
|
|
if (m_is_private) {
|
|
|
|
auto env_n = add_private_name(m_env, m_name, optional<unsigned>(hash(m_pos.first, m_pos.second)));
|
|
|
|
m_env = env_n.first;
|
|
|
|
m_real_name = env_n.second;
|
|
|
|
} else {
|
|
|
|
name const & ns = get_namespace(m_env);
|
|
|
|
m_real_name = ns + m_name;
|
|
|
|
}
|
|
|
|
}
|
2014-08-01 01:35:57 +00:00
|
|
|
|
2014-12-05 00:03:29 +00:00
|
|
|
void parse() {
|
|
|
|
parse_name();
|
|
|
|
parse_type_value();
|
|
|
|
if (m_p.used_sorry())
|
|
|
|
m_p.declare_sorry();
|
|
|
|
m_env = m_p.env();
|
|
|
|
mk_real_name();
|
2014-08-01 01:35:57 +00:00
|
|
|
}
|
|
|
|
|
2014-12-05 00:03:29 +00:00
|
|
|
void process_locals() {
|
|
|
|
if (m_p.has_locals()) {
|
|
|
|
buffer<expr> locals;
|
|
|
|
collect_locals(m_type, m_value, m_p, locals);
|
|
|
|
m_type = Pi_as_is(locals, m_type, m_p);
|
|
|
|
buffer<expr> new_locals;
|
|
|
|
new_locals.append(locals);
|
|
|
|
erase_local_binder_info(new_locals);
|
|
|
|
m_value = Fun_as_is(new_locals, m_value, m_p);
|
|
|
|
auto ps = collect_univ_params_ignoring_tactics(m_type);
|
|
|
|
ps = collect_univ_params_ignoring_tactics(m_value, ps);
|
|
|
|
update_univ_parameters(m_ls_buffer, ps, m_p);
|
|
|
|
remove_local_vars(m_p, locals);
|
|
|
|
m_ls = to_list(m_ls_buffer.begin(), m_ls_buffer.end());
|
|
|
|
levels local_ls = collect_local_nonvar_levels(m_p, m_ls);
|
|
|
|
local_ls = remove_local_vars(m_p, local_ls);
|
|
|
|
if (!locals.empty()) {
|
|
|
|
expr ref = mk_local_ref(m_real_name, local_ls, locals);
|
|
|
|
m_p.add_local_expr(m_name, ref);
|
|
|
|
} else if (local_ls) {
|
|
|
|
expr ref = mk_constant(m_real_name, local_ls);
|
|
|
|
m_p.add_local_expr(m_name, ref);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
update_univ_parameters(m_ls_buffer, collect_univ_params(m_value, collect_univ_params(m_type)), m_p);
|
|
|
|
m_ls = to_list(m_ls_buffer.begin(), m_ls_buffer.end());
|
2014-10-04 14:55:32 +00:00
|
|
|
}
|
2014-06-18 17:36:21 +00:00
|
|
|
}
|
2014-12-05 00:03:29 +00:00
|
|
|
|
|
|
|
bool try_cache() {
|
|
|
|
// We don't cache examples
|
|
|
|
if (m_kind != Example && m_p.are_info_lines_valid(start_line(), end_line())) {
|
|
|
|
// we only use the cache if the information associated with the line is valid
|
|
|
|
if (auto it = m_p.find_cached_definition(m_real_name, m_type, m_value)) {
|
|
|
|
optional<certified_declaration> cd;
|
|
|
|
try {
|
|
|
|
level_param_names c_ls; expr c_type, c_value;
|
|
|
|
std::tie(c_ls, c_type, c_value) = *it;
|
|
|
|
if (m_kind == Theorem) {
|
|
|
|
cd = check(m_env, mk_theorem(m_real_name, c_ls, c_type, c_value));
|
|
|
|
if (!m_p.keep_new_thms()) {
|
|
|
|
// discard theorem
|
|
|
|
cd = check(m_env, mk_axiom(m_real_name, c_ls, c_type));
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
cd = check(m_env, mk_definition(m_env, m_real_name, c_ls, c_type, c_value, m_is_opaque));
|
2014-10-13 17:05:38 +00:00
|
|
|
}
|
2014-12-05 00:03:29 +00:00
|
|
|
if (!m_is_private)
|
|
|
|
m_p.add_decl_index(m_real_name, m_pos, m_p.get_cmd_token(), c_type);
|
|
|
|
m_env = module::add(m_env, *cd);
|
|
|
|
return true;
|
|
|
|
} catch (exception&) {}
|
|
|
|
}
|
2014-08-17 19:14:42 +00:00
|
|
|
}
|
2014-12-05 00:03:29 +00:00
|
|
|
return false;
|
2014-08-10 18:04:16 +00:00
|
|
|
}
|
|
|
|
|
2014-12-05 00:03:29 +00:00
|
|
|
void register_decl() {
|
|
|
|
if (m_kind != Example) {
|
|
|
|
if (!m_is_private)
|
|
|
|
m_p.add_decl_index(m_real_name, m_pos, m_p.get_cmd_token(), m_type);
|
|
|
|
if (m_real_name != m_name)
|
|
|
|
m_env = add_expr_alias_rec(m_env, m_name, m_real_name);
|
|
|
|
if (m_modifiers.m_is_instance) {
|
|
|
|
bool persistent = true;
|
|
|
|
if (m_modifiers.m_priority) {
|
|
|
|
#if defined(__GNUC__) && !defined(__CLANG__)
|
|
|
|
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
|
|
|
|
#endif
|
|
|
|
m_env = add_instance(m_env, m_real_name, *m_modifiers.m_priority, persistent);
|
|
|
|
} else {
|
|
|
|
m_env = add_instance(m_env, m_real_name, persistent);
|
2014-10-13 17:05:38 +00:00
|
|
|
}
|
2014-08-10 18:04:16 +00:00
|
|
|
}
|
2014-12-05 00:03:29 +00:00
|
|
|
if (m_modifiers.m_is_coercion)
|
|
|
|
m_env = add_coercion(m_env, m_real_name, m_p.ios());
|
|
|
|
if (m_is_protected)
|
|
|
|
m_env = add_protected(m_env, m_real_name);
|
|
|
|
if (m_modifiers.m_is_reducible)
|
|
|
|
m_env = set_reducible(m_env, m_real_name, reducible_status::On);
|
2014-07-12 21:50:57 +00:00
|
|
|
}
|
2014-06-18 17:36:21 +00:00
|
|
|
}
|
2014-08-10 18:04:16 +00:00
|
|
|
|
2014-12-05 00:03:29 +00:00
|
|
|
void elaborate() {
|
|
|
|
if (!try_cache()) {
|
|
|
|
expr pre_type = m_type;
|
|
|
|
expr pre_value = m_value;
|
|
|
|
level_param_names new_ls;
|
|
|
|
m_p.remove_proof_state_info(m_pos, m_p.pos());
|
|
|
|
if (!is_definition()) {
|
|
|
|
// Theorems and Examples
|
|
|
|
auto type_pos = m_p.pos_of(m_type);
|
|
|
|
bool clear_pre_info = false; // we don't want to clear pre_info data until we process the proof.
|
|
|
|
std::tie(m_type, new_ls) = m_p.elaborate_type(m_type, list<expr>(), clear_pre_info);
|
|
|
|
check_no_metavar(m_env, m_real_name, m_type, true);
|
|
|
|
m_ls = append(m_ls, new_ls);
|
|
|
|
expr type_as_is = m_p.save_pos(mk_as_is(m_type), type_pos);
|
|
|
|
if (!m_p.collecting_info() && m_kind == Theorem && m_p.num_threads() > 1) {
|
|
|
|
// Add as axiom, and create a task to prove the theorem.
|
|
|
|
// Remark: we don't postpone the "proof" of Examples.
|
|
|
|
m_p.add_delayed_theorem(m_env, m_real_name, m_ls, type_as_is, m_value);
|
|
|
|
m_env = module::add(m_env, check(m_env, mk_axiom(m_real_name, m_ls, m_type)));
|
|
|
|
} else {
|
|
|
|
std::tie(m_type, m_value, new_ls) = m_p.elaborate_definition(m_name, type_as_is, m_value, m_is_opaque);
|
|
|
|
new_ls = append(m_ls, new_ls);
|
|
|
|
auto cd = check(m_env, mk_theorem(m_real_name, new_ls, m_type, m_value));
|
|
|
|
if (m_kind == Theorem) {
|
|
|
|
// Remark: we don't keep examples
|
|
|
|
if (!m_p.keep_new_thms()) {
|
|
|
|
// discard theorem
|
|
|
|
cd = check(m_env, mk_axiom(m_real_name, new_ls, m_type));
|
|
|
|
}
|
|
|
|
m_env = module::add(m_env, cd);
|
|
|
|
m_p.cache_definition(m_real_name, pre_type, pre_value, new_ls, m_type, m_value);
|
|
|
|
}
|
|
|
|
}
|
2014-11-01 18:35:38 +00:00
|
|
|
} else {
|
2014-12-05 00:03:29 +00:00
|
|
|
std::tie(m_type, m_value, new_ls) = m_p.elaborate_definition(m_name, m_type, m_value, m_is_opaque);
|
|
|
|
new_ls = append(m_ls, new_ls);
|
|
|
|
m_env = module::add(m_env, check(m_env, mk_definition(m_env, m_real_name, new_ls,
|
|
|
|
m_type, m_value, m_is_opaque)));
|
|
|
|
m_p.cache_definition(m_real_name, pre_type, pre_value, new_ls, m_type, m_value);
|
2014-11-01 18:35:38 +00:00
|
|
|
}
|
2014-09-28 19:20:42 +00:00
|
|
|
}
|
|
|
|
}
|
2014-12-05 00:03:29 +00:00
|
|
|
|
|
|
|
public:
|
|
|
|
definition_cmd_fn(parser & p, def_cmd_kind kind, bool is_opaque, bool is_private, bool is_protected):
|
|
|
|
m_p(p), m_env(m_p.env()), m_kind(kind), m_is_opaque(is_opaque),
|
|
|
|
m_is_private(is_private), m_is_protected(is_protected),
|
|
|
|
m_pos(p.pos()) {
|
|
|
|
lean_assert(!(!is_definition() && !m_is_opaque));
|
|
|
|
lean_assert(!(m_is_private && m_is_protected));
|
|
|
|
}
|
|
|
|
|
|
|
|
environment operator()() {
|
|
|
|
parse();
|
|
|
|
process_locals();
|
|
|
|
elaborate();
|
|
|
|
register_decl();
|
|
|
|
return m_env;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
static environment definition_cmd_core(parser & p, def_cmd_kind kind, bool is_opaque, bool is_private, bool is_protected) {
|
|
|
|
return definition_cmd_fn(p, kind, is_opaque, is_private, is_protected)();
|
2014-06-18 17:36:21 +00:00
|
|
|
}
|
2014-11-01 18:18:10 +00:00
|
|
|
static environment definition_cmd(parser & p) {
|
2014-11-01 18:35:38 +00:00
|
|
|
return definition_cmd_core(p, Definition, false, false, false);
|
2014-09-19 20:44:44 +00:00
|
|
|
}
|
2014-11-01 18:18:10 +00:00
|
|
|
static environment opaque_definition_cmd(parser & p) {
|
2014-09-23 17:00:36 +00:00
|
|
|
p.check_token_next(get_definition_tk(), "invalid 'opaque' definition, 'definition' expected");
|
2014-11-01 18:35:38 +00:00
|
|
|
return definition_cmd_core(p, Definition, true, false, false);
|
2014-06-18 17:36:21 +00:00
|
|
|
}
|
2014-11-01 18:18:10 +00:00
|
|
|
static environment theorem_cmd(parser & p) {
|
2014-11-01 18:35:38 +00:00
|
|
|
return definition_cmd_core(p, Theorem, true, false, false);
|
|
|
|
}
|
|
|
|
static environment example_cmd(parser & p) {
|
|
|
|
return definition_cmd_core(p, Example, true, false, false);
|
2014-09-19 21:30:02 +00:00
|
|
|
}
|
2014-11-01 18:18:10 +00:00
|
|
|
static environment private_definition_cmd(parser & p) {
|
2014-11-01 18:35:38 +00:00
|
|
|
def_cmd_kind kind = Definition;
|
2014-10-02 14:56:01 +00:00
|
|
|
bool is_opaque = false;
|
|
|
|
if (p.curr_is_token_or_id(get_opaque_tk())) {
|
|
|
|
is_opaque = true;
|
|
|
|
p.next();
|
|
|
|
p.check_token_next(get_definition_tk(), "invalid 'private' definition, 'definition' expected");
|
|
|
|
} else if (p.curr_is_token_or_id(get_definition_tk())) {
|
2014-09-19 21:30:02 +00:00
|
|
|
p.next();
|
2014-09-23 17:00:36 +00:00
|
|
|
} else if (p.curr_is_token_or_id(get_theorem_tk())) {
|
2014-09-19 21:30:02 +00:00
|
|
|
p.next();
|
2014-11-01 18:35:38 +00:00
|
|
|
kind = Theorem;
|
2014-10-02 14:56:01 +00:00
|
|
|
is_opaque = true;
|
2014-09-19 21:30:02 +00:00
|
|
|
} else {
|
|
|
|
throw parser_error("invalid 'private' definition/theorem, 'definition' or 'theorem' expected", p.pos());
|
|
|
|
}
|
2014-11-01 18:35:38 +00:00
|
|
|
return definition_cmd_core(p, kind, is_opaque, true, false);
|
2014-09-19 22:04:52 +00:00
|
|
|
}
|
2014-11-01 18:18:10 +00:00
|
|
|
static environment protected_definition_cmd(parser & p) {
|
2014-11-01 18:35:38 +00:00
|
|
|
def_cmd_kind kind = Definition;
|
2014-09-19 22:04:52 +00:00
|
|
|
bool is_opaque = false;
|
2014-09-23 17:00:36 +00:00
|
|
|
if (p.curr_is_token_or_id(get_opaque_tk())) {
|
2014-09-19 22:04:52 +00:00
|
|
|
is_opaque = true;
|
|
|
|
p.next();
|
2014-09-23 17:00:36 +00:00
|
|
|
p.check_token_next(get_definition_tk(), "invalid 'protected' definition, 'definition' expected");
|
|
|
|
} else if (p.curr_is_token_or_id(get_definition_tk())) {
|
2014-09-19 22:04:52 +00:00
|
|
|
p.next();
|
2014-09-23 17:00:36 +00:00
|
|
|
} else if (p.curr_is_token_or_id(get_theorem_tk())) {
|
2014-09-19 22:04:52 +00:00
|
|
|
p.next();
|
2014-11-01 18:35:38 +00:00
|
|
|
kind = Theorem;
|
2014-09-19 22:04:52 +00:00
|
|
|
is_opaque = true;
|
|
|
|
} else {
|
|
|
|
throw parser_error("invalid 'protected' definition/theorem, 'definition' or 'theorem' expected", p.pos());
|
|
|
|
}
|
2014-11-01 18:35:38 +00:00
|
|
|
return definition_cmd_core(p, kind, is_opaque, false, true);
|
2014-06-18 17:36:21 +00:00
|
|
|
}
|
|
|
|
|
2014-11-01 18:18:10 +00:00
|
|
|
static environment include_cmd_core(parser & p, bool include) {
|
2014-10-03 14:23:24 +00:00
|
|
|
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))
|
2014-10-10 03:48:20 +00:00
|
|
|
throw parser_error(sstream() << "invalid include/omit command, '" << n << "' is not a parameter/variable", pos);
|
2014-10-03 14:23:24 +00:00
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
2014-11-01 18:18:10 +00:00
|
|
|
static environment include_cmd(parser & p) {
|
2014-10-03 14:23:24 +00:00
|
|
|
return include_cmd_core(p, true);
|
|
|
|
}
|
|
|
|
|
2014-11-01 18:18:10 +00:00
|
|
|
static environment omit_cmd(parser & p) {
|
2014-10-03 14:23:24 +00:00
|
|
|
return include_cmd_core(p, false);
|
|
|
|
}
|
|
|
|
|
2014-06-18 17:36:21 +00:00
|
|
|
void register_decl_cmds(cmd_table & r) {
|
2014-10-10 15:45:59 +00:00
|
|
|
add_cmd(r, cmd_info("universe", "declare a universe level", universe_cmd));
|
|
|
|
add_cmd(r, cmd_info("universes", "declare universe levels", universes_cmd));
|
2014-10-02 23:20:52 +00:00
|
|
|
add_cmd(r, cmd_info("variable", "declare a new variable", variable_cmd));
|
|
|
|
add_cmd(r, cmd_info("parameter", "declare a new parameter", parameter_cmd));
|
|
|
|
add_cmd(r, cmd_info("constant", "declare a new constant (aka top-level variable)", constant_cmd));
|
2014-06-18 17:36:21 +00:00
|
|
|
add_cmd(r, cmd_info("axiom", "declare a new axiom", axiom_cmd));
|
2014-10-02 23:20:52 +00:00
|
|
|
add_cmd(r, cmd_info("variables", "declare new variables", variables_cmd));
|
|
|
|
add_cmd(r, cmd_info("parameters", "declare new parameters", parameters_cmd));
|
|
|
|
add_cmd(r, cmd_info("constants", "declare new constants (aka top-level variables)", constants_cmd));
|
2014-06-18 17:36:21 +00:00
|
|
|
add_cmd(r, cmd_info("definition", "add new definition", definition_cmd));
|
2014-11-01 18:35:38 +00:00
|
|
|
add_cmd(r, cmd_info("example", "add new example", example_cmd));
|
2014-09-19 20:44:44 +00:00
|
|
|
add_cmd(r, cmd_info("opaque", "add new opaque definition", opaque_definition_cmd));
|
2014-09-19 21:30:02 +00:00
|
|
|
add_cmd(r, cmd_info("private", "add new private definition/theorem", private_definition_cmd));
|
2014-09-19 22:04:52 +00:00
|
|
|
add_cmd(r, cmd_info("protected", "add new protected definition/theorem", protected_definition_cmd));
|
2014-06-18 17:36:21 +00:00
|
|
|
add_cmd(r, cmd_info("theorem", "add new theorem", theorem_cmd));
|
2014-10-03 14:23:24 +00:00
|
|
|
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));
|
2014-06-18 17:36:21 +00:00
|
|
|
}
|
|
|
|
}
|