diff --git a/libwccl/ops/functions/bool/predicates/pointagreement.cpp b/libwccl/ops/functions/bool/predicates/pointagreement.cpp index 1c7e8591d9622cd943a96b8b00f8b6ae5b39709d..07400ab37ac1f0fc455bb340f7f0f46a1833589b 100644 --- a/libwccl/ops/functions/bool/predicates/pointagreement.cpp +++ b/libwccl/ops/functions/bool/predicates/pointagreement.cpp @@ -33,12 +33,30 @@ PointAgreement::BaseRetValPtr PointAgreement::apply_internal(const FunExecContex 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_); + + const Corpus2::Token* t1 = sc.at(*pos1); + const Corpus2::Token* t2 = sc.at(*pos2); + // to optimize a bit, make sure t1 is the one with less lexemes + if (t1->lexemes().size() > t2->lexemes().size()) { + std::swap(t1, t2); + } + + foreach (const Corpus2::Lexeme& t1_lex, t1->lexemes()) { + const Corpus2::Tag& t1_tag = t1_lex.tag(); + // don't bother checking t2 unless current t1_tag matches enough categories + if (attribs->matching_categories(t1_tag) >= min_card) { + foreach (const Corpus2::Lexeme& t2_lex, t2->lexemes()) { + Corpus2::Tag& intersection = t1_tag.get_masked(t2_lex.tag()); + // if the intersection matches enough categories we have agreement + if (attribs->matching_categories(intersection) >= min_card) { + return Predicate::True(context); + } + } + } + } return Predicate::False(context); }