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;
 							}
 						}
 					}