From 5621820fe426a8baa49b3c4f430ae82182d184bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20L=C3=BChne?= Date: Wed, 15 Nov 2017 18:53:43 +0100 Subject: [PATCH] Added normalization tests for negations. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These tests ensure that multiple negations are eliminated, negated quantifiers are replaced appropriately, negations introduced by reduction are correctly handled, and negated disjunctions and conjunctions are replaced according to De Morgan’s rules. --- lib/pddl/tests/TestNormalization.cpp | 76 ++++++++++++++++++ tests/data/normalization/normalization-4.pddl | 80 +++++++++++++++++++ 2 files changed, 156 insertions(+) create mode 100644 tests/data/normalization/normalization-4.pddl diff --git a/lib/pddl/tests/TestNormalization.cpp b/lib/pddl/tests/TestNormalization.cpp index 5df794c..8f2a2bb 100644 --- a/lib/pddl/tests/TestNormalization.cpp +++ b/lib/pddl/tests/TestNormalization.cpp @@ -224,3 +224,79 @@ TEST_CASE("[normalization] Universal quantifiers are correctly reduced", "[norma CHECK(dp->declaration->parameters[1]->name == "y"); } } + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +TEST_CASE("[normalization] Negations are correctly normalized", "[normalization]") +{ + pddl::Tokenizer tokenizer; + pddl::Context context(std::move(tokenizer), ignoreWarnings); + + const auto domainFile = fs::path("data") / "normalization" / "normalization-4.pddl"; + context.tokenizer.read(domainFile); + auto description = pddl::parseDescription(context); + const auto normalizedDescription = pddl::normalize(std::move(description)); + + const auto &actions = normalizedDescription.domain->actions; + + SECTION("multiple negations are correctly eliminated") + { + const auto &p1 = actions[0]->precondition.value().get().get().get(); + CHECK(p1->declaration->name == "test-predicate-1"); + REQUIRE(p1->arguments.size() == 1); + CHECK(p1->arguments[0].get()->declaration->name == "x"); + + const auto &p2 = actions[1]->precondition.value().get().get>()->argument.get(); + CHECK(p2->declaration->name == "test-predicate-1"); + REQUIRE(p2->arguments.size() == 1); + CHECK(p2->arguments[0].get()->declaration->name == "x"); + } + + SECTION("“exists” statements with negations are correctly normalized") + { + const auto &dp = actions[2]->precondition.value().get().get>()->argument.get(); + CHECK(dp->declaration->existentialParameters.size() == 2); + const auto &dpp = dp->declaration->precondition.value().get().get().get(); + CHECK(dpp->declaration->name == "test-predicate-2"); + } + + SECTION("“forall” statements with negations are correctly normalized") + { + const auto &dp = actions[3]->precondition.value().get().get().get(); + CHECK(dp->declaration->existentialParameters.size() == 2); + const auto &dpp = dp->declaration->precondition.value().get().get().get(); + CHECK(dpp->declaration->name == "test-predicate-2"); + } + + SECTION("negations introduced by reduction are correctly normalized") + { + const auto &d = actions[4]->precondition.value().get().get().get(); + const auto &do_ = d->declaration->precondition.value().get>(); + REQUIRE(do_->arguments.size() == 2); + const auto &do1 = do_->arguments[0].get().get(); + REQUIRE(do1->declaration->name == "test-predicate-0"); + const auto &do2 = do_->arguments[1].get().get(); + REQUIRE(do2->declaration->name == "test-predicate-1"); + } + + SECTION("negated disjunctions are correctly normalized") + { + const auto &a = actions[5]->precondition.value().get>(); + REQUIRE(a->arguments.size() == 2); + const auto &a1 = a->arguments[0].get().get(); + REQUIRE(a1->declaration->name == "test-predicate-0"); + const auto &a2 = a->arguments[1].get().get(); + REQUIRE(a2->declaration->name == "test-predicate-1"); + } + + SECTION("negated conjunctions are correctly normalized") + { + const auto &d = actions[6]->precondition.value().get().get().get(); + const auto &do_ = d->declaration->precondition.value().get>(); + REQUIRE(do_->arguments.size() == 2); + const auto &do1 = do_->arguments[0].get().get(); + REQUIRE(do1->declaration->name == "test-predicate-0"); + const auto &do2 = do_->arguments[1].get().get(); + REQUIRE(do2->declaration->name == "test-predicate-1"); + } +} diff --git a/tests/data/normalization/normalization-4.pddl b/tests/data/normalization/normalization-4.pddl new file mode 100644 index 0000000..a2b1e22 --- /dev/null +++ b/tests/data/normalization/normalization-4.pddl @@ -0,0 +1,80 @@ +; tests that negations are correctly normalized +(define (domain test-normalization) + (:predicates + (test-predicate-0) + (test-predicate-1 ?x) + (test-predicate-2 ?x ?y)) + + ; multiple negations + (:action test-action-1 + :parameters + (?x) + :precondition + (not (not (not (not (not (not (test-predicate-1 ?x))))))) + :effect + (test-predicate-1 ?x)) + + ; multiple negations + (:action test-action-2 + :parameters + (?x) + :precondition + (not (not (not (not (not (test-predicate-1 ?x)))))) + :effect + (test-predicate-1 ?x)) + + ; negated “exists” statement + (:action test-action-3 + :parameters + (?x) + :precondition + (not (exists + (?x ?y) + (not (not (test-predicate-2 ?x ?y))))) + :effect + (test-predicate-1 ?x)) + + ; negated “forall” statement + (:action test-action-4 + :parameters + (?x) + :precondition + (not (forall + (?x ?y) + (not (not (not (test-predicate-2 ?x ?y)))))) + :effect + (test-predicate-1 ?x)) + + ; negations introduced by reduction + (:action test-action-5 + :parameters + (?x) + :precondition + (imply + (not (test-predicate-0)) + (test-predicate-1 ?x)) + :effect + (test-predicate-1 ?x)) + + ; negated disjunction + (:action test-action-6 + :parameters + (?x) + :precondition + (not (imply + (test-predicate-0) + (not (test-predicate-1 ?x)))) + :effect + (test-predicate-1 ?x)) + + ; negated conjunction + (:action test-action-7 + :parameters + (?x) + :precondition + (not (and + (not (test-predicate-0)) + (not (test-predicate-1 ?x)))) + :effect + (test-predicate-1 ?x)) +)