From 27f352d9926d9084b08cd63a75967f41893673db Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Adam=20Wardy=C5=84ski?= <no@email>
Date: Tue, 9 Nov 2010 12:12:27 +0100
Subject: [PATCH] Adding specialization of Equals for positions, as they
 logically need to take into account actual sentence context for full
 comparison.

---
 libwccl/ops/equals.h | 109 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 109 insertions(+)

diff --git a/libwccl/ops/equals.h b/libwccl/ops/equals.h
index 984e809..537b723 100644
--- a/libwccl/ops/equals.h
+++ b/libwccl/ops/equals.h
@@ -57,6 +57,115 @@ protected:
 	}
 };
 
+/**
+ * Predicate that checks for equality of Positions, given sentence context
+ */
+template <>
+class Equals<Position> : public Predicate {
+public:
+	typedef boost::shared_ptr<Function<Position> > ArgFunctionPtr;
+
+	Equals(const ArgFunctionPtr& arg1_expr, const ArgFunctionPtr& arg2_expr)
+		: arg1_expr_(arg1_expr), arg2_expr_(arg2_expr)
+	{
+		BOOST_ASSERT(arg1_expr_);
+		BOOST_ASSERT(arg2_expr_);
+	}
+
+	virtual std::string to_string(const Corpus2::Tagset& tagset) const {
+		return BinaryFunctionFormatter::to_string(tagset, *this, *arg1_expr_, *arg2_expr_);
+	}
+
+	virtual std::string to_raw_string() const {
+		return BinaryFunctionFormatter::to_raw_string(*this, *arg1_expr_, *arg2_expr_);
+	}
+
+	virtual const std::string raw_operator_name() const {
+		return "equals";
+	}
+
+protected:
+	const ArgFunctionPtr arg1_expr_;
+	const ArgFunctionPtr arg2_expr_;
+
+	typedef FunctionBase::BaseRetValPtr BaseRetValPtr;
+
+	/**
+	 * Take values of arguments from expressions and return True if they are equal,
+	 * False otherwise.
+	 */
+	virtual BaseRetValPtr apply_internal(const SentenceContext& context) const {
+		boost::shared_ptr<Position> arg1 = this->arg1_expr_->apply(context);
+		boost::shared_ptr<Position> arg2 = this->arg2_expr_->apply(context);
+		if(arg1->equals(*arg2)) {
+			return Predicate::True->apply(context);
+		} else {
+			//in the given context both positions can still point nowhere
+			//even if they have different underlying value
+			int abs_pos1 = context.get_abs_position(*arg1);
+			int abs_pos2 = context.get_abs_position(*arg2);
+			if(!context.is_inside(abs_pos1) && !context.is_inside(abs_pos2)) {
+				return Predicate::True->apply(context);
+			}
+		}
+		return Predicate::False->apply(context);
+	}
+};
+
+/**
+ * Predicate that checks for equality of PositionRefs, given sentence context
+ */
+template <>
+class Equals<PositionRef> : public Predicate {
+public:
+	typedef boost::shared_ptr<Function<PositionRef> > ArgFunctionPtr;
+
+	Equals(const ArgFunctionPtr& arg1_expr, const ArgFunctionPtr& arg2_expr)
+		: arg1_expr_(arg1_expr), arg2_expr_(arg2_expr)
+	{
+		BOOST_ASSERT(arg1_expr_);
+		BOOST_ASSERT(arg2_expr_);
+	}
+
+	virtual std::string to_string(const Corpus2::Tagset& tagset) const {
+		return BinaryFunctionFormatter::to_string(tagset, *this, *arg1_expr_, *arg2_expr_);
+	}
+
+	virtual std::string to_raw_string() const {
+		return BinaryFunctionFormatter::to_raw_string(*this, *arg1_expr_, *arg2_expr_);
+	}
+
+	virtual const std::string raw_operator_name() const {
+		return "equals";
+	}
+
+protected:
+	const ArgFunctionPtr arg1_expr_;
+	const ArgFunctionPtr arg2_expr_;
+
+	typedef FunctionBase::BaseRetValPtr BaseRetValPtr;
+
+	/**
+	 * Take values of arguments from expressions and return True if they are equal,
+	 * False otherwise.
+	 */
+	virtual BaseRetValPtr apply_internal(const SentenceContext& context) const {
+		boost::shared_ptr<PositionRef> arg1 = this->arg1_expr_->apply(context);
+		boost::shared_ptr<PositionRef> arg2 = this->arg2_expr_->apply(context);
+		if(arg1->equals(*arg2)) {
+			return Predicate::True->apply(context);
+		} else {
+			//in the given context both position refs can still point nowhere
+			//even if they have different underlying value
+			int abs_pos1 = context.get_abs_position(*arg1);
+			int abs_pos2 = context.get_abs_position(*arg2);
+			if(!context.is_inside(abs_pos1) && !context.is_inside(abs_pos2)) {
+				return Predicate::True->apply(context);
+			}
+		}
+		return Predicate::False->apply(context);
+	}
+};
 } /* end ns Wccl */
 
 #endif // EQUALS_H
-- 
GitLab