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

Factor out code that gets absolute range with validity check.

parent 29940c41
No related merge requests found
......@@ -34,25 +34,13 @@ Iteration::BaseRetValPtr Iteration::apply_internal(const FunExecContext& context
if (range_left->get_value() != Position::Nowhere) {
const boost::shared_ptr<const Position>& range_right =
right_pos_expr_->apply(context);
if (range_right->get_value() != Position::Nowhere) {
// Get absolute values for left and right extremes of the range.
int right = sc.get_abs_position(*range_right);
int left = sc.get_abs_position(*range_left);
// Trim range to sentence boundaries
if (left < 0) {
left = 0;
}
if (right >= sc.size()) {
right = sc.size() - 1;
}
// Proceed only if range isn't empty
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);
}
int left, right;
if (sc.validate_range(*range_left, *range_right, 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);
}
}
}
......
......@@ -33,21 +33,10 @@ StrongAgreement::BaseRetValPtr StrongAgreement::apply_internal(const FunExecCont
if (range_right->get_value() == Position::Nowhere) {
return Predicate::False(context);
}
// Get absolute values for left and right extremes of the range.
int abs_left = sc.get_abs_position(*range_left);
int abs_right = sc.get_abs_position(*range_right);
// Trim range to sentence boundaries
if (abs_left < 0) {
abs_left = 0;
}
if (abs_right >= sc.size()) {
abs_right = sc.size() - 1;
}
// Proceed only if range isn't empty (range outside of sentence or empty sentence are covered)
if (abs_left > abs_right) {
int abs_left, abs_right;
if (!sc.validate_range(*range_left, *range_right, abs_left, abs_right)) {
return Predicate::False(context);
}
const boost::shared_ptr<const TSet>& attribs = attribs_expr_->apply(context);
int min_card = attribs->categories_count(tagset_);
......
......@@ -33,21 +33,10 @@ WeakAgreement::BaseRetValPtr WeakAgreement::apply_internal(const FunExecContext&
if (range_right->get_value() == Position::Nowhere) {
return Predicate::False(context);
}
// Get absolute values for left and right extremes of the range.
int abs_left = sc.get_abs_position(*range_left);
int abs_right = sc.get_abs_position(*range_right);
// Trim range to sentence boundaries
if (abs_left < 0) {
abs_left = 0;
}
if (abs_right >= sc.size()) {
abs_right = sc.size() - 1;
}
// Proceed only if range isn't empty (range outside of sentence or empty sentence are covered)
if (abs_left > abs_right) {
int abs_left, abs_right;
if (!sc.validate_range(*range_left, *range_right, abs_left, abs_right)) {
return Predicate::False(context);
}
const boost::shared_ptr<const TSet>& attribs = attribs_expr_->apply(context);
int min_card = attribs->categories_count(tagset_);
......
......@@ -35,21 +35,10 @@ AgrFilter::BaseRetValPtr AgrFilter::apply_internal(const FunExecContext& context
if (range_right->get_value() == Position::Nowhere) {
return detail::DefaultFunction<TSet>()->apply(context);
}
// Get absolute values for left and right extremes of the range.
int abs_left = sc.get_abs_position(*range_left);
int abs_right = sc.get_abs_position(*range_right);
// Trim range to sentence boundaries
if (abs_left < 0) {
abs_left = 0;
}
if (abs_right >= sc.size()) {
abs_right = sc.size() - 1;
}
// Proceed only if range isn't empty (range outside of sentence or empty sentence are covered)
if (abs_left > abs_right) {
int abs_left, abs_right;
if (!sc.validate_range(*range_left, *range_right, abs_left, abs_right)) {
return detail::DefaultFunction<TSet>()->apply(context);
}
const boost::shared_ptr<const TSet>& attribs = attribs_expr_->apply(context);
const boost::shared_ptr<const TSet>& mask = mask_expr_->apply(context);
......
......@@ -26,22 +26,14 @@ std::ostream& GetSymbolsInRange::write_to(std::ostream& os) const
GetSymbolsInRange::BaseRetValPtr GetSymbolsInRange::apply_internal(const FunExecContext& context) const
{
const boost::shared_ptr<const Position>& range_begin = rbegin_expr_->apply(context);
const boost::shared_ptr<const Position>& range_end = rend_expr_->apply(context);
const SentenceContext& sc = context.sentence_context();
int abs_begin = sc.get_abs_position(*range_begin);
int abs_end = sc.get_abs_position(*range_end);
// Trim range to sentence boundaries
if ((abs_begin != Position::Nowhere) && (abs_begin < 0)) {
abs_begin = 0;
}
if ((abs_end != Position::Nowhere) && (abs_end >= sc.size())) {
abs_end = sc.size() - 1;
if (range_begin->get_value() == Position::Nowhere ) {
return detail::DefaultFunction<TSet>()->apply(context);
}
// If range is empty, return an empty set - note the below also
// covers ranges without overlap with actual sentence range
// (including an empty sentence).
if((abs_begin == Position::Nowhere) || (abs_end == Position::Nowhere) || (abs_begin > abs_end)) {
const boost::shared_ptr<const Position>& range_end = rend_expr_->apply(context);
int abs_begin, abs_end;
if (!sc.validate_range(*range_begin, *range_end, abs_begin, abs_end)) {
return detail::DefaultFunction<TSet>()->apply(context);
}
......
......@@ -72,6 +72,26 @@ public:
return !is_inside(get_abs_position(pos));
}
/**
* Checks if range is valid, i.e. non-empty and not outside of sentence,
* and at the same time finds absolute values of passed Positions
* @param left Position specyfing left extreme of the range
* @param right Position specyfing right extreme of the range
* @param abs_left reference to int value that will hold absolute
* value for left position
* @param abs_right reference to int value that will hold absolute
* value for right position
* @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
* are set to Nowhere
*/
bool validate_range(
const Position& left,
const Position& right,
int& abs_left,
int& abs_right) const;
/// Position setter
void set_position(int new_position) {
position_ = new_position;
......@@ -152,6 +172,42 @@ private:
int position_;
};
inline
bool SentenceContext::validate_range(
const Position& left,
const Position& right,
int& abs_left,
int& abs_right) const
{
abs_left = get_abs_position(left);
if (abs_left == Position::Nowhere) {
abs_right = Position::Nowhere;
return false;
}
abs_right = get_abs_position(right);
if (abs_right == Position::Nowhere) {
abs_left = Position::Nowhere;
return false;
}
// Trim range to sentence boundaries
if (abs_left < 0) {
abs_left = 0;
}
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) {
abs_left = Position::Nowhere;
abs_right = Position::Nowhere;
return false;
}
return true;
}
// TODO ConstSentenceContext ?
} /* end ns Wccl */
......
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