feat(frontends/lean): print all options for overloaded identifier

closes #608
This commit is contained in:
Leonardo de Moura 2015-05-18 17:12:16 -07:00
parent 1c77122fd0
commit c53b96c8d3
7 changed files with 89 additions and 41 deletions

View file

@ -272,34 +272,34 @@ bool print_polymorphic(parser & p) {
name id = p.check_id_next("");
// declarations
try {
name c = p.to_constant(id, "", pos);
list<name> cs = p.to_constants(id, "", pos);
for (name const & c : cs) {
declaration const & d = env.get(c);
if (d.is_theorem()) {
print_constant(p, "theorem", d);
print_definition(p, c, pos);
return true;
} else if (d.is_axiom() || d.is_constant_assumption()) {
if (inductive::is_inductive_decl(env, c)) {
print_inductive(p, c, pos);
return true;
} else if (inductive::is_intro_rule(env, c)) {
return print_constant(p, "constructor", d);
print_constant(p, "constructor", d);
} else if (inductive::is_elim_rule(env, c)) {
return print_constant(p, "eliminator", d);
print_constant(p, "eliminator", d);
} else if (is_quotient_decl(env, c)) {
return print_constant(p, "builtin-quotient-type-constant", d);
print_constant(p, "builtin-quotient-type-constant", d);
} else if (is_hits_decl(env, c)) {
return print_constant(p, "builtin-HIT-constant", d);
print_constant(p, "builtin-HIT-constant", d);
} else if (d.is_axiom()) {
return print_constant(p, "axiom", d);
} else if (d.is_constant_assumption()) {
return print_constant(p, "constant", d);
print_constant(p, "axiom", d);
} else {
print_constant(p, "constant", d);
}
} else if (d.is_definition()) {
print_constant(p, "definition", d);
print_definition(p, c, pos);
return true;
}
}
return true;
} catch (exception & ex) {}
// variables and parameters
@ -371,8 +371,20 @@ environment print_cmd(parser & p) {
} else if (p.curr_is_token_or_id(get_definition_tk())) {
p.next();
auto pos = p.pos();
name c = p.check_constant_next("invalid 'print definition', constant expected");
name id = p.check_id_next("invalid 'print definition', constant expected");
list<name> cs = p.to_constants(id, "invalid 'print definition', constant expected", pos);
for (name const & c : cs) {
declaration const & d = p.env().get(c);
if (d.is_theorem()) {
print_constant(p, "theorem", d);
print_definition(p, c, pos);
} else if (d.is_definition()) {
print_constant(p, "definition", d);
print_definition(p, c, pos);
} else {
throw parser_error(sstream() << "invalid 'print definition', '" << c << "' is not a definition", pos);
}
}
} else if (p.curr_is_token_or_id(get_instances_tk())) {
p.next();
name c = p.check_constant_next("invalid 'print instances', constant expected");

View file

@ -1230,22 +1230,30 @@ expr parser::id_to_expr(name const & id, pos_info const & p) {
return *r;
}
name parser::to_constant(name const & id, char const * msg, pos_info const & p) {
list<name> parser::to_constants(name const & id, char const * msg, pos_info const & p) {
expr e = id_to_expr(id, p);
buffer<name> rs;
std::function<void(expr const & e)> visit = [&](expr const & e) {
if (in_section(m_env) && is_as_atomic(e)) {
e = get_app_fn(get_as_atomic_arg(e));
if (is_explicit(e))
e = get_explicit_arg(e);
}
while (is_choice(e))
e = get_choice(e, 0);
if (is_constant(e)) {
return const_name(e);
visit(get_app_fn(get_as_atomic_arg(e)));
} else if (is_explicit(e)) {
visit(get_explicit_arg(e));
} else if (is_choice(e)) {
for (unsigned i = 0; i < get_num_choices(e); i++)
visit(get_choice(e, i));
} else if (is_constant(e)) {
rs.push_back(const_name(e));
} else {
throw parser_error(msg, p);
}
};
visit(e);
return to_list(rs);
}
name parser::to_constant(name const & id, char const * msg, pos_info const & p) {
return head(to_constants(id, msg, p));
}
name parser::check_constant_next(char const * msg) {

View file

@ -345,6 +345,7 @@ public:
/** \brief Check if the current token is an atomic identifier, if it is, return it and move to next token,
otherwise throw an exception. */
name check_atomic_id_next(char const * msg);
list<name> to_constants(name const & id, char const * msg, pos_info const & p);
name to_constant(name const & id, char const * msg, pos_info const & p);
/** \brief Check if the current token is a constant, if it is, return it and move to next token, otherwise throw an exception. */
name check_constant_next(char const * msg);

8
tests/lean/608.hlean Normal file
View file

@ -0,0 +1,8 @@
import algebra.category.precategory
open function category
print id
print "-----------"
print definition id

View file

@ -0,0 +1,9 @@
definition category.id [reducible] : Π {ob : Type} [C : precategory ob] {a : ob}, hom a a
λ (ob : Type) (C : precategory ob) (a : ob), ID a
definition function.id [reducible] : Π {A : Type}, A → A
is_typeof
-----------
definition category.id [reducible] : Π {ob : Type} [C : precategory ob] {a : ob}, hom a a
λ (ob : Type) (C : precategory ob) (a : ob), ID a
definition function.id [reducible] : Π {A : Type}, A → A
is_typeof

View file

@ -1,3 +1,6 @@
definition tst :
(λ (a : Type₁), 2 + 3)
definition tst :
foo
definition tst1 : num
is_typeof num 10

View file

@ -1,9 +1,16 @@
definition bla.tst :
foo
definition bla.tst :
10 + 1
abbrev2.lean:12:6: error: unknown identifier 'bla.foo'
abbrev2.lean:14:6: error: unknown identifier 'foo'
definition bla.tst :
10 + 1
definition bla2.tst2 :
foo2
definition bla2.tst2 :
1
definition bla2.tst2 :
foo2
definition bla2.tst2 :
foo2