Skip to content
Snippets Groups Projects
Commit 27614982 authored by Adam Wardynski's avatar Adam Wardynski
Browse files

ABC for Iteration Operators.

The concept has been reworked a bit.
parent 1050b71d
Branches
No related merge requests found
#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 */
......@@ -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
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment