From 640d27c7845499e9c2f01e921807eac323e2dc41 Mon Sep 17 00:00:00 2001 From: Adam Radziszewski <adam.radziszewski@pwr.wroc.pl> Date: Thu, 4 Aug 2011 12:51:35 +0200 Subject: [PATCH] Change in only semantics: range beg&end may be crossed, resulting in True --- libwccl/ops/functions/bool/iteration.cpp | 8 ++++++-- libwccl/ops/functions/bool/iteration.h | 14 +++++++++----- libwccl/ops/functions/bool/iterations/atleast.h | 3 ++- libwccl/ops/functions/bool/iterations/leftlook.h | 3 ++- libwccl/ops/functions/bool/iterations/only.h | 6 ++++-- libwccl/ops/functions/bool/iterations/rightlook.h | 3 ++- libwccl/sentencecontext.h | 10 +++++++--- 7 files changed, 32 insertions(+), 15 deletions(-) diff --git a/libwccl/ops/functions/bool/iteration.cpp b/libwccl/ops/functions/bool/iteration.cpp index c91fc17..cb2034a 100644 --- a/libwccl/ops/functions/bool/iteration.cpp +++ b/libwccl/ops/functions/bool/iteration.cpp @@ -25,8 +25,11 @@ std::ostream& Iteration::write_to(std::ostream& os) const Iteration::BaseRetValPtr Iteration::apply_internal(const FunExecContext& context) const { + // Set iteration variable to Nowhere + // Should be overridden if succeeded const boost::shared_ptr<Position>& iter_var = context.variables()->get_fast(iter_var_acc_); + iter_var->set_value(Position::Nowhere); const SentenceContext& sc = context.sentence_context(); // Proceed only if range extremes are not "nowhere". const boost::shared_ptr<const Position>& range_left = @@ -35,7 +38,8 @@ Iteration::BaseRetValPtr Iteration::apply_internal(const FunExecContext& context const boost::shared_ptr<const Position>& range_right = right_pos_expr_->apply(context); int left, right; - if (sc.validate_range(*range_left, *range_right, left, right)) { + if (sc.validate_range(*range_left, *range_right, + left, right, may_cross)) { // Change range from absolute to relative and iterate left -= sc.get_position(); right -= sc.get_position(); @@ -44,7 +48,7 @@ Iteration::BaseRetValPtr Iteration::apply_internal(const FunExecContext& context } } } - // In case of failure, set iteration variable to Nowhere and return False + // Failure. Make sure iteration variable points Nowhere and return False iter_var->set_value(Position::Nowhere); return Predicate::False(context); } diff --git a/libwccl/ops/functions/bool/iteration.h b/libwccl/ops/functions/bool/iteration.h index dee6c88..cb96a2e 100644 --- a/libwccl/ops/functions/bool/iteration.h +++ b/libwccl/ops/functions/bool/iteration.h @@ -28,16 +28,19 @@ protected: const PosFunctionPtr right_pos_expr_; const VariableAccessor<Position> iter_var_acc_; const BoolFunctionPtr evaluating_expr_; + const bool may_cross; Iteration( const PosFunctionPtr& left_pos_expr, const PosFunctionPtr& right_pos_expr, const VariableAccessor<Position>& iter_var_acc, - const BoolFunctionPtr& evaluating_expr) + const BoolFunctionPtr& evaluating_expr, + bool may_cross) : left_pos_expr_(left_pos_expr), right_pos_expr_(right_pos_expr), iter_var_acc_(iter_var_acc), - evaluating_expr_(evaluating_expr) + evaluating_expr_(evaluating_expr), + may_cross(may_cross) { BOOST_ASSERT(left_pos_expr_); BOOST_ASSERT(right_pos_expr_); @@ -50,9 +53,10 @@ protected: * 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. + * A range is invalid when begin or end point Nowhere. Depending on the + * value of may_cross, a range with begin following end is treated either + * as invalid (may_cross == False) or valid. In case of an invalid range, + * 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 diff --git a/libwccl/ops/functions/bool/iterations/atleast.h b/libwccl/ops/functions/bool/iterations/atleast.h index 21d5536..a2b756e 100644 --- a/libwccl/ops/functions/bool/iterations/atleast.h +++ b/libwccl/ops/functions/bool/iterations/atleast.h @@ -19,7 +19,8 @@ public: const VariableAccessor<Position>& iter_var_acc, const BoolFunctionPtr& evaluating_expr, int min_matches) - : Iteration(left_pos_expr, right_pos_expr, iter_var_acc, evaluating_expr), + : Iteration(left_pos_expr, right_pos_expr, iter_var_acc, + evaluating_expr, false), // false==no crossing ranges min_matches_(min_matches) { BOOST_ASSERT(min_matches_ > 0); diff --git a/libwccl/ops/functions/bool/iterations/leftlook.h b/libwccl/ops/functions/bool/iterations/leftlook.h index 618aa3d..e0776c6 100644 --- a/libwccl/ops/functions/bool/iterations/leftlook.h +++ b/libwccl/ops/functions/bool/iterations/leftlook.h @@ -18,7 +18,8 @@ public: const PosFunctionPtr& right_pos_expr, const VariableAccessor<Position>& iter_var_acc, const BoolFunctionPtr& evaluating_expr) - : Iteration(left_pos_expr, right_pos_expr, iter_var_acc, evaluating_expr) + : Iteration(left_pos_expr, right_pos_expr, iter_var_acc, + evaluating_expr, false) // false==no crossing ranges { } diff --git a/libwccl/ops/functions/bool/iterations/only.h b/libwccl/ops/functions/bool/iterations/only.h index dce58cb..f11d6f5 100644 --- a/libwccl/ops/functions/bool/iterations/only.h +++ b/libwccl/ops/functions/bool/iterations/only.h @@ -8,7 +8,8 @@ namespace Wccl { /** * Iterative operator "only", which mandates that * evaluating expression should evaluate to true - * on all positions in range. + * on all positions in range OR the range should + * be empty. */ class Only : public Iteration { @@ -18,7 +19,8 @@ public: const PosFunctionPtr& right_pos_expr, const VariableAccessor<Position>& iter_var_acc, const BoolFunctionPtr& evaluating_expr) - : Iteration(left_pos_expr, right_pos_expr, iter_var_acc, evaluating_expr) + : Iteration(left_pos_expr, right_pos_expr, iter_var_acc, + evaluating_expr, true) { } diff --git a/libwccl/ops/functions/bool/iterations/rightlook.h b/libwccl/ops/functions/bool/iterations/rightlook.h index dcc5e5f..579aea3 100644 --- a/libwccl/ops/functions/bool/iterations/rightlook.h +++ b/libwccl/ops/functions/bool/iterations/rightlook.h @@ -18,7 +18,8 @@ public: const PosFunctionPtr& right_pos_expr, const VariableAccessor<Position>& iter_var_acc, const BoolFunctionPtr& evaluating_expr) - : Iteration(left_pos_expr, right_pos_expr, iter_var_acc, evaluating_expr) + : Iteration(left_pos_expr, right_pos_expr, iter_var_acc, + evaluating_expr, false) // false==no crossing ranges { } diff --git a/libwccl/sentencecontext.h b/libwccl/sentencecontext.h index a857a3f..6775ef8 100644 --- a/libwccl/sentencecontext.h +++ b/libwccl/sentencecontext.h @@ -88,6 +88,7 @@ public: * value for left position * @param abs_right reference to int value that will hold absolute * value for right position + * @param may_cross set to true if crossing begin and end is admissible * @returns true if range is valid; in this case abs_left and abs_right * are set to absolute positions values for left and right Position. * False is returned otherwise; in this case abs_left and abs_right @@ -97,7 +98,8 @@ public: const Position& left, const Position& right, int& abs_left, - int& abs_right) const; + int& abs_right, + bool may_cross = false) const; /// Position setter void set_position(int new_position) { @@ -196,7 +198,8 @@ bool SentenceContext::validate_range( const Position& left, const Position& right, int& abs_left, - int& abs_right) const + int& abs_right, + bool may_cross) const { abs_left = get_abs_position(left); @@ -216,9 +219,10 @@ bool SentenceContext::validate_range( if (abs_right >= size()) { abs_right = size() - 1; } + // is range valid? this covers "crossed" range, an empty sentence, // and range outside boundaries of sentence - if (abs_left > abs_right) { + if (!may_cross && (abs_left > abs_right)) { abs_left = Position::Nowhere; abs_right = Position::Nowhere; return false; -- GitLab