From 9582c976fc2fefb4ab4fe3ce8aa4b5e35acfe514 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Wardy=C5=84ski?= <no@email> Date: Thu, 4 Nov 2010 23:26:09 +0100 Subject: [PATCH] Adding "not"/"nor" predicate operator --- libwccl/CMakeLists.txt | 1 + libwccl/ops/nor.cpp | 19 ++++++++ libwccl/ops/nor.h | 38 ++++++++++++++++ tests/logicalpredicates.cpp | 88 +++++++++++++++++++++++++++++++++++-- 4 files changed, 142 insertions(+), 4 deletions(-) create mode 100644 libwccl/ops/nor.cpp create mode 100644 libwccl/ops/nor.h diff --git a/libwccl/CMakeLists.txt b/libwccl/CMakeLists.txt index b271d96..00ed846 100644 --- a/libwccl/CMakeLists.txt +++ b/libwccl/CMakeLists.txt @@ -19,6 +19,7 @@ SET(libwccl_STAT_SRC ops/and.cpp ops/or.cpp ops/logicalpredicate.cpp + ops/nor.cpp ops/predicate.cpp sentencecontext.cpp values/bool.cpp diff --git a/libwccl/ops/nor.cpp b/libwccl/ops/nor.cpp new file mode 100644 index 0000000..d547da3 --- /dev/null +++ b/libwccl/ops/nor.cpp @@ -0,0 +1,19 @@ +#include <libwccl/ops/nor.h> + +namespace Wccl { + +Nor::BaseRetValPtr Nor::apply_internal(const SentenceContext &context) const +{ + foreach(BoolFunctionPtr expression, *expressions_) { + if(expression->apply(context)->get_value()) { + return Predicate::False->apply(context); + } + } + return Predicate::True->apply(context); +} + +const std::string Nor::raw_operator_name() const { + return "not"; +} + +} /* end ns Wccl */ diff --git a/libwccl/ops/nor.h b/libwccl/ops/nor.h new file mode 100644 index 0000000..368c3c7 --- /dev/null +++ b/libwccl/ops/nor.h @@ -0,0 +1,38 @@ +#ifndef NOR_H +#define NOR_H + +#include <boost/foreach.hpp> +#define foreach BOOST_FOREACH + +#include <libwccl/ops/logicalpredicate.h> + +namespace Wccl { + +/** + * Operator that realises logical predicate "nor", + * (note: the operator is called "not" in CCL) + */ +class Nor : public LogicalPredicate +{ +public: + Nor(const boost::shared_ptr<BoolFunctionPtrVector>& expressions) + : LogicalPredicate(expressions) + { + } + +protected : + typedef FunctionBase::BaseRetValPtr BaseRetValPtr ; + + /** + * "Nor" (aka "not") predicate evaluates expressions one by one in order + * from left to right, and False is returned once an expression evaluating + * to True is found. + * If all of the expressions were False, True is returned. + */ + virtual BaseRetValPtr apply_internal(const SentenceContext&) const; + + virtual const std::string raw_operator_name() const; +}; + +} /* end ns Wccl */ +#endif // NOR_H diff --git a/tests/logicalpredicates.cpp b/tests/logicalpredicates.cpp index ae27e1b..df8c12f 100644 --- a/tests/logicalpredicates.cpp +++ b/tests/logicalpredicates.cpp @@ -7,6 +7,7 @@ #include <libwccl/ops/logicalpredicate.h> #include <libwccl/ops/and.h> #include <libwccl/ops/or.h> +#include <libwccl/ops/nor.h> #include <libwccl/values/bool.h> #include <libwccl/sentencecontext.h> @@ -122,6 +123,48 @@ BOOST_FIXTURE_TEST_CASE(or_3arg, PredFix) } } +BOOST_FIXTURE_TEST_CASE(nor_1arg, PredFix) +{ + boost::shared_ptr<Nor::BoolFunctionPtrVector> v(new Nor::BoolFunctionPtrVector()); + v->push_back(true_constant); + Nor pred_nor(v); + BOOST_CHECK_EQUAL(false, pred_nor.apply(sc)->get_value()); + v->clear(); + v->push_back(false_constant); + BOOST_CHECK_EQUAL(true, pred_nor.apply(sc)->get_value()); +} + + +BOOST_FIXTURE_TEST_CASE(nor_2arg, PredFix) +{ + for(int arg1 = 0; arg1 < 2; ++arg1) { + for(int arg2 = 0; arg2 < 2; ++arg2) { + boost::shared_ptr<Nor::BoolFunctionPtrVector> v(new Nor::BoolFunctionPtrVector()); + v->push_back(arg1 != 0 ? true_constant : false_constant); + v->push_back(arg2 != 0 ? true_constant : false_constant); + Nor pred_nor(v); + BOOST_CHECK_EQUAL(!((arg1 != 0) || (arg2 != 0)), pred_nor.apply(sc)->get_value()); + } + } +} + +BOOST_FIXTURE_TEST_CASE(nor_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<Nor::BoolFunctionPtrVector> v(new Nor::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); + Nor pred_nor(v); + BOOST_CHECK_EQUAL(!((arg1 != 0) || (arg2 != 0) || (arg3 != 0)), pred_nor.apply(sc)->get_value()); + } + } + } +} + + //------ to_string test cases ------- BOOST_FIXTURE_TEST_CASE(and_to_string, PredFix) @@ -139,9 +182,9 @@ BOOST_FIXTURE_TEST_CASE(and_to_string, PredFix) 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()); + BOOST_CHECK_EQUAL("and(false, and(true, false, true))", another_and.to_string(tagset)); v2->push_back(false_constant); - BOOST_CHECK_EQUAL("and(false, and(true, false, true), false)", another_and.to_raw_string()); + BOOST_CHECK_EQUAL("and(false, and(true, false, true), false)", another_and.to_string(tagset)); } BOOST_FIXTURE_TEST_CASE(and_to_raw_string, PredFix) @@ -177,9 +220,9 @@ BOOST_FIXTURE_TEST_CASE(or_to_string, PredFix) v2->push_back(pred_or); v2->push_back(false_constant); Or another_or(v2); - BOOST_CHECK_EQUAL("or(or(true, false, true), false)", another_or.to_raw_string()); + BOOST_CHECK_EQUAL("or(or(true, false, true), false)", another_or.to_string(tagset)); v2->push_back(true_constant); - BOOST_CHECK_EQUAL("or(or(true, false, true), false, true)", another_or.to_raw_string()); + BOOST_CHECK_EQUAL("or(or(true, false, true), false, true)", another_or.to_string(tagset)); } BOOST_FIXTURE_TEST_CASE(or_to_raw_string, PredFix) @@ -198,7 +241,44 @@ BOOST_FIXTURE_TEST_CASE(or_to_raw_string, PredFix) v2->push_back(pred_or); Or another_or(v2); BOOST_CHECK_EQUAL("or(true, or(false, true, true))", another_or.to_raw_string()); +} + +BOOST_FIXTURE_TEST_CASE(nor_to_string, PredFix) +{ + boost::shared_ptr<Nor::BoolFunctionPtrVector> v(new Nor::BoolFunctionPtrVector()); + v->push_back(true_constant); + boost::shared_ptr<Function<Bool> > pred_nor(new Nor(v)); + BOOST_CHECK_EQUAL("not(true)", pred_nor->to_string(tagset)); + v->push_back(false_constant); + BOOST_CHECK_EQUAL("not(true, false)", pred_nor->to_string(tagset)); + v->push_back(true_constant); + BOOST_CHECK_EQUAL("not(true, false, true)", pred_nor->to_string(tagset)); + + boost::shared_ptr<Or::BoolFunctionPtrVector> v2(new Nor::BoolFunctionPtrVector()); + v2->push_back(pred_nor); + v2->push_back(false_constant); + Nor another_nor(v2); + BOOST_CHECK_EQUAL("not(not(true, false, true), false)", another_nor.to_string(tagset)); + v2->push_back(true_constant); + BOOST_CHECK_EQUAL("not(not(true, false, true), false, true)", another_nor.to_string(tagset)); +} +BOOST_FIXTURE_TEST_CASE(nor_to_raw_string, PredFix) +{ + boost::shared_ptr<Or::BoolFunctionPtrVector> v(new Nor::BoolFunctionPtrVector()); + v->push_back(false_constant); + boost::shared_ptr<Function<Bool> > pred_nor(new Nor(v)); + BOOST_CHECK_EQUAL("not(false)", pred_nor->to_raw_string()); + v->push_back(true_constant); + BOOST_CHECK_EQUAL("not(false, true)", pred_nor->to_raw_string()); + v->push_back(true_constant); + BOOST_CHECK_EQUAL("not(false, true, true)", pred_nor->to_raw_string()); + + boost::shared_ptr<Nor::BoolFunctionPtrVector> v2(new Nor::BoolFunctionPtrVector()); + v2->push_back(true_constant); + v2->push_back(pred_nor); + Nor another_nor(v2); + BOOST_CHECK_EQUAL("not(true, not(false, true, true))", another_nor.to_raw_string()); } BOOST_AUTO_TEST_SUITE_END() -- GitLab