fix(frontends/lean/pp): abbreviation with parameters

closes #639
This commit is contained in:
Leonardo de Moura 2015-05-29 15:08:49 -07:00
parent a071012346
commit f48cdccd20
8 changed files with 83 additions and 20 deletions

View file

@ -532,6 +532,8 @@ optional<name> pretty_fn::is_abbreviated(expr const & e) const {
}
auto pretty_fn::pp_const(expr const & e, optional<unsigned> const & num_ref_univ_params) -> result {
if (auto it = is_abbreviated(e))
return pp_abbreviation(e, *it, false);
if (!num_ref_univ_params) {
if (auto r = pp_local_ref(e))
return *r;

View file

@ -12,6 +12,7 @@ Author: Leonardo de Moura
#include "library/scoped_ext.h"
#include "library/expr_lt.h"
#include "library/util.h"
#include "library/normalize.h"
namespace lean {
typedef pair<name, bool> abbrev_entry;
@ -26,7 +27,8 @@ struct abbrev_state {
throw exception(sstream() << "invalid abbreviation '" << n << "', it is not a definition");
m_abbrevs.insert(n, parsing_only);
if (!parsing_only) {
m_inv_map.insert(d.get_value(), n);
expr v = try_eta(d.get_value());
m_inv_map.insert(v, n);
}
}

View file

@ -164,6 +164,28 @@ void finalize_normalize() {
delete g_key;
}
expr try_eta(expr const & e) {
if (is_lambda(e)) {
expr const & b = binding_body(e);
if (is_lambda(b)) {
expr new_b = try_eta(b);
if (is_eqp(b, new_b)) {
return e;
} else if (is_app(new_b) && is_var(app_arg(new_b), 0) && !has_free_var(app_fn(new_b), 0)) {
return lower_free_vars(app_fn(new_b), 1);
} else {
return update_binding(e, binding_domain(e), new_b);
}
} else if (is_app(b) && is_var(app_arg(b), 0) && !has_free_var(app_fn(b), 0)) {
return lower_free_vars(app_fn(b), 1);
} else {
return e;
}
} else {
return e;
}
}
class normalize_fn {
type_checker & m_tc;
name_generator m_ngen;
@ -267,25 +289,6 @@ class normalize_fn {
}
}
expr try_eta(expr const & e) {
lean_assert(is_lambda(e));
expr const & b = binding_body(e);
if (is_lambda(b)) {
expr new_b = try_eta(b);
if (is_eqp(b, new_b)) {
return e;
} else if (is_app(new_b) && is_var(app_arg(new_b), 0) && !has_free_var(app_fn(new_b), 0)) {
return lower_free_vars(app_fn(new_b), 1);
} else {
return update_binding(e, binding_domain(e), new_b);
}
} else if (is_app(b) && is_var(app_arg(b), 0) && !has_free_var(app_fn(b), 0)) {
return lower_free_vars(app_fn(b), 1);
} else {
return e;
}
}
expr normalize(expr e) {
check_system("normalize");
if (!m_pred(e))

View file

@ -60,6 +60,8 @@ environment erase_constructor_hint(environment const & env, name const & n, bool
/** \brief Retrieve the hint added with the procedure add_constructor_hint. */
optional<unsigned> has_constructor_hint(environment const & env, name const & d);
expr try_eta(expr const & e);
void initialize_normalize();
void finalize_normalize();
}

40
tests/lean/640a.hlean Normal file
View file

@ -0,0 +1,40 @@
section
parameter {A : Type}
definition relation : A → A → Type := λa b, a = b
local abbreviation R := relation
local abbreviation S [parsing-only] := relation
variable {a : A}
check relation a a
check R a a
check S a a
end
section
parameter {A : Type}
definition relation' : A → A → Type := λa b, a = b
local infix `~1`:50 := relation'
local infix [parsing-only] `~2`:50 := relation'
variable {a : A}
check relation' a a
check a ~1 a
check a ~2 a
end
section
parameter {A : Type}
definition relation'' : A → A → Type := λa b, a = b
local infix [parsing-only] `~2`:50 := relation''
variable {a : A}
check relation'' a a
check a ~2 a
check a ~2 a
end
section
parameter {A : Type}
definition relation''' : A → A → Type := λa b, a = b
local abbreviation S [parsing-only] := relation'''
variable {a : A}
check relation''' a a
check S a a
end

View file

@ -0,0 +1,11 @@
R a a : Type
R a a : Type
R a a : Type
a ~1 a : Type
a ~1 a : Type
a ~1 a : Type
relation'' a a : Type
relation'' a a : Type
relation'' a a : Type
relation''' a a : Type
relation''' a a : Type

2
tests/lean/640b.lean Normal file
View file

@ -0,0 +1,2 @@
abbreviation bar [parsing-only] := @eq
check @bar

View file

@ -0,0 +1 @@
eq : Π {A : Type}, A → A → Prop