From 39410ac98b9f142c5ba2868f06a88604a1703852 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20L=C3=BChne?= Date: Thu, 16 Nov 2017 16:29:12 +0100 Subject: [PATCH] Added normalization tests for nested expressions. These tests ensure that nested expressions in preconditions and effects are correctly flattened via derived predicates. --- lib/pddl/tests/TestNormalization.cpp | 129 ++++++++++++++++++ tests/data/normalization/normalization-5.pddl | 58 ++++++++ 2 files changed, 187 insertions(+) create mode 100644 tests/data/normalization/normalization-5.pddl diff --git a/lib/pddl/tests/TestNormalization.cpp b/lib/pddl/tests/TestNormalization.cpp index 8f2a2bb..457d433 100644 --- a/lib/pddl/tests/TestNormalization.cpp +++ b/lib/pddl/tests/TestNormalization.cpp @@ -300,3 +300,132 @@ TEST_CASE("[normalization] Negations are correctly normalized", "[normalization] REQUIRE(do2->declaration->name == "test-predicate-1"); } } + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +TEST_CASE("[normalization] Nested expressions are correctly flattened via derived predicates", "[normalization]") +{ + pddl::Tokenizer tokenizer; + pddl::Context context(std::move(tokenizer), ignoreWarnings); + + const auto domainFile = fs::path("data") / "normalization" / "normalization-5.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("nested expressions in action preconditions are correctly flattened") + { + const auto &a = actions[0]->precondition.value().get>(); + REQUIRE(a->arguments.size() == 3); + + const auto &a1 = a->arguments[0].get>()->argument.get(); + REQUIRE(a1->declaration->parameters.size() == 1); + CHECK(a1->declaration->existentialParameters.size() == 1); + const auto &a11 = a1->declaration->precondition.value().get>(); + REQUIRE(a11->arguments.size() == 2); + const auto &a111 = a11->arguments[0].get().get(); + CHECK(a111->declaration->name == "p1"); + REQUIRE(a111->arguments.size() == 2); + CHECK(a111->arguments[0].get()->declaration == actions[0]->parameters[1].get()); + CHECK(a111->arguments[1].get()->declaration == a1->declaration->existentialParameters[0].get()); + const auto &a112 = a11->arguments[1].get>()->argument.get(); + CHECK(a112->declaration->name == "p2"); + + const auto &a2 = a->arguments[1].get().get(); + CHECK(a2->declaration->name == "p3"); + REQUIRE(a2->arguments.size() == 2); + CHECK(a2->arguments[0].get()->declaration == actions[0]->parameters[0].get()); + + const auto &a3 = a->arguments[2].get().get(); + REQUIRE(a3->arguments.size() == 2); + const auto &a31 = a3->declaration->precondition.value().get>(); + REQUIRE(a31->arguments.size() == 2); + const auto &a311 = a31->arguments[0].get().get(); + const auto &a3111 = a311->declaration->precondition.value().get>(); + REQUIRE(a3111->arguments.size() == 2); + const auto &a31111 = a3111->arguments[0].get().get(); + CHECK(a31111->declaration->name == "p4"); + const auto &a31112 = a3111->arguments[1].get>()->argument.get(); + CHECK(a31112->declaration->parameters.size() == 2); + CHECK(a31112->declaration->existentialParameters.size() == 1); + const auto &a311121 = a31112->declaration->precondition.value().get>(); + REQUIRE(a311121->arguments.size() == 2); + const auto &a3111211 = a311121->arguments[0].get().get(); + CHECK(a3111211->declaration->name == "p5"); + const auto &a3111212 = a311121->arguments[1].get>()->argument.get(); + CHECK(a3111212->declaration->name == "p3"); + const auto &a312 = a31->arguments[1].get().get(); + const auto &a3121 = a312->declaration->precondition.value().get>(); + REQUIRE(a3121->arguments.size() == 2); + const auto &a31211 = a3121->arguments[0].get().get(); + CHECK(a31111->declaration->name == "p4"); + const auto &a31212 = a3121->arguments[1].get>()->argument.get(); + REQUIRE(a31212->declaration->parameters.size() == 1); + REQUIRE(a31212->declaration->existentialParameters.size() == 2); + const auto &a312121 = a31212->declaration->precondition.value().get>(); + REQUIRE(a312121->arguments.size() == 2); + const auto &a3121211 = a312121->arguments[0].get().get(); + CHECK(a3121211->declaration->name == "p6"); + REQUIRE(a3121211->arguments.size() == 3); + CHECK(a3121211->arguments[0].get()->declaration == a31212->declaration->existentialParameters[0].get()); + CHECK(a3121211->arguments[1].get()->declaration == a31212->declaration->existentialParameters[1].get()); + CHECK(a3121211->arguments[2].get()->declaration == actions[0]->parameters[1].get()); + const auto &a3121212 = a312121->arguments[1].get().get(); + CHECK(a3121212->declaration->name == "p3"); + REQUIRE(a3121212->arguments.size() == 2); + CHECK(a3121212->arguments[0].get()->declaration == a31212->declaration->existentialParameters[0].get()); + CHECK(a3121212->arguments[1].get()->declaration == actions[0]->parameters[1].get()); + } + + SECTION("nested expressions in conditional effect preconditions are correctly flattened") + { + const auto &a = actions[0]->effect.value().get>(); + REQUIRE(a->arguments.size() == 3); + + const auto &a1 = a->arguments[0].get().get>()->argument.get(); + CHECK(a1->declaration->name == "p3"); + REQUIRE(a1->arguments.size() == 2); + CHECK(a1->arguments[0].get()->declaration == actions[0]->parameters[0].get()); + CHECK(a1->arguments[1].get()->declaration == actions[0]->parameters[1].get()); + + const auto &a2 = a->arguments[1].get().get().get(); + CHECK(a2->declaration->name == "p9"); + REQUIRE(a2->arguments.size() == 1); + CHECK(a2->arguments[0].get()->declaration == actions[0]->parameters[0].get()); + + const auto &a3 = a->arguments[2].get>(); + const auto &a31 = a3->argumentLeft.get>(); + REQUIRE(a31->arguments.size() == 2); + const auto &a311 = a31->arguments[0].get().get(); + CHECK(a311->declaration->parameters.size() == 1); + CHECK(a311->declaration->existentialParameters.size() == 1); + const auto &a3111 = a311->declaration->precondition.value().get>(); + REQUIRE(a3111->arguments.size() == 2); + const auto &a31111 = a3111->arguments[0].get().get(); + CHECK(a31111->declaration->name == "p7"); + REQUIRE(a31111->arguments.size() == 2); + CHECK(a31111->arguments[0].get()->declaration == a311->declaration->existentialParameters[0].get()); + CHECK(a31111->arguments[1].get()->declaration == actions[0]->parameters[1].get()); + const auto &a31112 = a3111->arguments[1].get().get(); + CHECK(a31112->declaration->name == "p3"); + REQUIRE(a31112->arguments.size() == 2); + CHECK(a31112->arguments[0].get()->declaration == actions[0]->parameters[1].get()); + CHECK(a31112->arguments[1].get()->declaration == a311->declaration->existentialParameters[0].get()); + const auto &a312 = a31->arguments[1].get().get(); + CHECK(a312->declaration->parameters.size() == 0); + CHECK(a312->declaration->existentialParameters.size() == 2); + const auto &a3121 = a312->declaration->precondition.value().get>(); + const auto &a31211 = a3121->arguments[0].get().get(); + CHECK(a31211->declaration->name == "p4"); + REQUIRE(a31211->arguments.size() == 2); + CHECK(a31211->arguments[0].get()->declaration == a312->declaration->existentialParameters[0].get()); + CHECK(a31211->arguments[1].get()->declaration == a312->declaration->existentialParameters[1].get()); + const auto &a31212 = a3121->arguments[1].get().get(); + CHECK(a31212->declaration->name == "p3"); + REQUIRE(a31212->arguments.size() == 2); + CHECK(a31212->arguments[0].get()->declaration == a312->declaration->existentialParameters[1].get()); + CHECK(a31212->arguments[1].get()->declaration == a312->declaration->existentialParameters[0].get()); + } +} diff --git a/tests/data/normalization/normalization-5.pddl b/tests/data/normalization/normalization-5.pddl new file mode 100644 index 0000000..7afb6be --- /dev/null +++ b/tests/data/normalization/normalization-5.pddl @@ -0,0 +1,58 @@ +(define (domain test-normalization) + (:predicates + (p1 ?x ?y) + (p2 ?x ?y) + (p3 ?x ?y) + (p4 ?x ?y) + (p5 ?x ?y ?z) + (p6 ?x ?y ?z) + (p7 ?x ?y) + (p8 ?x) + (p9 ?x)) + + (:action test-action-1 + :parameters + (?x + ?y) + :precondition + (and + (forall + (?z) + (imply + (p1 ?y ?z) + (p2 ?z ?y))) + (p3 ?x ?y) + (or + (and + (p4 ?x ?y) + (forall + (?z) + (imply + (p5 ?z ?x ?y) + (p3 ?z ?y)))) + (and + (p7 ?x ?y) + (not (exists + (?z ?a) + (and + (p6 ?z ?a ?y) + (p3 ?z ?y))))))) + :effect + (and + (not (p3 ?x ?y)) + (p9 ?x) + (when + (and + (not (forall + (?p) + (and + (not (p7 ?p ?y)) + (not (p3 ?y ?p))))) + (exists + (?z ?a) + (or + (p4 ?z ?a) + (p3 ?a ?z)))) + (and + (p8 ?y) + (p9 ?y))))))