fix(frontends/lean): type information for "atomic" notation declaration, fixes #292

This commit is contained in:
Leonardo de Moura 2014-11-04 17:47:30 -08:00
parent fa405d7884
commit 3bfe5b0b7e
6 changed files with 69 additions and 2 deletions

View file

@ -132,7 +132,8 @@ optional<expr> elaborator::mvar_to_meta(expr const & mvar) {
/** \brief Store the pair (pos(e), type(r)) in the info_data if m_info_manager is available. */ /** \brief Store the pair (pos(e), type(r)) in the info_data if m_info_manager is available. */
void elaborator::save_type_data(expr const & e, expr const & r) { void elaborator::save_type_data(expr const & e, expr const & r) {
if (!m_no_info && infom() && pip() && if (!m_no_info && infom() && pip() &&
(is_constant(e) || is_local(e) || is_placeholder(e) || is_as_atomic(e) || is_consume_args(e))) { (is_constant(e) || is_local(e) || is_placeholder(e) || is_as_atomic(e) ||
is_consume_args(e) || is_notation_info(e))) {
if (auto p = pip()->get_pos_info(e)) { if (auto p = pip()->get_pos_info(e)) {
expr t = m_tc[m_relax_main_opaque]->infer(r).first; expr t = m_tc[m_relax_main_opaque]->infer(r).first;
m_pre_info_data.add_type_info(p->first, p->second, t); m_pre_info_data.add_type_info(p->first, p->second, t);
@ -862,6 +863,15 @@ pair<expr, constraint_seq> elaborator::visit(expr const & e) {
save_extra_type_data(e, ecs.first); save_extra_type_data(e, ecs.first);
return ecs; return ecs;
} }
if (is_notation_info(e)) {
pair<expr, constraint_seq> ecs;
{
flet<bool> let(m_no_info, true);
ecs = visit(get_annotation_arg(e));
}
save_type_data(e, ecs.first);
return ecs;
}
expr r; expr r;
expr b = e; expr b = e;
constraint_seq cs; constraint_seq cs;

View file

@ -20,15 +20,25 @@ expr mk_extra_info(expr const & e, tag g) { return mk_annotation(get_extra_info(
expr mk_extra_info(expr const & e) { return mk_annotation(get_extra_info(), e); } expr mk_extra_info(expr const & e) { return mk_annotation(get_extra_info(), e); }
bool is_extra_info(expr const & e) { return is_annotation(e, get_extra_info()); } bool is_extra_info(expr const & e) { return is_annotation(e, get_extra_info()); }
static name * g_notation_info = nullptr;
name const & get_notation_info() { return *g_notation_info; }
expr mk_notation_info(expr const & e, tag g) { return mk_annotation(get_notation_info(), e, g); }
expr mk_notation_info(expr const & e) { return mk_annotation(get_notation_info(), e); }
bool is_notation_info(expr const & e) { return is_annotation(e, get_notation_info()); }
void initialize_info_annotation() { void initialize_info_annotation() {
g_no_info = new name("no_info"); g_no_info = new name("no_info");
register_annotation(*g_no_info); register_annotation(*g_no_info);
g_extra_info = new name("extra_info"); g_extra_info = new name("extra_info");
register_annotation(*g_extra_info); register_annotation(*g_extra_info);
g_notation_info = new name("notation_info");
register_annotation(*g_notation_info);
} }
void finalize_info_annotation() { void finalize_info_annotation() {
delete g_no_info; delete g_no_info;
delete g_extra_info; delete g_extra_info;
delete g_notation_info;
} }
} }

View file

@ -28,6 +28,16 @@ expr mk_extra_info(expr const & e);
/** \brief Return true iff \c e is a term annotated with mk_extra_info */ /** \brief Return true iff \c e is a term annotated with mk_extra_info */
bool is_extra_info(expr const & e); bool is_extra_info(expr const & e);
/** \brief Annotate \c e with "notation-info" annotation.
It instructs the elaborator to store the type of \c e.
We use this feature to store the type of atomic notation (i.e.,
notation without parameters).
*/
expr mk_notation_info(expr const & e, tag g);
expr mk_notation_info(expr const & e);
/** \brief Return true iff \c e is a term annotated with mk_notation_info */
bool is_notation_info(expr const & e);
void initialize_info_annotation(); void initialize_info_annotation();
void finalize_info_annotation(); void finalize_info_annotation();
} }

View file

@ -42,6 +42,7 @@ Author: Leonardo de Moura
#include "frontends/lean/notation_cmd.h" #include "frontends/lean/notation_cmd.h"
#include "frontends/lean/elaborator.h" #include "frontends/lean/elaborator.h"
#include "frontends/lean/pp_options.h" #include "frontends/lean/pp_options.h"
#include "frontends/lean/info_annotation.h"
#ifndef LEAN_DEFAULT_PARSER_SHOW_ERRORS #ifndef LEAN_DEFAULT_PARSER_SHOW_ERRORS
#define LEAN_DEFAULT_PARSER_SHOW_ERRORS true #define LEAN_DEFAULT_PARSER_SHOW_ERRORS true
@ -1002,7 +1003,13 @@ expr parser::parse_notation(parse_table t, expr * left) {
} }
buffer<expr> cs; buffer<expr> cs;
for (expr const & a : as) { for (expr const & a : as) {
expr r = instantiate_rev(copy_with_new_pos(a, p), args.size(), args.data()); expr r = copy_with_new_pos(a, p);
if (args.empty()) {
// Notation does not have arguments. Thus, the info-manager should treat is as a single thing.
r = mk_notation_info(r, r.get_tag());
} else {
r = instantiate_rev(r, args.size(), args.data());
}
cs.push_back(r); cs.push_back(r);
} }
expr r = save_pos(mk_choice(cs.size(), cs.data()), p); expr r = save_pos(mk_choice(cs.size(), cs.data()), p);

View file

@ -0,0 +1,8 @@
VISIT notation_info.lean
SYNC 4
import data.nat
open nat
notation `one` := (succ 0)
check one + one
WAIT
INFO 4

View file

@ -0,0 +1,22 @@
-- BEGINWAIT
-- ENDWAIT
-- BEGININFO
-- TYPE|4|6
-- ACK
-- SYMBOL|4|6
one
-- ACK
-- TYPE|4|10
-- ACK
-- SYMBOL|4|10
+
-- ACK
-- TYPE|4|12
-- ACK
-- SYMBOL|4|12
one
-- ACK
-- ENDINFO