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