From a8f793865d928791aa213604cd1e7ae914d75b63 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Adam=20Wardy=C5=84ski?= <no@email>
Date: Thu, 4 Nov 2010 21:04:03 +0100
Subject: [PATCH] Adding "and" predicate

---
 libwccl/CMakeLists.txt      |   1 +
 libwccl/ops/and.cpp         |  19 ++++++
 libwccl/ops/and.h           |  32 ++++++++++
 tests/CMakeLists.txt        |   1 +
 tests/logicalpredicates.cpp | 120 ++++++++++++++++++++++++++++++++++++
 5 files changed, 173 insertions(+)
 create mode 100644 libwccl/ops/and.cpp
 create mode 100644 libwccl/ops/and.h
 create mode 100644 tests/logicalpredicates.cpp

diff --git a/libwccl/CMakeLists.txt b/libwccl/CMakeLists.txt
index 3027aee..ccf8411 100644
--- a/libwccl/CMakeLists.txt
+++ b/libwccl/CMakeLists.txt
@@ -16,6 +16,7 @@ set(LIBS ${LIBS} ${Boost_LIBRARIES})
 SET(libwccl_STAT_SRC
 	exception.cpp
 	main.cpp
+	ops/and.cpp
 	ops/logicalpredicate.cpp
 	ops/predicate.cpp
 	sentencecontext.cpp
diff --git a/libwccl/ops/and.cpp b/libwccl/ops/and.cpp
new file mode 100644
index 0000000..893eb6a
--- /dev/null
+++ b/libwccl/ops/and.cpp
@@ -0,0 +1,19 @@
+#include "and.h"
+
+namespace Wccl {
+
+And::BaseRetValPtr And::apply_internal(const SentenceContext &context) const
+{
+	foreach(boost::shared_ptr< Function<Bool> > expression, *expressions_) {
+		if(!(expression->apply(context)->get_value())) {
+			return Predicate::False->apply(context);
+		}
+	}
+	return Predicate::True->apply(context);
+}
+
+const std::string And::raw_operator_name() const {
+	return "and";
+}
+
+} /* end ns Wccl */
diff --git a/libwccl/ops/and.h b/libwccl/ops/and.h
new file mode 100644
index 0000000..1f533d4
--- /dev/null
+++ b/libwccl/ops/and.h
@@ -0,0 +1,32 @@
+#ifndef AND_H
+#define AND_H
+
+#include <boost/foreach.hpp>
+#define foreach         BOOST_FOREACH
+
+#include <libwccl/ops/logicalpredicate.h>
+
+namespace Wccl {
+
+class And : public LogicalPredicate
+{
+public:
+	And(const boost::shared_ptr<BoolFunctionPtrVector>& expressions)
+		: LogicalPredicate(expressions)
+	{
+	}
+
+protected :
+	typedef FunctionBase::BaseRetValPtr BaseRetValPtr ;
+
+	/**
+	 * "And" predicate returns True only when all expressions are true,
+	 * otherwise it returns False
+	 */
+	virtual BaseRetValPtr apply_internal(const SentenceContext&) const;
+
+	virtual const std::string raw_operator_name() const;
+};
+
+} /* end ns Wccl */
+#endif // AND_H
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 2a538ca..167604e 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -7,6 +7,7 @@ add_definitions(-DLIBWCCL_TEST_DATA_DIR="${PROJECT_SOURCE_DIR}/")
 add_executable(tests
 	constant_tests.cpp
 	context.cpp
+	logicalpredicates.cpp
 	main.cpp
 	position.cpp
 	values.cpp
diff --git a/tests/logicalpredicates.cpp b/tests/logicalpredicates.cpp
new file mode 100644
index 0000000..31ef9fb
--- /dev/null
+++ b/tests/logicalpredicates.cpp
@@ -0,0 +1,120 @@
+#include <boost/test/unit_test.hpp>
+#include <boost/bind.hpp>
+#include <boost/shared_ptr.hpp>
+#include <libcorpus2/sentence.h>
+
+#include <libwccl/ops/constant.h>
+#include <libwccl/ops/logicalpredicate.h>
+#include <libwccl/ops/and.h>
+#include <libwccl/values/bool.h>
+#include <libwccl/sentencecontext.h>
+
+using namespace Wccl;
+
+BOOST_AUTO_TEST_SUITE(logical_predicates)
+
+struct PredFix
+{
+	PredFix()
+		: sc(boost::make_shared<Corpus2::Sentence>()),
+		  tagset(),
+		  true_value(true),
+		  false_value(false),
+		  true_constant(new Constant<Bool>(true_value)),
+		  false_constant(new Constant<Bool>(false_value))
+	{
+	}
+	SentenceContext sc;
+	Corpus2::Tagset tagset;
+
+	Bool true_value;
+	Bool false_value;
+	LogicalPredicate::BoolFunctionPtr true_constant;
+	LogicalPredicate::BoolFunctionPtr false_constant;
+};
+
+BOOST_FIXTURE_TEST_CASE(predicate_constants, PredFix)
+{
+	BOOST_CHECK_EQUAL(true, Predicate::True->apply(sc)->get_value());
+	BOOST_CHECK_EQUAL(false, Predicate::False->apply(sc)->get_value());
+}
+
+BOOST_FIXTURE_TEST_CASE(and_1arg, PredFix)
+{
+	boost::shared_ptr<And::BoolFunctionPtrVector> v(new And::BoolFunctionPtrVector());
+	v->push_back(true_constant);
+	And pred_and(v);
+	BOOST_CHECK_EQUAL(true, pred_and.apply(sc)->get_value());
+	v->clear();
+	v->push_back(false_constant);
+	BOOST_CHECK_EQUAL(false, pred_and.apply(sc)->get_value());
+}
+
+BOOST_FIXTURE_TEST_CASE(and_2arg, PredFix)
+{
+	for(int arg1 = 0; arg1 < 2; ++arg1) {
+		for(int arg2 = 0; arg2 < 2; ++arg2) {
+			boost::shared_ptr<And::BoolFunctionPtrVector> v(new And::BoolFunctionPtrVector());
+			v->push_back(arg1 != 0 ? true_constant : false_constant);
+			v->push_back(arg2 != 0 ? true_constant : false_constant);
+			And pred_and(v);
+			BOOST_CHECK_EQUAL((arg1 != 0) && (arg2 != 0), pred_and.apply(sc)->get_value());
+		}
+	}
+}
+
+BOOST_FIXTURE_TEST_CASE(and_3arg, PredFix)
+{
+	for(int arg1 = 0; arg1 < 2; ++arg1) {
+		for(int arg2 = 0; arg2 < 2; ++arg2) {
+			for(int arg3 = 0; arg3 < 2; ++arg3) {
+				boost::shared_ptr<And::BoolFunctionPtrVector> v(new And::BoolFunctionPtrVector());
+				v->push_back(arg1 != 0 ? true_constant : false_constant);
+				v->push_back(arg2 != 0 ? true_constant : false_constant);
+				v->push_back(arg3 != 0 ? true_constant : false_constant);
+				And pred_and(v);
+				BOOST_CHECK_EQUAL((arg1 != 0) && (arg2 != 0) && (arg3 != 0), pred_and.apply(sc)->get_value());
+			}
+		}
+	}
+}
+
+BOOST_FIXTURE_TEST_CASE(and_to_string, PredFix)
+{
+	boost::shared_ptr<And::BoolFunctionPtrVector> v(new And::BoolFunctionPtrVector());
+	v->push_back(true_constant);
+	boost::shared_ptr<Function<Bool> > pred_and(new And(v));
+	BOOST_CHECK_EQUAL("and(true)", pred_and->to_string(tagset));
+	v->push_back(false_constant);
+	BOOST_CHECK_EQUAL("and(true, false)", pred_and->to_string(tagset));
+	v->push_back(true_constant);
+	BOOST_CHECK_EQUAL("and(true, false, true)", pred_and->to_string(tagset));
+
+	boost::shared_ptr<And::BoolFunctionPtrVector> v2(new And::BoolFunctionPtrVector());
+	v2->push_back(false_constant);
+	v2->push_back(pred_and);
+	And another_and(v2);
+	BOOST_CHECK_EQUAL("and(false, and(true, false, true))", another_and.to_raw_string());
+	v2->push_back(false_constant);
+	BOOST_CHECK_EQUAL("and(false, and(true, false, true), false)", another_and.to_raw_string());
+}
+
+BOOST_FIXTURE_TEST_CASE(and_to_raw_string, PredFix)
+{
+	boost::shared_ptr<And::BoolFunctionPtrVector> v(new And::BoolFunctionPtrVector());
+	v->push_back(false_constant);
+	boost::shared_ptr<Function<Bool> > pred_and(new And(v));
+	BOOST_CHECK_EQUAL("and(false)", pred_and->to_raw_string());
+	v->push_back(true_constant);
+	BOOST_CHECK_EQUAL("and(false, true)", pred_and->to_raw_string());
+	v->push_back(true_constant);
+	BOOST_CHECK_EQUAL("and(false, true, true)", pred_and->to_raw_string());
+
+	boost::shared_ptr<And::BoolFunctionPtrVector> v2(new And::BoolFunctionPtrVector());
+	v2->push_back(true_constant);
+	v2->push_back(pred_and);
+	And another_and(v2);
+	BOOST_CHECK_EQUAL("and(true, and(false, true, true))", another_and.to_raw_string());
+}
+
+BOOST_AUTO_TEST_SUITE_END()
-- 
GitLab