diff --git a/libwccl/ops/functions/bool/predicates/weakagreement.cpp b/libwccl/ops/functions/bool/predicates/weakagreement.cpp index 4c6f3eadf0813b6dfe1110b1721905fb47486962..22828122c8565a4b07ea3548528519d0c23ad9f3 100644 --- a/libwccl/ops/functions/bool/predicates/weakagreement.cpp +++ b/libwccl/ops/functions/bool/predicates/weakagreement.cpp @@ -57,13 +57,16 @@ WeakAgreement::BaseRetValPtr WeakAgreement::apply_internal(const FunExecContext& if (t1->lexemes().size() > t2->lexemes().size()) { std::swap(t1, t2); } - // check strong agreement between range endpoints - // for each possible agreement between them, + // Check strong agreement between range endpoints. + // For each possible agreement between the endpoints, // check if remaining tokens meet that agreement too, - // but take into account only tokens with a tag that - // has enough categories, ignoring the rest (hence "weak" - // agreement). - // return True if an agreement met by all selected tokens is found + // but instead of looking for strong agreement i.e. + // matching on exact number of categories, look for + // weak agreement i.e. matching only on those categories + // that are present. + // Specifically, if there is a lexeme that does not + // match any of the categories, that means the token + // does meet the weak agreement. 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 @@ -72,21 +75,20 @@ WeakAgreement::BaseRetValPtr WeakAgreement::apply_internal(const FunExecContext& Corpus2::Tag inter = t1_tag.get_masked(t2_lex.tag()); // if the intersection matches enough categories we have agreement if (attribs->matching_categories(inter) >= min_card) { - // check if selected agreement is met by all remaining tokens - // but take into account only tokens with a tag that has - // proper amount of categories. + // Check if selected agreement is met by all remaining tokens bool agreement_met = true; for(int i = abs_left + 1; agreement_met && (i < abs_right); ++i) { foreach(const Corpus2::Lexeme& i_lex, sc.at(i)->lexemes()) { - if (attribs->matching_categories(i_lex.tag()) >= min_card) { - // token has a tag matching enough categories, - // so now it has to meet the selected agreement - agreement_met = false; - Corpus2::Tag i_inter = i_lex.tag().get_masked(inter); - if (attribs->matching_categories(i_inter) >= min_card) { - agreement_met = true; - break; - } + // Check if agreement is met, but taking into account + // only categories actually matched in current tag, + // without requirement to match all categories in the + // agreement. + Corpus2::Tag i_inter = i_lex.tag().get_masked(inter); + agreement_met = + (attribs->matching_categories(i_lex.tag()) + == attribs->matching_categories(i_inter)); + if(agreement_met) { + break; } } }