fixup! also allow shadowing non-constructor definitions

This commit is contained in:
Sebastian Ullrich 2016-06-14 00:23:21 -04:00 committed by Leonardo de Moura
parent d7789fa58a
commit e9a6a532ab
5 changed files with 45 additions and 26 deletions

View file

@ -258,8 +258,8 @@ definition rotl : ∀ {n : nat} m : nat, fin n → fin n
| (succ n) := take m, madd (mk_mod n (n*m))
definition rotr : ∀ {n : nat} m : nat, fin n → fin n
| (0:nat) := take m i, elim0 i
| (nat.succ n) := take m, madd (-(mk_mod n (n*m)))
| 0 := take m i, elim0 i
| (succ n) := take m, madd (-(mk_mod n (n*m)))
lemma rotl_succ' {n m : nat} : rotl m = madd (mk_mod n (n*m)) := rfl

View file

@ -441,13 +441,8 @@ static bool is_curr_with_or_comma_or_bar(parser & p) {
}
/**
For convenience, the left-hand-side of a recursive equation may contain
undeclared variables.
We use parser::undef_id_to_local_scope to force the parser to create a local constant for
each undefined identifier.
This method validates occurrences of these variables. They can only occur as an application
or macro argument.
This method validates occurrences of local variables (i.e., variables bound in the pattern).
They can only occur as an application or macro argument.
*/
static void validate_equation_lhs(parser const & p, expr const & lhs, buffer<expr> const & locals) {
if (is_app(lhs)) {

View file

@ -18,6 +18,7 @@ Author: Leonardo de Moura
#include "kernel/replace_fn.h"
#include "kernel/abstract.h"
#include "kernel/instantiate.h"
#include "kernel/inductive/inductive.h"
#include "kernel/error_msgs.h"
#include "library/trace.h"
#include "library/parser_nested_exception.h"
@ -108,7 +109,7 @@ parser::undef_id_to_const_scope::undef_id_to_const_scope(parser & p):
parser::undef_id_to_local_scope::undef_id_to_local_scope(parser & p):
flet<undef_id_behavior>(p.m_undef_id_behavior, undef_id_behavior::AssumeLocal) {}
parser::local_and_undef_id_to_local_scope::local_and_undef_id_to_local_scope(parser & p):
flet<undef_id_behavior>(p.m_undef_id_behavior, undef_id_behavior::AssumeLocalAndAlsoDefinedLocals) {}
flet<undef_id_behavior>(p.m_undef_id_behavior, undef_id_behavior::AssumeLocalAndAlsoDefinedNonConstructors) {}
static name * g_tmp_prefix = nullptr;
@ -1459,6 +1460,13 @@ expr parser::parse_led_notation(expr left) {
}
}
expr parser::mk_placeholder_local(name const & id, pos_info const & p) {
expr local = mk_local(id, mk_expr_placeholder());
m_undef_ids.push_back(local);
save_identifier_info(p, local_pp_name(local));
return save_pos(local, p);
}
expr parser::id_to_expr(name const & id, pos_info const & p) {
buffer<level> lvl_buffer;
levels ls;
@ -1476,11 +1484,8 @@ expr parser::id_to_expr(name const & id, pos_info const & p) {
if (ls && m_undef_id_behavior != undef_id_behavior::AssumeConstant)
throw parser_error("invalid use of explicit universe parameter, identifier is a variable, "
"parameter or a constant bound to parameters in a section", p);
if (m_undef_id_behavior == undef_id_behavior::AssumeLocalAndAlsoDefinedLocals) {
expr local = mk_local(id, mk_expr_placeholder());
m_undef_ids.push_back(local);
return save_pos(local, p);
}
if (m_undef_id_behavior == undef_id_behavior::AssumeLocalAndAlsoDefinedNonConstructors)
return mk_placeholder_local(id, p);
auto r = copy_with_new_pos(*it1, p);
save_type_info(r);
save_identifier_info(p, id);
@ -1491,6 +1496,10 @@ expr parser::id_to_expr(name const & id, pos_info const & p) {
auto new_id = ns + id;
if (!ns.is_anonymous() && m_env.find(new_id) &&
(!id.is_atomic() || !is_protected(m_env, new_id))) {
if (m_undef_id_behavior == undef_id_behavior::AssumeLocalAndAlsoDefinedNonConstructors &&
id.is_atomic() && !inductive::is_intro_rule(m_env, new_id)) {
return mk_placeholder_local(id, p);
}
auto r = save_pos(mk_constant(new_id, ls), p);
save_type_info(r);
add_ref_index(new_id, p);
@ -1513,27 +1522,42 @@ expr parser::id_to_expr(name const & id, pos_info const & p) {
optional<expr> r;
// globals
if (m_env.find(id))
if (m_env.find(id)) {
if (m_undef_id_behavior == undef_id_behavior::AssumeLocalAndAlsoDefinedNonConstructors && id.is_atomic()) {
bool has_constructor = false;
for (auto & c : to_constants(id, "", p)) {
if (inductive::is_intro_rule(m_env, c))
has_constructor = true;
}
if (!has_constructor)
return mk_placeholder_local(id, p);
}
r = save_pos(mk_constant(id, ls), p);
}
// aliases
auto as = get_expr_aliases(m_env, id);
if (!is_nil(as)) {
buffer<expr> new_as;
if (r)
new_as.push_back(*r);
bool has_constructor = false;
for (auto const & e : as) {
has_constructor |= (bool)inductive::is_intro_rule(m_env, e);
new_as.push_back(copy_with_new_pos(mk_constant(e, ls), p));
}
if (m_undef_id_behavior == undef_id_behavior::AssumeLocalAndAlsoDefinedNonConstructors &&
id.is_atomic() && !has_constructor) {
return mk_placeholder_local(id, p);
}
r = save_pos(mk_choice(new_as.size(), new_as.data()), p);
save_overload(*r);
}
if (!r) {
if (m_undef_id_behavior == undef_id_behavior::AssumeConstant) {
r = save_pos(mk_constant(get_namespace(m_env) + id, ls), p);
} else if (m_undef_id_behavior == undef_id_behavior::AssumeLocal || m_undef_id_behavior == undef_id_behavior::AssumeLocalAndAlsoDefinedLocals) {
expr local = mk_local(id, mk_expr_placeholder());
m_undef_ids.push_back(local);
r = save_pos(local, p);
} else if (m_undef_id_behavior == undef_id_behavior::AssumeLocal ||
m_undef_id_behavior == undef_id_behavior::AssumeLocalAndAlsoDefinedNonConstructors) {
return mk_placeholder_local(id, p);
}
}
if (!r)
@ -1542,8 +1566,6 @@ expr parser::id_to_expr(name const & id, pos_info const & p) {
if (is_constant(*r)) {
add_ref_index(const_name(*r), p);
save_identifier_info(p, const_name(*r));
} else if (is_local(*r)) {
save_identifier_info(p, local_pp_name(*r));
}
return *r;
}

View file

@ -83,7 +83,7 @@ typedef std::vector<snapshot> snapshot_vector;
enum class keep_theorem_mode { All, DiscardImported, DiscardAll };
enum class undef_id_behavior { Error, AssumeConstant, AssumeLocal, AssumeLocalAndAlsoDefinedLocals };
enum class undef_id_behavior { Error, AssumeConstant, AssumeLocal, AssumeLocalAndAlsoDefinedNonConstructors };
class parser {
environment m_env;
@ -533,6 +533,8 @@ public:
public:
in_notation_ctx(parser & p):m_ctx(p.m_scanner) {}
};
expr mk_placeholder_local(const name &id, const pos_info &p);
};
bool parse_commands(environment & env, io_state & ios, std::istream & in, char const * strm_name, optional<std::string> const & base_dir,

View file

@ -27,9 +27,9 @@ infix `+` := expr.add
set_option pp.notation false
definition ev : expr → nat
| zero := 0
| one := 1
| ((a : expr) + b) := ev a + ev b
| zero := 0
| one := 1
| (a + b) := ev a + ev b
definition foo : expr := add zero (add one one)