diff --git a/libwccl/values/position.cpp b/libwccl/values/position.cpp index 5be0a85b2be1d03e3b48cbad9ff35801e4302899..f1cadf25c45e8b9dece29211949bece6fd09caaa 100644 --- a/libwccl/values/position.cpp +++ b/libwccl/values/position.cpp @@ -43,4 +43,9 @@ bool Position::is_inside(const SentenceContext& context) const return context.is_inside(abs_position); } +bool Position::equals(const Position& other, const SentenceContext& context) const +{ + return context.get_abs_position(*this) == context.get_abs_position(other); +} + } /* end ns Wccl */ diff --git a/libwccl/values/position.h b/libwccl/values/position.h index fed7a414ed5369acf13a6c909b4e714db93ef26d..ca3f7a1e790df02833add568363d34d2f514a843 100644 --- a/libwccl/values/position.h +++ b/libwccl/values/position.h @@ -50,7 +50,8 @@ public: /** * @returns True if underlying position values are equal, false otherwise. * @note This version does not take into account sentence context, only - * the raw value of position. + * the raw value of position. In practice it means that the special positions + * Begin, End, Nowhere are equal only to a coresponding special position. */ bool equals(const Position& other) const { return val_ == other.val_; @@ -58,13 +59,13 @@ public: /** * @returns True if positions are equal in context of a sentence, false otherwise. - * @note This version determines if position values point outside of a sentence, - * and if both of them do, they are considered to be equal as well (both "nowhere"). + * @note The equality is determined by absolute value of the Position in context + * of a sentence (this means pointing to the same absolute position regardless + * if it lies inside or outside of the sentence). + * Nowhere is only equal to another Nowhere, but Begin or End may be equal to + * a nonspecial position depending on the value of current position in the context. */ - bool equals(const Position& other, const SentenceContext& context) const - { - return equals(other) || (is_outside(context) && other.is_outside(context)); - } + bool equals(const Position& other, const SentenceContext& context) const; private: int val_; diff --git a/tests/values.cpp b/tests/values.cpp index c39115e7cbbe63ea41660a8b1843e762c7d46c56..6f9e5c391c56d3a61c65d43ab741d7748aa0fce8 100644 --- a/tests/values.cpp +++ b/tests/values.cpp @@ -2,6 +2,7 @@ #include <boost/bind.hpp> #include <libcorpus2/tagsetmanager.h> +#include <libwccl/sentencecontext.h> #include <libwccl/variables.h> #include <iostream> @@ -26,6 +27,14 @@ BOOST_AUTO_TEST_CASE(tsetz) BOOST_CHECK_EQUAL(v.get_type_name(), TSet::type_name); } +BOOST_AUTO_TEST_CASE(positionz) +{ + Position p; + BOOST_CHECK(p.get_value() == Position::Nowhere); + Value& v = p; + BOOST_CHECK_EQUAL(v.get_type_name(), Position::type_name); +} + BOOST_AUTO_TEST_CASE(strset_ops) { StrSet s1, s2; @@ -85,4 +94,67 @@ BOOST_AUTO_TEST_CASE(tset_ops) BOOST_CHECK(s1.intersects(s2)); } +BOOST_AUTO_TEST_CASE(position_ops) +{ + boost::shared_ptr<Corpus2::Sentence> s(boost::make_shared<Corpus2::Sentence>()); + SentenceContext sc(s); + Corpus2::Token* a_token = new Corpus2::Token("ZZ", PwrNlp::Whitespace::ManySpaces); + Corpus2::Tag t1(Corpus2::mask_t(0)); + Corpus2::Lexeme l1("aaa", t1); + Corpus2::Lexeme l2("bbb", t1); + a_token->add_lexeme(l1); + a_token->add_lexeme(l2); + s->append(a_token); + s->append(a_token->clone()); + Position begin(Position::Begin); + Position end(Position::End); + Position nowhere(Position::Nowhere); + Position zero(0); + Position one(1); + Position minus_one(-1); + Position minus_two(-2); + + std::vector<Position> v; + v.push_back(begin); + v.push_back(end); + v.push_back(nowhere); + v.push_back(zero); + v.push_back(one); + v.push_back(minus_one); + v.push_back(minus_two); + + for(int i = 0; i < v.size(); ++i) { + for(int j = 0; j < v.size(); ++j) { + BOOST_CHECK_EQUAL(i == j, v[i].equals(v[j])); + BOOST_CHECK_EQUAL(i == j, v[j].equals(v[i])); + if(i >= 2 && j >= 2) { //nowhere, zero, one, minus_one, minus_two + BOOST_CHECK_EQUAL(i == j, v[j].equals(v[i], sc)); + BOOST_CHECK_EQUAL(i == j, v[j].equals(v[i], sc)); + sc.advance(); + BOOST_CHECK_EQUAL(i == j, v[j].equals(v[i], sc)); + BOOST_CHECK_EQUAL(i == j, v[j].equals(v[i], sc)); + sc.advance(); + BOOST_CHECK_EQUAL(i == j, v[j].equals(v[i], sc)); + BOOST_CHECK_EQUAL(i == j, v[j].equals(v[i], sc)); + sc.goto_start(); + } + } + } + sc.goto_start(); + BOOST_CHECK(begin.equals(zero, sc)); + BOOST_CHECK(zero.equals(begin, sc)); + BOOST_CHECK(one.equals(end, sc)); + BOOST_CHECK(end.equals(one, sc)); + sc.advance(); + BOOST_CHECK(begin.equals(minus_one, sc)); + BOOST_CHECK(minus_one.equals(begin, sc)); + BOOST_CHECK(zero.equals(end, sc)); + BOOST_CHECK(end.equals(zero, sc)); + sc.advance(); + BOOST_CHECK(begin.equals(minus_two, sc)); + BOOST_CHECK(minus_two.equals(begin, sc)); + BOOST_CHECK(minus_one.equals(end, sc)); + BOOST_CHECK(end.equals(minus_one, sc)); +} + BOOST_AUTO_TEST_SUITE_END()