Add operator== to list

Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
Leonardo de Moura 2013-08-14 16:35:04 -07:00
parent 5bfb074eaf
commit 913fd14549
5 changed files with 58 additions and 6 deletions

View file

@ -5,18 +5,22 @@ Released under Apache 2.0 license as described in the file LICENSE.
Author: Leonardo de Moura
*/
#include <atomic>
#include <unordered_map>
#include "frontend.h"
#include "environment.h"
#include "operator_info.h"
namespace lean {
static name g_overload_prefix(name(0u), "overload");
/** \brief Implementation of the Lean frontend */
struct frontend::imp {
// Remark: only named objects are stored in the dictionary.
typedef std::unordered_map<name, operator_info, name_hash, name_eq> operator_table;
std::atomic<unsigned> m_num_children;
std::shared_ptr<imp> m_parent;
environment m_env;
operator_table m_nud; // nud table for Pratt's parser
operator_table m_led; // led table for Pratt's parser
operator_table m_name_to_operator; // map internal names to operators (this is used for pretty printing)
bool has_children() const { return m_num_children > 0; }
void inc_children() { m_num_children++; }

View file

@ -30,6 +30,15 @@ struct operator_info::imp {
imp(imp const & s):
m_rc(1), m_fixity(s.m_fixity), m_assoc(s.m_assoc), m_precedence(s.m_precedence), m_op_parts(s.m_op_parts), m_names(s.m_names) {
}
bool is_eq(imp const & other) const {
return
m_fixity == other.m_fixity &&
m_assoc == other.m_assoc &&
m_precedence == other.m_precedence &&
m_op_parts == other.m_op_parts;
}
};
operator_info::operator_info(imp * p):m_ptr(p) {}
@ -62,6 +71,15 @@ list<name> const & operator_info::get_op_name_parts() const { lean_assert(m_ptr)
operator_info operator_info::copy() const { return operator_info(new imp(*m_ptr)); }
bool operator==(operator_info const & op1, operator_info const & op2) {
if ((op1.m_ptr == nullptr) != (op2.m_ptr == nullptr))
return false;
if (op1.m_ptr)
return op1.m_ptr->is_eq(*(op2.m_ptr));
else
return true;
}
operator_info infixr(name const & op, unsigned precedence) {
return operator_info(new operator_info::imp(op, fixity::Infix, associativity::Right, precedence));
}

View file

@ -83,6 +83,9 @@ public:
/** \brief Return a copy of the operator. */
operator_info copy() const;
friend bool operator==(operator_info const & op1, operator_info const & op2);
friend bool operator!=(operator_info const & op1, operator_info const & op2) { return !(op1 == op2); }
};
operator_info infixl(name const & op, unsigned precedence);
operator_info infixr(name const & op, unsigned precedence);

View file

@ -17,7 +17,7 @@ static void tst1() {
l = list<int>(i, l);
lean_assert(!is_nil(l));
lean_assert(car(l) == i);
lean_assert(cdr(l) == old);
lean_assert(is_eqp(cdr(l), old));
}
std::cout << l << "\n";
}
@ -45,9 +45,22 @@ static void tst3() {
lean_assert(length(tail(list<int>(10, list<int>()))) == 0);
}
static void tst4() {
list<int> l1{1, 2, 3};
list<int> l2{1, 2, 3};
lean_assert(l1 == l2);
lean_assert(l1 != cons(1, l2));
lean_assert(l1 != tail(l1));
lean_assert(list<int>() == list<int>());
lean_assert(l2 != list<int>());
lean_assert(l1 != list<int>({1, 2, 3, 4}));
lean_assert(l1 != tail(list<int>{1, 2, 3, 4}));
}
int main() {
tst1();
tst2();
tst3();
tst4();
return has_violations() ? 1 : 0;
}

View file

@ -49,8 +49,22 @@ public:
friend bool is_nil(list const & l) { return l.m_ptr == nullptr; }
friend T const & head(list const & l) { lean_assert(!is_nil(l)); return l.m_ptr->m_head; }
friend list const & tail(list const & l) { lean_assert(!is_nil(l)); return l.m_ptr->m_tail; }
friend bool operator==(list const & l1, list const & l2) { return l1.m_ptr == l2.m_ptr; }
friend bool operator!=(list const & l1, list const & l2) { return l1.m_ptr != l2.m_ptr; }
friend bool is_eqp(list const & l1, list const & l2) { return l1.m_ptr == l2.m_ptr; }
friend bool operator==(list const & l1, list const & l2) {
cell * it1 = l1.m_ptr;
cell * it2 = l2.m_ptr;
while (it1 != nullptr && it2 != nullptr) {
if (it1 == it2)
return true;
if (it1->m_head != it2->m_head)
return false;
it1 = it1->m_tail.m_ptr;
it2 = it2->m_tail.m_ptr;
}
return it1 == nullptr && it2 == nullptr;
}
friend bool operator!=(list const & l1, list const & l2) { return !(l1 == l2); }
class iterator {
friend class list;