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
Branches
No related merge requests found
...@@ -34,25 +34,13 @@ Iteration::BaseRetValPtr Iteration::apply_internal(const FunExecContext& context ...@@ -34,25 +34,13 @@ Iteration::BaseRetValPtr Iteration::apply_internal(const FunExecContext& context
if (range_left->get_value() != Position::Nowhere) { if (range_left->get_value() != Position::Nowhere) {
const boost::shared_ptr<const Position>& range_right = const boost::shared_ptr<const Position>& range_right =
right_pos_expr_->apply(context); right_pos_expr_->apply(context);
if (range_right->get_value() != Position::Nowhere) { int left, right;
// Get absolute values for left and right extremes of the range. if (sc.validate_range(*range_left, *range_right, left, right)) {
int right = sc.get_abs_position(*range_right); // Change range from absolute to relative and iterate
int left = sc.get_abs_position(*range_left); left -= sc.get_position();
// Trim range to sentence boundaries right -= sc.get_position();
if (left < 0) { if (iterate(left, right, *iter_var, context)) {
left = 0; return Predicate::True(context);
}
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);
}
} }
} }
} }
......
...@@ -33,21 +33,10 @@ StrongAgreement::BaseRetValPtr StrongAgreement::apply_internal(const FunExecCont ...@@ -33,21 +33,10 @@ StrongAgreement::BaseRetValPtr StrongAgreement::apply_internal(const FunExecCont
if (range_right->get_value() == Position::Nowhere) { if (range_right->get_value() == Position::Nowhere) {
return Predicate::False(context); return Predicate::False(context);
} }
// Get absolute values for left and right extremes of the range. int abs_left, abs_right;
int abs_left = sc.get_abs_position(*range_left); if (!sc.validate_range(*range_left, *range_right, abs_left, abs_right)) {
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) {
return Predicate::False(context); return Predicate::False(context);
} }
const boost::shared_ptr<const TSet>& attribs = attribs_expr_->apply(context); const boost::shared_ptr<const TSet>& attribs = attribs_expr_->apply(context);
int min_card = attribs->categories_count(tagset_); int min_card = attribs->categories_count(tagset_);
......
...@@ -33,21 +33,10 @@ WeakAgreement::BaseRetValPtr WeakAgreement::apply_internal(const FunExecContext& ...@@ -33,21 +33,10 @@ WeakAgreement::BaseRetValPtr WeakAgreement::apply_internal(const FunExecContext&
if (range_right->get_value() == Position::Nowhere) { if (range_right->get_value() == Position::Nowhere) {
return Predicate::False(context); return Predicate::False(context);
} }
// Get absolute values for left and right extremes of the range. int abs_left, abs_right;
int abs_left = sc.get_abs_position(*range_left); if (!sc.validate_range(*range_left, *range_right, abs_left, abs_right)) {
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) {
return Predicate::False(context); return Predicate::False(context);
} }
const boost::shared_ptr<const TSet>& attribs = attribs_expr_->apply(context); const boost::shared_ptr<const TSet>& attribs = attribs_expr_->apply(context);
int min_card = attribs->categories_count(tagset_); int min_card = attribs->categories_count(tagset_);
......
...@@ -35,21 +35,10 @@ AgrFilter::BaseRetValPtr AgrFilter::apply_internal(const FunExecContext& context ...@@ -35,21 +35,10 @@ AgrFilter::BaseRetValPtr AgrFilter::apply_internal(const FunExecContext& context
if (range_right->get_value() == Position::Nowhere) { if (range_right->get_value() == Position::Nowhere) {
return detail::DefaultFunction<TSet>()->apply(context); return detail::DefaultFunction<TSet>()->apply(context);
} }
// Get absolute values for left and right extremes of the range. int abs_left, abs_right;
int abs_left = sc.get_abs_position(*range_left); if (!sc.validate_range(*range_left, *range_right, abs_left, abs_right)) {
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) {
return detail::DefaultFunction<TSet>()->apply(context); return detail::DefaultFunction<TSet>()->apply(context);
} }
const boost::shared_ptr<const TSet>& attribs = attribs_expr_->apply(context); const boost::shared_ptr<const TSet>& attribs = attribs_expr_->apply(context);
const boost::shared_ptr<const TSet>& mask = mask_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 ...@@ -26,22 +26,14 @@ std::ostream& GetSymbolsInRange::write_to(std::ostream& os) const
GetSymbolsInRange::BaseRetValPtr GetSymbolsInRange::apply_internal(const FunExecContext& context) 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_begin = rbegin_expr_->apply(context);
const boost::shared_ptr<const Position>& range_end = rend_expr_->apply(context);
const SentenceContext& sc = context.sentence_context(); const SentenceContext& sc = context.sentence_context();
int abs_begin = sc.get_abs_position(*range_begin); if (range_begin->get_value() == Position::Nowhere ) {
int abs_end = sc.get_abs_position(*range_end); return detail::DefaultFunction<TSet>()->apply(context);
// 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 is empty, return an empty set - note the below also const boost::shared_ptr<const Position>& range_end = rend_expr_->apply(context);
// covers ranges without overlap with actual sentence range int abs_begin, abs_end;
// (including an empty sentence). if (!sc.validate_range(*range_begin, *range_end, abs_begin, abs_end)) {
if((abs_begin == Position::Nowhere) || (abs_end == Position::Nowhere) || (abs_begin > abs_end)) {
return detail::DefaultFunction<TSet>()->apply(context); return detail::DefaultFunction<TSet>()->apply(context);
} }
......
...@@ -72,6 +72,26 @@ public: ...@@ -72,6 +72,26 @@ public:
return !is_inside(get_abs_position(pos)); 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 /// Position setter
void set_position(int new_position) { void set_position(int new_position) {
position_ = new_position; position_ = new_position;
...@@ -152,6 +172,42 @@ private: ...@@ -152,6 +172,42 @@ private:
int position_; 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 ? // TODO ConstSentenceContext ?
} /* end ns Wccl */ } /* 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