From bae8dd09de45a9000f968dbfe394c7d070dcbbe7 Mon Sep 17 00:00:00 2001
From: Adam Wardynski <award@.(B-4.4.46a)>
Date: Thu, 9 Dec 2010 16:29:59 +0100
Subject: [PATCH] agrpp, point-to-point strong agreement operator.

---
 .../bool/predicates/pointagreement.cpp        | 28 +++++++++++++++----
 1 file changed, 23 insertions(+), 5 deletions(-)

diff --git a/libwccl/ops/functions/bool/predicates/pointagreement.cpp b/libwccl/ops/functions/bool/predicates/pointagreement.cpp
index 1c7e859..07400ab 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);
 }
-- 
GitLab