feat(frontends/lean): add 'override' (notation) command
This commit is contained in:
parent
90ea4995f4
commit
af3f0088f4
8 changed files with 63 additions and 19 deletions
|
@ -12,7 +12,7 @@
|
|||
"hiding" "exposing" "parameter" "parameters" "begin" "begin+" "proof" "qed" "conjecture" "constant" "constants"
|
||||
"hypothesis" "lemma" "corollary" "variable" "variables" "premise" "premises"
|
||||
"print" "theorem" "example" "abbreviation"
|
||||
"open" "as" "export" "axiom" "axioms" "inductive" "with" "structure" "record" "universe" "universes"
|
||||
"open" "as" "export" "override" "axiom" "axioms" "inductive" "with" "structure" "record" "universe" "universes"
|
||||
"alias" "help" "environment" "options" "precedence" "reserve"
|
||||
"match" "infix" "infixl" "infixr" "notation" "postfix" "prefix"
|
||||
"tactic_infix" "tactic_infixl" "tactic_infixr" "tactic_notation" "tactic_postfix" "tactic_prefix"
|
||||
|
|
|
@ -690,11 +690,11 @@ environment open_export_cmd(parser & p, bool open) {
|
|||
fingerprint = hash(fingerprint, n.hash());
|
||||
auto pos = p.pos();
|
||||
name ns = p.check_id_next("invalid 'open/export' command, identifier expected");
|
||||
fingerprint = hash(fingerprint, ns.hash());
|
||||
optional<name> real_ns = to_valid_namespace_name(env, ns);
|
||||
if (!real_ns)
|
||||
throw parser_error(sstream() << "invalid namespace name '" << ns << "'", pos);
|
||||
ns = *real_ns;
|
||||
fingerprint = hash(fingerprint, ns.hash());
|
||||
name as;
|
||||
if (p.curr_is_token_or_id(get_as_tk())) {
|
||||
p.next();
|
||||
|
@ -778,16 +778,32 @@ environment open_export_cmd(parser & p, bool open) {
|
|||
}
|
||||
return update_fingerprint(env, fingerprint);
|
||||
}
|
||||
environment open_cmd(parser & p) { return open_export_cmd(p, true); }
|
||||
environment export_cmd(parser & p) { return open_export_cmd(p, false); }
|
||||
static environment open_cmd(parser & p) { return open_export_cmd(p, true); }
|
||||
static environment export_cmd(parser & p) { return open_export_cmd(p, false); }
|
||||
|
||||
environment erase_cache_cmd(parser & p) {
|
||||
static environment override_cmd(parser & p) {
|
||||
environment env = p.env();
|
||||
while (p.curr_is_identifier()) {
|
||||
auto pos = p.pos();
|
||||
name ns = p.check_id_next("invalid 'override' command, identifier expected");
|
||||
optional<name> real_ns = to_valid_namespace_name(env, ns);
|
||||
if (!real_ns)
|
||||
throw parser_error(sstream() << "invalid namespace name '" << ns << "'", pos);
|
||||
ns = *real_ns;
|
||||
bool persistent = false;
|
||||
env = override_notation(env, ns, persistent);
|
||||
env = update_fingerprint(env, ns.hash());
|
||||
}
|
||||
return env;
|
||||
}
|
||||
|
||||
static environment erase_cache_cmd(parser & p) {
|
||||
name n = p.check_id_next("invalid #erase_cache command, identifier expected");
|
||||
p.erase_cached_definition(n);
|
||||
return p.env();
|
||||
}
|
||||
|
||||
environment projections_cmd(parser & p) {
|
||||
static environment projections_cmd(parser & p) {
|
||||
name n = p.check_id_next("invalid #projections command, identifier expected");
|
||||
if (p.curr_is_token(get_dcolon_tk())) {
|
||||
p.next();
|
||||
|
@ -802,7 +818,7 @@ environment projections_cmd(parser & p) {
|
|||
}
|
||||
}
|
||||
|
||||
environment telescope_eq_cmd(parser & p) {
|
||||
static environment telescope_eq_cmd(parser & p) {
|
||||
expr e; level_param_names ls;
|
||||
std::tie(e, ls) = parse_local_expr(p);
|
||||
buffer<expr> t;
|
||||
|
@ -821,7 +837,7 @@ environment telescope_eq_cmd(parser & p) {
|
|||
return p.env();
|
||||
}
|
||||
|
||||
environment local_cmd(parser & p) {
|
||||
static environment local_cmd(parser & p) {
|
||||
if (p.curr_is_token_or_id(get_attribute_tk())) {
|
||||
p.next();
|
||||
return local_attribute_cmd(p);
|
||||
|
@ -867,13 +883,13 @@ static environment help_cmd(parser & p) {
|
|||
return p.env();
|
||||
}
|
||||
|
||||
environment init_quotient_cmd(parser & p) {
|
||||
static environment init_quotient_cmd(parser & p) {
|
||||
if (!(p.env().prop_proof_irrel() && p.env().impredicative()))
|
||||
throw parser_error("invalid init_quotient command, this command is only available for kernels containing an impredicative and proof irrelevant Prop", p.cmd_pos());
|
||||
return module::declare_quotient(p.env());
|
||||
}
|
||||
|
||||
environment init_hits_cmd(parser & p) {
|
||||
static environment init_hits_cmd(parser & p) {
|
||||
if (p.env().prop_proof_irrel() || p.env().impredicative())
|
||||
throw parser_error("invalid init_hits command, this command is only available for proof relevant and predicative kernels", p.cmd_pos());
|
||||
return module::declare_hits(p.env());
|
||||
|
@ -884,6 +900,8 @@ void init_cmd_table(cmd_table & r) {
|
|||
open_cmd));
|
||||
add_cmd(r, cmd_info("export", "create abbreviations for declarations, "
|
||||
"and export objects defined in other namespaces", export_cmd));
|
||||
add_cmd(r, cmd_info("override", "override notation declarations using the ones defined in the given namespace",
|
||||
override_cmd));
|
||||
add_cmd(r, cmd_info("set_option", "set configuration option", set_option_cmd));
|
||||
add_cmd(r, cmd_info("exit", "exit", exit_cmd));
|
||||
add_cmd(r, cmd_info("print", "print a string", print_cmd));
|
||||
|
|
|
@ -559,9 +559,10 @@ static expr parse_calc_expr(parser & p, unsigned, expr const *, pos_info const &
|
|||
return parse_calc(p);
|
||||
}
|
||||
|
||||
static expr parse_overwrite_notation(parser & p, unsigned, expr const *, pos_info const &) {
|
||||
static expr parse_override_notation(parser & p, unsigned, expr const *, pos_info const &) {
|
||||
name n = p.check_id_next("invalid '#' local notation, identifier expected");
|
||||
environment env = overwrite_notation(p.env(), n);
|
||||
bool persistent = false;
|
||||
environment env = override_notation(p.env(), n, persistent);
|
||||
return p.parse_expr_with_env(env);
|
||||
}
|
||||
|
||||
|
@ -630,7 +631,7 @@ parse_table init_nud_table() {
|
|||
r = r.add({transition("Type", mk_ext_action(parse_Type))}, x0);
|
||||
r = r.add({transition("let", mk_ext_action(parse_let_expr))}, x0);
|
||||
r = r.add({transition("calc", mk_ext_action(parse_calc_expr))}, x0);
|
||||
r = r.add({transition("#", mk_ext_action(parse_overwrite_notation))}, x0);
|
||||
r = r.add({transition("#", mk_ext_action(parse_override_notation))}, x0);
|
||||
r = r.add({transition("@", mk_ext_action(parse_explicit_expr))}, x0);
|
||||
r = r.add({transition("!", mk_ext_action(parse_consume_args_expr))}, x0);
|
||||
r = r.add({transition("begin", mk_ext_action_core(parse_begin_end))}, x0);
|
||||
|
|
|
@ -411,20 +411,20 @@ list<notation_entry> get_notation_entries(environment const & env, head_index co
|
|||
return list<notation_entry>();
|
||||
}
|
||||
|
||||
environment overwrite_notation(environment const & env, name const & n) {
|
||||
environment override_notation(environment const & env, name const & n, bool persistent) {
|
||||
environment r = env;
|
||||
bool found = false;
|
||||
if (auto it = token_ext::get_entries(r, n)) {
|
||||
found = true;
|
||||
for (token_entry e : *it) {
|
||||
r = add_token(r, e);
|
||||
r = add_token(r, e, persistent);
|
||||
}
|
||||
}
|
||||
if (auto it = notation_ext::get_entries(env, n)) {
|
||||
found = true;
|
||||
for (notation_entry const & e : *it) {
|
||||
notation_entry new_e(e, false);
|
||||
r = add_notation(r, new_e);
|
||||
r = add_notation(r, new_e, persistent);
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
|
|
|
@ -85,7 +85,7 @@ parse_table const & get_tactic_nud_table(environment const & env);
|
|||
parse_table const & get_tactic_led_table(environment const & env);
|
||||
cmd_table const & get_cmd_table(environment const & env);
|
||||
/** \brief Force notation from namespace \c n to shadow any existing notation */
|
||||
environment overwrite_notation(environment const & env, name const & n);
|
||||
environment override_notation(environment const & env, name const & n, bool persistent = true);
|
||||
|
||||
/** \brief Add \c n as notation for \c e */
|
||||
environment add_mpz_notation(environment const & env, mpz const & n, expr const & e, bool overload = true, bool parse_only = false);
|
||||
|
|
|
@ -114,7 +114,7 @@ void init_token_table(token_table & t) {
|
|||
"import", "inductive", "record", "structure", "module", "universe", "universes", "local",
|
||||
"precedence", "reserve", "infixl", "infixr", "infix", "postfix", "prefix", "notation",
|
||||
"tactic_infixl", "tactic_infixr", "tactic_infix", "tactic_postfix", "tactic_prefix", "tactic_notation",
|
||||
"exit", "set_option", "open", "export", "calc_subst", "calc_refl", "calc_trans", "calc_symm", "tactic_hint",
|
||||
"exit", "set_option", "open", "export", "override", "calc_subst", "calc_refl", "calc_trans", "calc_symm", "tactic_hint",
|
||||
"add_begin_end_tactic", "set_begin_end_tactic", "instance", "class",
|
||||
"multiple_instances", "find_decl", "attribute", "persistent",
|
||||
"include", "omit", "migrate", "init_quotient", "init_hits", "#erase_cache", "#projections", "#telescope_eq",
|
||||
|
|
|
@ -409,7 +409,8 @@ name get_decl_short_name(name const & d, environment const & env) {
|
|||
environment open_num_notation(environment const & env) {
|
||||
name num("num");
|
||||
try {
|
||||
environment new_env = overwrite_notation(env, num);
|
||||
bool persistent = false;
|
||||
environment new_env = override_notation(env, num, persistent);
|
||||
return overwrite_aliases(new_env, num, name());
|
||||
} catch (exception &) {
|
||||
// num namespace is not available, then use only the aliases
|
||||
|
|
24
tests/lean/run/override1.lean
Normal file
24
tests/lean/run/override1.lean
Normal file
|
@ -0,0 +1,24 @@
|
|||
import data.finset data.set
|
||||
|
||||
open set
|
||||
|
||||
example (A : Type) (x : A) (S H : set A) (Pin : x ∈ S)
|
||||
(Psub : S ⊆ H) : x ∈ H := Psub Pin
|
||||
|
||||
open finset
|
||||
|
||||
section
|
||||
override set -- set notation overrides existing one
|
||||
|
||||
example (A : Type) (x : A) (S H : set A) (Pin : x ∈ S)
|
||||
(Psub : S ⊆ H) : x ∈ H := Psub Pin
|
||||
end
|
||||
|
||||
-- ⊆ is now overloaded
|
||||
example (A : Type) (x : A) (S H : set A) (Pin : x ∈ S)
|
||||
(Psub : S ⊆ H) : x ∈ H := Psub _ Pin
|
||||
|
||||
|
||||
override set -- overrides existing notation
|
||||
|
||||
example (A : Type) (x : A) (S H : set A) (Pin : x ∈ S) (Psub : S ⊆ H) : x ∈ H := Psub Pin
|
Loading…
Reference in a new issue