diff --git a/libwccl/ops/functions/bool/predicates/weakagreement.cpp b/libwccl/ops/functions/bool/predicates/weakagreement.cpp index ec373186957592ab6c8de77187b68e77526cfed6..a8a8ce49c8e4c8e986b05c171c14602e06947da4 100644 --- a/libwccl/ops/functions/bool/predicates/weakagreement.cpp +++ b/libwccl/ops/functions/bool/predicates/weakagreement.cpp @@ -47,14 +47,43 @@ WeakAgreement::BaseRetValPtr WeakAgreement::apply_internal(const FunExecContext& return Predicate::False(context); } - const boost::shared_ptr<const TSet>& attribs_tset = attribs_expr_->apply(context); - const Corpus2::Tag& attribs = attribs_tset->get_value(); + const boost::shared_ptr<const TSet>& attribs = attribs_expr_->apply(context); - // - // @todo: implement - // + int min_card = attribs->categories_count(tagset_); - return Predicate::False(context); + for(int i = abs_left; i <= abs_right; ++i) { + bool i_has_matched_tag = false; + foreach (const Corpus2::Lexeme& i_lex, sc.at(i)->lexemes()) { + const Corpus2::Tag& i_tag = i_lex.tag(); + if (attribs->matching_categories(i_tag) >= min_card) { + i_has_matched_tag = true; + for(int j = abs_right; j > i; --j) { + bool i_agrees_with_j = false; + bool j_has_matched_tag = false; + foreach(const Corpus2::Lexeme& j_lex, sc.at(j)->lexemes()) { + const Corpus2::Tag& j_tag = j_lex.tag(); + if (attribs->matching_categories(i_tag) >= min_card) { + j_has_matched_tag = true; + Corpus2::Tag intersection = i_tag.get_masked(j_tag); + // if the intersection matches enough categories we have agreement + if (attribs->matching_categories(intersection) >= min_card) { + i_agrees_with_j = true; + break; + } + } + } + if (j_has_matched_tag && !i_agrees_with_j) { + return Predicate::False(context); + } + } + } + } + if (!i_has_matched_tag && (i == abs_left || i == abs_right)) { + return Predicate::False(context); + } + } + + return Predicate::True(context); } } /* end ns Wccl */