diff --git a/libwccl/ops/equals.h b/libwccl/ops/equals.h index 984e80913676f3e77c7f31d0f49b047aae7d7f7a..537b7237b08b72b067a06da30883a88d90e40b84 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