From 276149824e043595312c291ad1dfe4bf4b4f381b Mon Sep 17 00:00:00 2001 From: Adam Wardynski <award@.(win7-laptop)> Date: Fri, 3 Dec 2010 21:30:29 +0100 Subject: [PATCH] ABC for Iteration Operators. The concept has been reworked a bit. --- libwccl/ops/functions/bool/iteration.cpp | 74 ++++++++++--------- libwccl/ops/functions/bool/iteration.h | 92 +++++++++++++++--------- 2 files changed, 97 insertions(+), 69 deletions(-) diff --git a/libwccl/ops/functions/bool/iteration.cpp b/libwccl/ops/functions/bool/iteration.cpp index fd9c97c..86707bf 100644 --- a/libwccl/ops/functions/bool/iteration.cpp +++ b/libwccl/ops/functions/bool/iteration.cpp @@ -1,47 +1,57 @@ #include <libwccl/ops/functions/bool/iteration.h> #include <libwccl/ops/functions/bool/predicate.h> - +#include <sstream> namespace Wccl { -#ifndef _MSC_VER -const int Iteration::MatchAll; -#endif +std::string Iteration::to_string(const Corpus2::Tagset& tagset) const +{ + std::ostringstream ss; + ss << name(tagset) << "(" + << left_pos_expr_->to_string(tagset) << ", " + << right_pos_expr_->to_string(tagset) << ", " + << Position::var_repr(iter_var_acc_.get_name()) << ", " + << evaluating_expr_->to_string(tagset) << ")"; + return ss.str(); +} + +std::string Iteration::to_raw_string() const +{ + std::ostringstream ss; + ss << raw_name() << "(" + << left_pos_expr_->to_raw_string() << ", " + << right_pos_expr_->to_raw_string() << ", " + << Position::var_repr(iter_var_acc_.get_name()) << ", " + << evaluating_expr_->to_raw_string() << ")"; + return ss.str(); +} Iteration::BaseRetValPtr Iteration::apply_internal(const FunExecContext& context) const { - const boost::shared_ptr<const Position>& range_begin = range_begin_expr_->apply(context); - const boost::shared_ptr<const Position>& range_end = range_end_expr_->apply(context); + const boost::shared_ptr<const Position>& range_begin = left_pos_expr_->apply(context); + const boost::shared_ptr<const Position>& range_end = right_pos_expr_->apply(context); const boost::shared_ptr<Position>& iter_var = context.variables()->get_fast(iter_var_acc_); const SentenceContext& sc = context.sentence_context(); - - int abs_begin = sc.get_abs_position(*range_begin); - int abs_end = sc.get_abs_position(*range_end); - - // Proceed only if range positions are not "nowhere". - if (abs_begin != Position::Nowhere && abs_end != Position::Nowhere) { + // Get absolute values for left and right extremes of the range + int left = sc.get_abs_position(*range_begin); + int right = sc.get_abs_position(*range_end); + // Proceed only if range extremes are not "nowhere". + if (left != Position::Nowhere && right != Position::Nowhere) { // Trim range to sentence boundaries - if (abs_begin < 0) { - abs_begin = 0; + if (left < 0) { + left = 0; } - if (abs_end >= sc.size()) { - abs_end = sc.size() - 1; + if (right >= sc.size()) { + right = sc.size() - 1; } - int range_size = abs_begin - abs_end + 1; // Proceed only if range isn't empty - if (range_size > 0) { - int n = (match_count_ == MatchAll) ? range_size : match_count_; - // Proceed only if the range actually has enough positions to match - if (n <= range_size) { - if (direction_ == Forward) { - if (iterate(abs_begin, abs_end, 1, *iter_var, context)) { - return Predicate::True(context); - } - } - if (iterate(abs_end, abs_begin, -1, *iter_var, context)) { - return Predicate::True(context); - } + if (left <= right) { + // Change range from absolute to relative and iterate + left -= sc.get_position(); + right -= sc.get_position(); + if (iterate(left, right, *iter_var, context)) { + return Predicate::True(context); } } } @@ -50,10 +60,4 @@ Iteration::BaseRetValPtr Iteration::apply_internal(const FunExecContext& context return Predicate::False(context); } -bool Iteration::iterate(int start, int stop, int step, Position &p, const FunExecContext &context) const -{ - //TODO: implement - return false; -} - } /* end ns Wccl */ diff --git a/libwccl/ops/functions/bool/iteration.h b/libwccl/ops/functions/bool/iteration.h index 1b27b9f..f5f9290 100644 --- a/libwccl/ops/functions/bool/iteration.h +++ b/libwccl/ops/functions/bool/iteration.h @@ -10,57 +10,81 @@ namespace Wccl { /** * Abstract base class for a class of operators that iterate over a range. */ -class Iteration : public Function<Bool> { +class Iteration : public Function<Bool> +{ public: typedef boost::shared_ptr<Function<Position> > PosFunctionPtr; typedef boost::shared_ptr<Function<Bool> > BoolFunctionPtr; - static const int MatchAll = boost::integer_traits<int>::const_min; - typedef enum Direction - { - Forward, - Backward - } Direction; -protected: + /** + * @returns String reperesentation of Iteration Operator. This is + * default representation of + * name(left_pos_expr, right_pos_expr, variable, eval_expr) + */ + std::string to_string(const Corpus2::Tagset& tagset) const; + + /** + * @returns String reperesentation of Iteration Operator. This is + * default representation of + * raw_name(raw_left_pos_expr, raw_right_pos_expr, variable, raw_eval_expr) + * @note This version doesn't require a Tagset, but may + * be incomplete and/or contain internal info. + */ + std::string to_raw_string() const; +protected: + const PosFunctionPtr& left_pos_expr_; + const PosFunctionPtr& right_pos_expr_; + const VariableAccessor<Position> iter_var_acc_; + const BoolFunctionPtr& evaluating_expr_; + Iteration( - const PosFunctionPtr& range_begin_expr, - const PosFunctionPtr& range_end_expr, + const PosFunctionPtr& left_pos_expr, + const PosFunctionPtr& right_pos_expr, const VariableAccessor<Position>& iter_var_acc, - const BoolFunctionPtr& condition_expr, - int match_count = MatchAll, - Direction direction = Forward) - : range_begin_expr_(range_begin_expr), - range_end_expr_(range_end_expr), + const BoolFunctionPtr& evaluating_expr) + : left_pos_expr_(left_pos_expr), + right_pos_expr_(right_pos_expr), iter_var_acc_(iter_var_acc), - condition_expr_(condition_expr), - match_count_(match_count), - direction_(direction) + evaluating_expr_(evaluating_expr) { - BOOST_ASSERT(range_begin_expr_); - BOOST_ASSERT(range_end_expr_); - BOOST_ASSERT(condition_expr_); - BOOST_ASSERT(match_count == MatchAll || match_count > 0); + BOOST_ASSERT(left_pos_expr_); + BOOST_ASSERT(right_pos_expr_); + BOOST_ASSERT(evaluating_expr_); } /** - * Evaluate argument expression and assign the result to underlying variable. - * @returns True. + * Gets start and end positions from arguments to create + * a range of positions to iterate over using a supplied + * iteration variable, evaluating positions within the + * range using supplied evaluation function. + * Range is trimmed to sentence boundaries. + * In case of an invalid range (begin and end cross over or + * either of them points Nowhere), False is returned and iteration + * variable set to Nowhere. + * If range is correct, return value depends on stopping condition + * that describes how many positions within the range have to evaluate + * to true. Exact details depend on type of iteration, and are + * specified by the subclasses via \link iterate \endlink method. + * If the stopping condition has been met positively, + * the iteration variable is set to the first position that made + * the condition true, and True is returned. + * If whole range has been iterated over without meeting the stopping + * condition, False is returned and iteration variable is set to + * Nowhere. + * @returns False in case of invalid range or when whole range has + * been iterated without meeting stop condition specified by a subclass. + * True is returned if the stop condition has been met. */ BaseRetValPtr apply_internal(const FunExecContext& context) const; - const PosFunctionPtr& range_begin_expr_; - const PosFunctionPtr& range_end_expr_; - const VariableAccessor<Position> iter_var_acc_; - const BoolFunctionPtr& condition_expr_; - const int match_count_; - const Direction direction_; - -private: - bool iterate(int start, int stop, int step, Position& p, const FunExecContext& context) const; + virtual bool iterate( + int left, + int right, + Position &p, + const FunExecContext &context) const = 0; }; - } /* end ns Wccl */ #endif // LIBWCCL_OPS_FUNCTIONS_BOOL_ITERATION_H -- GitLab