From ef4ea955f4e042543ed717c1ef92bc0c8eec04d4 Mon Sep 17 00:00:00 2001 From: Francesco Fuggitti Date: Wed, 27 Sep 2023 17:48:29 -0400 Subject: [PATCH 1/4] fix issue #87 about allowing typing when specifying adl requirements --- pddl/_validation.py | 5 +++-- pddl/parser/domain.py | 7 ++----- pddl/requirements.py | 27 ++++++++++++++++++++++++++- 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/pddl/_validation.py b/pddl/_validation.py index d5f76fdc..22e42f6e 100644 --- a/pddl/_validation.py +++ b/pddl/_validation.py @@ -27,7 +27,7 @@ from pddl.logic.predicates import DerivedPredicate, EqualTo from pddl.logic.terms import Term from pddl.parser.symbols import Symbols -from pddl.requirements import Requirements +from pddl.requirements import Requirements, _extend_domain_requirements def validate(condition: bool, message: str = "") -> None: @@ -193,7 +193,8 @@ def __init__( @property def has_typing(self) -> bool: """Check if the typing requirement is specified.""" - return Requirements.TYPING in self._requirements + self._extended_requirements = _extend_domain_requirements(self._requirements) + return Requirements.TYPING in self._extended_requirements def _check_typing_requirement(self, type_tags: Collection[name_type]) -> None: """Check that the typing requirement is specified.""" diff --git a/pddl/parser/domain.py b/pddl/parser/domain.py index f0cf83bf..d9999bce 100644 --- a/pddl/parser/domain.py +++ b/pddl/parser/domain.py @@ -28,7 +28,7 @@ from pddl.parser import DOMAIN_GRAMMAR_FILE, PARSERS_DIRECTORY from pddl.parser.symbols import Symbols from pddl.parser.typed_list_parser import TypedListParser -from pddl.requirements import Requirements +from pddl.requirements import Requirements, _extend_domain_requirements class DomainTransformer(Transformer): @@ -72,10 +72,7 @@ def domain_def(self, args): def requirements(self, args): """Process the 'requirements' rule.""" self._requirements = {Requirements(r[1:]) for r in args[2:-1]} - - self._extended_requirements = set(self._requirements) - if Requirements.STRIPS in self._requirements: - self._extended_requirements.update(Requirements.strips_requirements()) + self._extended_requirements = _extend_domain_requirements(self._requirements) return dict(requirements=self._requirements) diff --git a/pddl/requirements.py b/pddl/requirements.py index 22622d06..56ae1af2 100644 --- a/pddl/requirements.py +++ b/pddl/requirements.py @@ -13,7 +13,7 @@ """This module contains the definition of the PDDL requirements.""" import functools from enum import Enum -from typing import Set +from typing import AbstractSet, Set from pddl.parser.symbols import RequirementSymbols as RS @@ -46,6 +46,19 @@ def strips_requirements(cls) -> Set["Requirements"]: Requirements.CONDITIONAL_EFFECTS, } + @classmethod + def adl_requirements(cls) -> Set["Requirements"]: + """Get the ADL requirements.""" + return { + Requirements.STRIPS, + Requirements.TYPING, + Requirements.NEG_PRECONDITION, + Requirements.DIS_PRECONDITION, + Requirements.EQUALITY, + Requirements.QUANTIFIED_PRECONDITION, + Requirements.CONDITIONAL_EFFECTS, + } + def __str__(self) -> str: """Get the string representation.""" return f":{self.value}" @@ -60,3 +73,15 @@ def __lt__(self, other): return self.value <= other.value else: return super().__lt__(other) + + +def _extend_domain_requirements( + requirements: AbstractSet[Requirements], +) -> Set[Requirements]: + """Extend the requirements with the domain requirements.""" + extended_requirements = set(requirements) + if Requirements.STRIPS in requirements: + extended_requirements.update(Requirements.strips_requirements()) + if Requirements.ADL in requirements: + extended_requirements.update(Requirements.adl_requirements()) + return extended_requirements From 0354e203be0349a80201a494c4d7315b61b43b7f Mon Sep 17 00:00:00 2001 From: Francesco Fuggitti Date: Wed, 27 Sep 2023 17:48:41 -0400 Subject: [PATCH 2/4] add test --- tests/test_parser/test_domain.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/tests/test_parser/test_domain.py b/tests/test_parser/test_domain.py index 5019456b..ebe67893 100644 --- a/tests/test_parser/test_domain.py +++ b/tests/test_parser/test_domain.py @@ -121,6 +121,30 @@ def test_types_repetition_in_typed_lists_not_allowed() -> None: DomainParser()(domain_str) +def test_typing_requirement_under_other_domain_requirements() -> None: + """Check :typing requirement does not throw error if other domain requirements that includes it are detected.""" + domain_str = dedent( + """ +(define (domain tictactoe) + (:requirements :adl) + (:types a b c) + (:predicates + (predicate1 ?x - a) + (predicate2 ?x - b) + (predicate3 ?x - c) + ) + ) + """ + ) + + domain = DomainParser()(domain_str) + assert domain.types == { + "a": None, + "b": None, + "c": None, + } + + @pytest.mark.parametrize("keyword", TEXT_SYMBOLS - {Symbols.OBJECT.value}) def test_keyword_usage_not_allowed_as_name(keyword) -> None: """Check keywords usage as names is detected and a parsing error is raised.""" From e28585f8b7ce6441674a73b7e6479ee22284404b Mon Sep 17 00:00:00 2001 From: Francesco Fuggitti Date: Thu, 28 Sep 2023 11:58:29 -0400 Subject: [PATCH 3/4] fix strips requirements --- pddl/requirements.py | 18 +++++++----------- tests/test_parser/test_domain.py | 2 +- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/pddl/requirements.py b/pddl/requirements.py index 56ae1af2..543eaedc 100644 --- a/pddl/requirements.py +++ b/pddl/requirements.py @@ -36,14 +36,11 @@ class Requirements(Enum): NON_DETERMINISTIC = RS.NON_DETERMINISTIC.strip() @classmethod - def strips_requirements(cls) -> Set["Requirements"]: - """Get the STRIPS requirements.""" + def quantified_precondition_requirements(cls) -> Set["Requirements"]: + """Get the quantified precondition requirements.""" return { - Requirements.TYPING, - Requirements.NEG_PRECONDITION, - Requirements.DIS_PRECONDITION, - Requirements.EQUALITY, - Requirements.CONDITIONAL_EFFECTS, + Requirements.UNIVERSAL_PRECONDITION, + Requirements.EXISTENTIAL_PRECONDITION, } @classmethod @@ -55,9 +52,8 @@ def adl_requirements(cls) -> Set["Requirements"]: Requirements.NEG_PRECONDITION, Requirements.DIS_PRECONDITION, Requirements.EQUALITY, - Requirements.QUANTIFIED_PRECONDITION, Requirements.CONDITIONAL_EFFECTS, - } + }.union(cls.quantified_precondition_requirements()) def __str__(self) -> str: """Get the string representation.""" @@ -80,8 +76,8 @@ def _extend_domain_requirements( ) -> Set[Requirements]: """Extend the requirements with the domain requirements.""" extended_requirements = set(requirements) - if Requirements.STRIPS in requirements: - extended_requirements.update(Requirements.strips_requirements()) + if Requirements.QUANTIFIED_PRECONDITION in requirements: + extended_requirements.update(Requirements.quantified_precondition_requirements()) if Requirements.ADL in requirements: extended_requirements.update(Requirements.adl_requirements()) return extended_requirements diff --git a/tests/test_parser/test_domain.py b/tests/test_parser/test_domain.py index ebe67893..c193b651 100644 --- a/tests/test_parser/test_domain.py +++ b/tests/test_parser/test_domain.py @@ -125,7 +125,7 @@ def test_typing_requirement_under_other_domain_requirements() -> None: """Check :typing requirement does not throw error if other domain requirements that includes it are detected.""" domain_str = dedent( """ -(define (domain tictactoe) +(define (domain test) (:requirements :adl) (:types a b c) (:predicates From d61e692d1d070d52c4da25c96b0efef399353d59 Mon Sep 17 00:00:00 2001 From: Francesco Fuggitti Date: Thu, 28 Sep 2023 11:59:16 -0400 Subject: [PATCH 4/4] apply style --- pddl/requirements.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pddl/requirements.py b/pddl/requirements.py index 543eaedc..91a5ebc6 100644 --- a/pddl/requirements.py +++ b/pddl/requirements.py @@ -77,7 +77,9 @@ def _extend_domain_requirements( """Extend the requirements with the domain requirements.""" extended_requirements = set(requirements) if Requirements.QUANTIFIED_PRECONDITION in requirements: - extended_requirements.update(Requirements.quantified_precondition_requirements()) + extended_requirements.update( + Requirements.quantified_precondition_requirements() + ) if Requirements.ADL in requirements: extended_requirements.update(Requirements.adl_requirements()) return extended_requirements