fix(frontends/lean): type information for "atomic" notation declaration, fixes #292
This commit is contained in:
parent
fa405d7884
commit
3bfe5b0b7e
6 changed files with 69 additions and 2 deletions
|
@ -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. */
|
||||
void elaborator::save_type_data(expr const & e, expr const & r) {
|
||||
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)) {
|
||||
expr t = m_tc[m_relax_main_opaque]->infer(r).first;
|
||||
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);
|
||||
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 b = e;
|
||||
constraint_seq cs;
|
||||
|
|
|
@ -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); }
|
||||
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() {
|
||||
g_no_info = new name("no_info");
|
||||
register_annotation(*g_no_info);
|
||||
g_extra_info = new name("extra_info");
|
||||
register_annotation(*g_extra_info);
|
||||
g_notation_info = new name("notation_info");
|
||||
register_annotation(*g_notation_info);
|
||||
}
|
||||
|
||||
void finalize_info_annotation() {
|
||||
delete g_no_info;
|
||||
delete g_extra_info;
|
||||
delete g_notation_info;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
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 finalize_info_annotation();
|
||||
}
|
||||
|
|
|
@ -42,6 +42,7 @@ Author: Leonardo de Moura
|
|||
#include "frontends/lean/notation_cmd.h"
|
||||
#include "frontends/lean/elaborator.h"
|
||||
#include "frontends/lean/pp_options.h"
|
||||
#include "frontends/lean/info_annotation.h"
|
||||
|
||||
#ifndef LEAN_DEFAULT_PARSER_SHOW_ERRORS
|
||||
#define LEAN_DEFAULT_PARSER_SHOW_ERRORS true
|
||||
|
@ -1002,7 +1003,13 @@ expr parser::parse_notation(parse_table t, expr * left) {
|
|||
}
|
||||
buffer<expr> cs;
|
||||
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);
|
||||
}
|
||||
expr r = save_pos(mk_choice(cs.size(), cs.data()), p);
|
||||
|
|
8
tests/lean/interactive/notation_info.input
Normal file
8
tests/lean/interactive/notation_info.input
Normal 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
|
22
tests/lean/interactive/notation_info.input.expected.out
Normal file
22
tests/lean/interactive/notation_info.input.expected.out
Normal 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
|
Loading…
Reference in a new issue