fix(frontends/lean/elaborator): bug when mixing implicit arguments and sections

Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
Leonardo de Moura 2014-07-19 09:55:34 +01:00
parent e817260c6d
commit 6b60db7b93
6 changed files with 52 additions and 16 deletions

View file

@ -258,7 +258,7 @@ environment definition_cmd_core(parser & p, bool is_theorem, bool _is_opaque) {
type = Pi_as_is(section_ps, type, p);
value = Fun_as_is(section_ps, value, p);
levels section_ls = collect_section_levels(ls, p);
expr ref = mk_app(mk_explicit(mk_constant(real_n, section_ls)), section_ps);
expr ref = mk_implicit(mk_app(mk_explicit(mk_constant(real_n, section_ls)), section_ps));
p.add_local_expr(n, ref);
}
level_param_names new_ls;

View file

@ -948,7 +948,13 @@ public:
} else if (is_explicit(get_app_fn(e))) {
r = visit_core(e);
} else {
r = visit_core(e);
if (is_implicit(e)) {
r = get_implicit_arg(e);
if (is_explicit(r)) r = get_explicit_arg(r);
r = visit_core(r);
} else {
r = visit_core(e);
}
if (!is_lambda(r)) {
tag g = e.get_tag();
expr r_type = whnf(infer_type(r));

View file

@ -10,6 +10,7 @@ Author: Leonardo de Moura
namespace lean {
static name g_explicit_name("@");
static name g_implicit_name("@^-1");
static name g_as_is_name("as_is");
[[ noreturn ]] static void throw_ex(name const & n) { throw exception(sstream() << "unexpected occurrence of '" << n << "' expression"); }
@ -26,20 +27,22 @@ public:
virtual void write(serializer &) const { throw_ex(get_name()); }
};
class as_is_macro_cell : public explicit_macro_cell {
public:
virtual name get_name() const { return g_as_is_name; }
};
struct as_is_macro_cell : public explicit_macro_cell { virtual name get_name() const { return g_as_is_name; } };
struct implicit_macro_cell : public explicit_macro_cell { virtual name get_name() const { return g_implicit_name; } };
static macro_definition g_explicit(new explicit_macro_cell());
static macro_definition g_as_is(new as_is_macro_cell());
static macro_definition g_implicit(new implicit_macro_cell());
expr mk_explicit(expr const & e) { return mk_macro(g_explicit, 1, &e); }
bool is_explicit(expr const & e) { return is_macro(e) && macro_def(e) == g_explicit; }
expr mk_as_is(expr const & e) { return mk_macro(g_as_is, 1, &e); }
bool is_as_is(expr const & e) { return is_macro(e) && macro_def(e) == g_as_is; }
expr mk_implicit(expr const & e) { return mk_macro(g_implicit, 1, &e); }
bool is_implicit(expr const & e) { return is_macro(e) && macro_def(e) == g_implicit; }
expr const & get_explicit_arg(expr const & e) { lean_assert(is_explicit(e)); return macro_arg(e, 0); }
expr const & get_as_is_arg(expr const & e) { lean_assert(is_as_is(e)); return macro_arg(e, 0); }
expr const & get_implicit_arg(expr const & e) { lean_assert(is_implicit(e)); return macro_arg(e, 0); }
static int mk_explicit(lua_State * L) { return push_expr(L, mk_explicit(to_expr(L, 1))); }
static int is_explicit(lua_State * L) { return push_boolean(L, is_explicit(to_expr(L, 1))); }

View file

@ -9,29 +9,35 @@ Author: Leonardo de Moura
#include "kernel/expr.h"
namespace lean {
/**
\brief Create an explicit expression '@ f'.
/** \brief Create an explicit expression '@ f'.
This only affects the elaborator behavior.
*/
expr mk_explicit(expr const & e);
/** \brief Return true iff \c e is an explicit expression. */
bool is_explicit(expr const & e);
/**
\brief Create an explicit expression that is accepted as is
/** \brief Create an explicit expression that is accepted as is
by the elaborator.
*/
expr mk_as_is(expr const & e);
/** \brief Return true iff \c e was created with mk_as_is. */
bool is_as_is(expr const & e);
/**
\brief Return the argument of an explicit expression.
\pre is_explicit(e)
/** \brief Create an implicit expression '@^-1 f'.
This only affects the elaborator behavior. This expression "cancels" the effect of '@'
*/
expr mk_implicit(expr const & e);
/** \brief Return true iff \c e is an implicit expression. */
bool is_implicit(expr const & e);
/** \brief Return the argument of an explicit expression.
\pre is_explicit(e)
*/
expr const & get_explicit_arg(expr const & e);
/**
\brief Return the argument of an expression created using mk_as_is.
\pre is_as_is(e)
/** \brief Return the argument of an expression created using mk_as_is.
\pre is_as_is(e)
*/
expr const & get_as_is_arg(expr const & e);
/** \brief Return the argument of an implicit expression.
\pre is_implicit(e)
*/
expr const & get_implicit_arg(expr const & e);
void open_explicit(lua_State * L);
}

20
tests/lean/run/bug6.lean Normal file
View file

@ -0,0 +1,20 @@
import standard
section
parameter {A : Type}
theorem T {a b : A} (H : a = b) : b = a
:= symm H
variables x y : A
axiom H : x = y
check T H
check T
end
section
parameter {A : Type}
theorem T2 ⦃a b : A⦄ (H : a = b) : b = a
:= symm H
variables x y : A
axiom H : x = y
check T2 H
check T2
end

View file

@ -35,6 +35,7 @@ section
definition add_in (a : int) (b : nat) := a + (of_nat b)
infixl + := add_ni
infixl + := add_in
check add_ni
check i + n
check n + i