From 831de22bcdd17c744ec342fb241718c197d6ed3f Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Mon, 7 Jul 2014 09:31:42 -0700 Subject: [PATCH] fix(frontends/lean): bugs in notation management Signed-off-by: Leonardo de Moura --- src/frontends/lean/class.cpp | 6 ++- src/frontends/lean/parse_table.cpp | 37 ++++++++++++++++++ src/frontends/lean/parse_table.h | 3 ++ src/frontends/lean/parser_config.cpp | 21 +++++++--- src/frontends/lean/token_table.cpp | 10 +++++ src/frontends/lean/token_table.h | 1 + tests/lean/run/class5.lean | 58 ++++++++++++++++++++++++++++ tests/lean/run/e10.lean | 4 ++ 8 files changed, 132 insertions(+), 8 deletions(-) create mode 100644 tests/lean/run/class5.lean diff --git a/src/frontends/lean/class.cpp b/src/frontends/lean/class.cpp index c30470335..deb47b140 100644 --- a/src/frontends/lean/class.cpp +++ b/src/frontends/lean/class.cpp @@ -30,8 +30,10 @@ struct class_state { } void add_instance(name const & c, name const & i) { auto it = m_instances.find(c); - if (!it) throw exception(sstream() << "invalid instance, unknown class '" << c << "'"); - m_instances.insert(c, cons(i, filter(*it, [&](name const & i1) { return i1 != i; }))); + if (!it) + m_instances.insert(c, list(i)); + else + m_instances.insert(c, cons(i, filter(*it, [&](name const & i1) { return i1 != i; }))); } }; diff --git a/src/frontends/lean/parse_table.cpp b/src/frontends/lean/parse_table.cpp index cb416ff61..93c8e0d2b 100644 --- a/src/frontends/lean/parse_table.cpp +++ b/src/frontends/lean/parse_table.cpp @@ -131,6 +131,24 @@ bool action::is_compatible(action const & a) const { } lean_unreachable(); // LCOV_EXCL_LINE } +void action::display(std::ostream & out) const { + switch (kind()) { + case action_kind::Skip: out << "skip"; break; + case action_kind::Binder: out << "binder"; break; + case action_kind::Binders: out << "binders"; break; + case action_kind::Ext: out << "ext"; break; + case action_kind::LuaExt: out << "luaext"; break; + case action_kind::Expr: out << rbp(); break; + case action_kind::Exprs: + out << "(fold" << (is_fold_right() ? "r" : "l") << " " + << rbp() << " " << get_rec() << " " << get_initial() << ")"; + break; + case action_kind::ScopedExpr: + out << "(scoped " << rbp() << " " << get_rec() << ")"; + break; + } +} + void action_cell::dealloc() { switch (m_kind) { @@ -287,6 +305,25 @@ parse_table parse_table::merge(parse_table const & s, bool overload) const { bool parse_table::is_nud() const { return m_ptr->m_nud; } +void parse_table::display(std::ostream & out) const { + for_each([&](unsigned num, transition const * ts, list const & es) { + for (unsigned i = 0; i < num; i++) { + if (i > 0) out << " "; + out << "`" << ts[i].get_token() << "`:"; + ts[i].get_action().display(out); + } + out << " :="; + if (length(es) == 1) { + out << " " << head(es) << "\n"; + } else { + out << "\n"; + for (auto e : es) { + out << " | " << e << "\n"; + } + } + }); +} + typedef action notation_action; DECL_UDATA(notation_action) diff --git a/src/frontends/lean/parse_table.h b/src/frontends/lean/parse_table.h index d487a10fd..44618f9ab 100644 --- a/src/frontends/lean/parse_table.h +++ b/src/frontends/lean/parse_table.h @@ -77,6 +77,7 @@ public: std::string const & get_lua_fn() const; bool is_compatible(action const & a) const; + void display(std::ostream & out) const; }; action mk_skip_action(); @@ -125,6 +126,8 @@ public: optional> find(name const & tk) const; list const & is_accepting() const; void for_each(std::function const &)> const & fn) const; + + void display(std::ostream & out) const; }; } typedef notation::parse_table parse_table; diff --git a/src/frontends/lean/parser_config.cpp b/src/frontends/lean/parser_config.cpp index 8613cad51..463c3d29b 100644 --- a/src/frontends/lean/parser_config.cpp +++ b/src/frontends/lean/parser_config.cpp @@ -196,14 +196,23 @@ environment add_led_notation(environment const & env, std::initializer_list const & fn); +void display(std::ostream & out, token_table const & s); token_table const * find(token_table const & s, char c); optional get_precedence(token_table const & s, char const * token); token_info const * value_of(token_table const & s); diff --git a/tests/lean/run/class5.lean b/tests/lean/run/class5.lean new file mode 100644 index 000000000..17ddf5f2b --- /dev/null +++ b/tests/lean/run/class5.lean @@ -0,0 +1,58 @@ +import standard + +namespace algebra + inductive mul_struct (A : Type) : Type := + | mk_mul_struct : (A → A → A) → mul_struct A + + class mul_struct + + definition mul [inline] {A : Type} {s : mul_struct A} (a b : A) + := mul_struct_rec (λ f, f) s a b + + infixl `*`:75 := mul +end + +namespace nat + inductive nat : Type := + | zero : nat + | succ : nat → nat + + variable mul : nat → nat → nat + variable add : nat → nat → nat + + definition mul_struct [instance] : algebra.mul_struct nat + := algebra.mk_mul_struct mul +end + +section + using algebra + using nat + variables a b c : nat + check a * b * c +end + +section + using [notation] algebra + using nat + -- check mul_struct nat << This is an error, we are using only the notation from algebra + variables a b c : nat + check a * b * c +end + +section + using nat + -- check mul_struct nat << This is an error, we are using only the notation from algebra + variables a b c : nat + check #algebra a*b*c +end + +section + using nat + + definition add_struct [instance] : algebra.mul_struct nat + := algebra.mk_mul_struct add + + variables a b c : nat + check #algebra a*b*c -- << is using add instead of mul +end + diff --git a/tests/lean/run/e10.lean b/tests/lean/run/e10.lean index 111640fa8..1ce9a73c9 100644 --- a/tests/lean/run/e10.lean +++ b/tests/lean/run/e10.lean @@ -40,3 +40,7 @@ section print raw i + n check n + m end + + +variables a b : nat.nat +check #nat a + b