feat(frontends/lean/decl_cmds): allow local coercions in contexts
closes #525
This commit is contained in:
parent
8c59f17605
commit
d591c63840
2 changed files with 36 additions and 18 deletions
|
@ -290,6 +290,7 @@ static environment constants_cmd(parser & p) {
|
||||||
struct decl_attributes {
|
struct decl_attributes {
|
||||||
bool m_def_only; // if true only definition attributes are allowed
|
bool m_def_only; // if true only definition attributes are allowed
|
||||||
bool m_is_abbrev; // if true only abbreviation attributes are allowed
|
bool m_is_abbrev; // if true only abbreviation attributes are allowed
|
||||||
|
bool m_persistent;
|
||||||
bool m_is_instance;
|
bool m_is_instance;
|
||||||
bool m_is_coercion;
|
bool m_is_coercion;
|
||||||
bool m_is_reducible;
|
bool m_is_reducible;
|
||||||
|
@ -302,10 +303,11 @@ struct decl_attributes {
|
||||||
optional<unsigned> m_priority;
|
optional<unsigned> m_priority;
|
||||||
optional<unsigned> m_unfold_c_hint;
|
optional<unsigned> m_unfold_c_hint;
|
||||||
|
|
||||||
decl_attributes(bool def_only = true, bool is_abbrev = false):
|
decl_attributes(bool def_only = true, bool is_abbrev = false, bool persistent = true):
|
||||||
m_priority() {
|
m_priority() {
|
||||||
m_def_only = def_only;
|
m_def_only = def_only;
|
||||||
m_is_abbrev = is_abbrev;
|
m_is_abbrev = is_abbrev;
|
||||||
|
m_persistent = persistent;
|
||||||
m_is_instance = false;
|
m_is_instance = false;
|
||||||
m_is_coercion = false;
|
m_is_coercion = false;
|
||||||
m_is_reducible = is_abbrev;
|
m_is_reducible = is_abbrev;
|
||||||
|
@ -366,8 +368,8 @@ struct decl_attributes {
|
||||||
} else if (p.curr_is_token(get_coercion_tk())) {
|
} else if (p.curr_is_token(get_coercion_tk())) {
|
||||||
auto pos = p.pos();
|
auto pos = p.pos();
|
||||||
p.next();
|
p.next();
|
||||||
if (in_context(p.env()))
|
if (in_context(p.env()) && m_persistent)
|
||||||
throw parser_error("invalid '[coercion]' attribute, coercions cannot be defined in contexts", pos);
|
throw parser_error("invalid '[coercion]' attribute, (non local) coercions cannot be defined in contexts", pos);
|
||||||
m_is_coercion = true;
|
m_is_coercion = true;
|
||||||
} else if (p.curr_is_token(get_reducible_tk())) {
|
} else if (p.curr_is_token(get_reducible_tk())) {
|
||||||
if (m_is_irreducible || m_is_semireducible || m_is_quasireducible)
|
if (m_is_irreducible || m_is_semireducible || m_is_quasireducible)
|
||||||
|
@ -443,36 +445,36 @@ struct decl_attributes {
|
||||||
parse(ns, p);
|
parse(ns, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
environment apply(environment env, io_state const & ios, name const & d, bool persistent) {
|
environment apply(environment env, io_state const & ios, name const & d) {
|
||||||
if (m_is_instance) {
|
if (m_is_instance) {
|
||||||
if (m_priority) {
|
if (m_priority) {
|
||||||
#if defined(__GNUC__) && !defined(__CLANG__)
|
#if defined(__GNUC__) && !defined(__CLANG__)
|
||||||
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
|
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
|
||||||
#endif
|
#endif
|
||||||
env = add_instance(env, d, *m_priority, persistent);
|
env = add_instance(env, d, *m_priority, m_persistent);
|
||||||
} else {
|
} else {
|
||||||
env = add_instance(env, d, persistent);
|
env = add_instance(env, d, m_persistent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (m_is_coercion)
|
if (m_is_coercion)
|
||||||
env = add_coercion(env, d, ios, persistent);
|
env = add_coercion(env, d, ios, m_persistent);
|
||||||
auto decl = env.find(d);
|
auto decl = env.find(d);
|
||||||
if (decl && decl->is_definition()) {
|
if (decl && decl->is_definition()) {
|
||||||
if (m_is_reducible)
|
if (m_is_reducible)
|
||||||
env = set_reducible(env, d, reducible_status::Reducible, persistent);
|
env = set_reducible(env, d, reducible_status::Reducible, m_persistent);
|
||||||
if (m_is_irreducible)
|
if (m_is_irreducible)
|
||||||
env = set_reducible(env, d, reducible_status::Irreducible, persistent);
|
env = set_reducible(env, d, reducible_status::Irreducible, m_persistent);
|
||||||
if (m_is_semireducible)
|
if (m_is_semireducible)
|
||||||
env = set_reducible(env, d, reducible_status::Semireducible, persistent);
|
env = set_reducible(env, d, reducible_status::Semireducible, m_persistent);
|
||||||
if (m_is_quasireducible)
|
if (m_is_quasireducible)
|
||||||
env = set_reducible(env, d, reducible_status::Quasireducible, persistent);
|
env = set_reducible(env, d, reducible_status::Quasireducible, m_persistent);
|
||||||
if (m_unfold_c_hint)
|
if (m_unfold_c_hint)
|
||||||
env = add_unfold_c_hint(env, d, m_unfold_c_hint, persistent);
|
env = add_unfold_c_hint(env, d, m_unfold_c_hint, m_persistent);
|
||||||
}
|
}
|
||||||
if (m_is_class)
|
if (m_is_class)
|
||||||
env = add_class(env, d, persistent);
|
env = add_class(env, d, m_persistent);
|
||||||
if (m_has_multiple_instances)
|
if (m_has_multiple_instances)
|
||||||
env = mark_multiple_instances(env, d, persistent);
|
env = mark_multiple_instances(env, d, m_persistent);
|
||||||
return env;
|
return env;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -995,8 +997,7 @@ class definition_cmd_fn {
|
||||||
bool persistent = m_kind == Abbreviation;
|
bool persistent = m_kind == Abbreviation;
|
||||||
m_env = add_abbreviation(m_env, real_n, m_attributes.m_is_parsing_only, persistent);
|
m_env = add_abbreviation(m_env, real_n, m_attributes.m_is_parsing_only, persistent);
|
||||||
}
|
}
|
||||||
bool persistent = true;
|
m_env = m_attributes.apply(m_env, m_p.ios(), real_n);
|
||||||
m_env = m_attributes.apply(m_env, m_p.ios(), real_n, persistent);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1303,11 +1304,12 @@ static environment attribute_cmd_core(parser & p, bool persistent) {
|
||||||
ds.push_back(p.check_constant_next("invalid 'attribute' command, constant expected"));
|
ds.push_back(p.check_constant_next("invalid 'attribute' command, constant expected"));
|
||||||
}
|
}
|
||||||
bool decl_only = false;
|
bool decl_only = false;
|
||||||
decl_attributes attributes(decl_only);
|
bool abbrev = false;
|
||||||
|
decl_attributes attributes(decl_only, abbrev, persistent);
|
||||||
attributes.parse(ds, p);
|
attributes.parse(ds, p);
|
||||||
environment env = p.env();
|
environment env = p.env();
|
||||||
for (name const & d : ds)
|
for (name const & d : ds)
|
||||||
env = attributes.apply(env, p.ios(), d, persistent);
|
env = attributes.apply(env, p.ios(), d);
|
||||||
return env;
|
return env;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
16
tests/lean/run/localcoe.lean
Normal file
16
tests/lean/run/localcoe.lean
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
open nat
|
||||||
|
|
||||||
|
context
|
||||||
|
inductive NatA :=
|
||||||
|
| a : NatA
|
||||||
|
| s : NatA → NatA
|
||||||
|
|
||||||
|
open NatA
|
||||||
|
|
||||||
|
definition foo (n : nat) : NatA :=
|
||||||
|
nat.rec_on n a (λ n' r, s r)
|
||||||
|
|
||||||
|
local attribute foo [coercion]
|
||||||
|
|
||||||
|
check s 10
|
||||||
|
end
|
Loading…
Reference in a new issue