From 12e55da6627d5f76f901e6c95b320895a5556a91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20L=C3=BChne?= Date: Wed, 21 Jun 2017 22:54:07 +0200 Subject: [PATCH] =?UTF-8?q?Allowing=20=E2=80=9Cat=E2=80=9D=20as=20a=20pred?= =?UTF-8?q?icate=20name=20even=20though=20it=20is=20an=20expression=20iden?= =?UTF-8?q?tifier.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/pddlparse/detail/parsing/Fact.cpp | 15 +- lib/pddlparse/tests/TestIssues.cpp | 26 +++ tests/data/issues/issue-10.pddl | 160 ++++++++++++++++++ 3 files changed, 197 insertions(+), 4 deletions(-) create mode 100644 tests/data/issues/issue-10.pddl diff --git a/lib/pddlparse/src/pddlparse/detail/parsing/Fact.cpp b/lib/pddlparse/src/pddlparse/detail/parsing/Fact.cpp index 02806a4..0553df5 100644 --- a/lib/pddlparse/src/pddlparse/detail/parsing/Fact.cpp +++ b/lib/pddlparse/src/pddlparse/detail/parsing/Fact.cpp @@ -26,8 +26,7 @@ std::experimental::optional parseFact(Context &context, ASTContext &a tokenizer.expect("("); tokenizer.skipWhiteSpace(); - if (tokenizer.testIdentifierAndReturn("=") - || tokenizer.testIdentifierAndReturn("at")) + if (tokenizer.testIdentifierAndReturn("=")) { tokenizer.seek(position); return parseUnsupported(context); @@ -39,12 +38,20 @@ std::experimental::optional parseFact(Context &context, ASTContext &a std::experimental::optional fact; if ((fact = parseNot(context, astContext, variableStack, parseAtomicFormula)) - || (fact = parseAtomicFormula(context, astContext, variableStack))) + || (fact = parseAtomicFormula(context, astContext, variableStack))) { return std::move(fact.value()); } - return parseAtomicFormula(context, astContext, variableStack); + // Test for “at” expressions only now to allow “at” as a predicate name + // TODO: allow this in compatibility mode only? + if (tokenizer.testIdentifierAndReturn("at")) + { + tokenizer.seek(position); + return parseUnsupported(context); + } + + return std::experimental::nullopt; } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/lib/pddlparse/tests/TestIssues.cpp b/lib/pddlparse/tests/TestIssues.cpp index cf65073..5361740 100644 --- a/lib/pddlparse/tests/TestIssues.cpp +++ b/lib/pddlparse/tests/TestIssues.cpp @@ -60,4 +60,30 @@ TEST_CASE("[PDDL parser issues] Check past issues", "[PDDL parser issues]") context.tokenizer.read(domainFile); CHECK_THROWS(pddl::parseDescription(context)); } + + // Check that “at” is allowed as a predicate name and not exclusively for “at” expressions + SECTION("“at” as predicate name") + { + const auto domainFile = fs::path("data") / "issues" / "issue-10.pddl"; + context.tokenizer.read(domainFile); + + const auto description = pddl::parseDescription(context); + + REQUIRE(description.problem); + + const auto &problem = description.problem.value(); + const auto &facts = problem->initialState.facts; + + const auto invalidFact = std::find_if(facts.cbegin(), facts.cend(), + [](const auto &fact) + { + return + fact.template is>() + || (fact.template is() && fact.template get().template is()); + }); + + const auto containsInvalidFact = (invalidFact != facts.cend()); + + CHECK(!containsInvalidFact); + } } diff --git a/tests/data/issues/issue-10.pddl b/tests/data/issues/issue-10.pddl new file mode 100644 index 0000000..986f3b1 --- /dev/null +++ b/tests/data/issues/issue-10.pddl @@ -0,0 +1,160 @@ +(define (domain logistics-strips) + (:requirements :strips) + (:predicates (OBJ ?obj) + (TRUCK ?truck) + (LOCATION ?loc) + (AIRPLANE ?airplane) + (CITY ?city) + (AIRPORT ?airport) + (at ?obj ?loc) + (in ?obj1 ?obj2) + (in-city ?obj ?city)) + + ; (:types ) ; default object + +(:action LOAD-TRUCK + :parameters + (?obj + ?truck + ?loc) + :precondition + (and (OBJ ?obj) (TRUCK ?truck) (LOCATION ?loc) + (at ?truck ?loc) (at ?obj ?loc)) + :effect + (and (not (at ?obj ?loc)) (in ?obj ?truck))) + +(:action LOAD-AIRPLANE + :parameters + (?obj + ?airplane + ?loc) + :precondition + (and (OBJ ?obj) (AIRPLANE ?airplane) (LOCATION ?loc) + (at ?obj ?loc) (at ?airplane ?loc)) + :effect + (and (not (at ?obj ?loc)) (in ?obj ?airplane))) + +(:action UNLOAD-TRUCK + :parameters + (?obj + ?truck + ?loc) + :precondition + (and (OBJ ?obj) (TRUCK ?truck) (LOCATION ?loc) + (at ?truck ?loc) (in ?obj ?truck)) + :effect + (and (not (in ?obj ?truck)) (at ?obj ?loc))) + +(:action UNLOAD-AIRPLANE + :parameters + (?obj + ?airplane + ?loc) + :precondition + (and (OBJ ?obj) (AIRPLANE ?airplane) (LOCATION ?loc) + (in ?obj ?airplane) (at ?airplane ?loc)) + :effect + (and (not (in ?obj ?airplane)) (at ?obj ?loc))) + +(:action DRIVE-TRUCK + :parameters + (?truck + ?loc-from + ?loc-to + ?city) + :precondition + (and (TRUCK ?truck) (LOCATION ?loc-from) (LOCATION ?loc-to) (CITY ?city) + (at ?truck ?loc-from) + (in-city ?loc-from ?city) + (in-city ?loc-to ?city)) + :effect + (and (not (at ?truck ?loc-from)) (at ?truck ?loc-to))) + +(:action FLY-AIRPLANE + :parameters + (?airplane + ?loc-from + ?loc-to) + :precondition + (and (AIRPLANE ?airplane) (AIRPORT ?loc-from) (AIRPORT ?loc-to) + (at ?airplane ?loc-from)) + :effect + (and (not (at ?airplane ?loc-from)) (at ?airplane ?loc-to))) +) +(define (problem strips-log-x-1) + (:domain logistics-strips) + (:objects package6 package5 package4 package3 package2 package1 + city6 city5 city4 city3 city2 city1 truck6 truck5 truck4 + truck3 truck2 truck1 plane2 plane1 city6-1 city5-1 city4-1 + city3-1 city2-1 city1-1 city6-2 city5-2 city4-2 city3-2 + city2-2 city1-2) + (:init (obj package6) + (obj package5) + (obj package4) + (obj package3) + (obj package2) + (obj package1) + (city city6) + (city city5) + (city city4) + (city city3) + (city city2) + (city city1) + (truck truck6) + (truck truck5) + (truck truck4) + (truck truck3) + (truck truck2) + (truck truck1) + (airplane plane2) + (airplane plane1) + (location city6-1) + (location city5-1) + (location city4-1) + (location city3-1) + (location city2-1) + (location city1-1) + (airport city6-2) + (location city6-2) + (airport city5-2) + (location city5-2) + (airport city4-2) + (location city4-2) + (airport city3-2) + (location city3-2) + (airport city2-2) + (location city2-2) + (airport city1-2) + (location city1-2) + (in-city city6-2 city6) + (in-city city6-1 city6) + (in-city city5-2 city5) + (in-city city5-1 city5) + (in-city city4-2 city4) + (in-city city4-1 city4) + (in-city city3-2 city3) + (in-city city3-1 city3) + (in-city city2-2 city2) + (in-city city2-1 city2) + (in-city city1-2 city1) + (in-city city1-1 city1) + (at plane2 city4-2) + (at plane1 city4-2) + (at truck6 city6-1) + (at truck5 city5-1) + (at truck4 city4-1) + (at truck3 city3-1) + (at truck2 city2-1) + (at truck1 city1-1) + (at package6 city3-1) + (at package5 city4-2) + (at package4 city1-1) + (at package3 city1-1) + (at package2 city1-2) + (at package1 city2-1)) + (:goal (and (at package6 city1-2) + (at package5 city6-2) + (at package4 city3-2) + (at package3 city6-1) + (at package2 city6-2) + (at package1 city2-1))))