diff --git a/libwccl/ops/functions/bool/predicates/strongagreement.cpp b/libwccl/ops/functions/bool/predicates/strongagreement.cpp
index 82b27fd6afab98b5b6962e23db9088e87fdbd562..4081562aa08c6e30fbcbeef7a098e6a8307af4ba 100644
--- a/libwccl/ops/functions/bool/predicates/strongagreement.cpp
+++ b/libwccl/ops/functions/bool/predicates/strongagreement.cpp
@@ -1,4 +1,5 @@
 #include <libwccl/ops/functions/bool/predicates/strongagreement.h>
+#include <libpwrutils/foreach.h>
 
 namespace Wccl {
 
@@ -47,14 +48,38 @@ StrongAgreement::BaseRetValPtr StrongAgreement::apply_internal(const FunExecCont
 		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;
+					foreach(const Corpus2::Lexeme& j_lex, sc.at(j)->lexemes()) {
+						Corpus2::Tag intersection = i_tag.get_masked(j_lex.tag());
+						// if the intersection matches enough categories we have agreement
+						if (attribs->matching_categories(intersection) >= min_card) {
+							i_agrees_with_j = true;
+							break;
+						}
+					}
+					if (!i_agrees_with_j) {
+						return Predicate::False(context);
+					}
+				}
+			}
+		}
+		if (!i_has_matched_tag) {
+			return Predicate::False(context);
+		}
+	}
+
+	return Predicate::True(context);
 }
 
 } /* end ns Wccl */