feat(frontends/lean/decl_cmds): allow local coercions in contexts

closes #525
This commit is contained in:
Leonardo de Moura 2015-04-04 15:16:34 -07:00
parent 8c59f17605
commit d591c63840
2 changed files with 36 additions and 18 deletions

View file

@ -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;
} }

View 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