From e1227b51f45386490314ad0456cb861e00def4bb Mon Sep 17 00:00:00 2001 From: Christian Muise Date: Thu, 28 Dec 2023 10:32:21 -0500 Subject: [PATCH 1/3] Some minor touchup to preconditions and fix for minus. --- pddl/parser/domain.lark | 6 ++---- pddl/parser/domain.py | 7 ++++++- pddl/parser/problem.py | 7 ++++++- tests/test_parser/test_domain.py | 28 ++++++++++++++++++++++++++++ 4 files changed, 42 insertions(+), 6 deletions(-) diff --git a/pddl/parser/domain.lark b/pddl/parser/domain.lark index 6703c10..6784fa2 100644 --- a/pddl/parser/domain.lark +++ b/pddl/parser/domain.lark @@ -67,8 +67,7 @@ constant: NAME | GREATER_EQUAL_OP | LESSER_EQUAL_OP -?binary_op: multi_op - | MINUS +?binary_op: MINUS | DIVIDE ?multi_op: TIMES @@ -76,8 +75,7 @@ constant: NAME f_exp: NUMBER | LPAR binary_op f_exp f_exp RPAR - | LPAR multi_op f_exp f_exp+ RPAR - | LPAR MINUS f_exp RPAR + | LPAR multi_op f_exp+ RPAR | f_head f_head: NAME diff --git a/pddl/parser/domain.py b/pddl/parser/domain.py index e08bfdd..afd2aa1 100644 --- a/pddl/parser/domain.py +++ b/pddl/parser/domain.py @@ -462,8 +462,13 @@ def __init__(self): def __call__(self, text): """Call.""" + def handle_debug(e): + print("\nLocation of parse error:") + print(e.get_context(text)) + print(e.interactive_parser.pretty()) + print() sys.tracebacklimit = 0 # noqa - tree = self._parser.parse(text) + tree = self._parser.parse(text, on_error=handle_debug) sys.tracebacklimit = None # noqa formula = self._transformer.transform(tree) return formula diff --git a/pddl/parser/problem.py b/pddl/parser/problem.py index 2ca8856..2d14f58 100644 --- a/pddl/parser/problem.py +++ b/pddl/parser/problem.py @@ -244,8 +244,13 @@ def __init__(self): def __call__(self, text): """Call.""" + def handle_debug(e): + print("\nLocation of parse error:") + print(e.get_context(text)) + print(e.interactive_parser.pretty()) + print() sys.tracebacklimit = 0 # noqa - tree = self._parser.parse(text) + tree = self._parser.parse(text, on_error=handle_debug) sys.tracebacklimit = None # noqa formula = self._transformer.transform(tree) return formula diff --git a/tests/test_parser/test_domain.py b/tests/test_parser/test_domain.py index b41b480..974d86d 100644 --- a/tests/test_parser/test_domain.py +++ b/tests/test_parser/test_domain.py @@ -317,3 +317,31 @@ def test_check_action_costs_requirement_with_total_cost() -> None: match=r"action costs requirement is not specified, but the total-cost function is specified.", ): DomainParser()(domain_str) + + +def test_minus_in_precondition() -> None: + """Check minus in precondition.""" + domain_str = dedent( + """ + (define (domain cant-subtract-in-precondition) + (:requirements :strips :typing :numeric-fluents) + + (:types + agent - object + ) + + (:functions + (x ?l - agent) + ) + + (:action move-south + :parameters (?ag - agent) + :precondition (and + (< (- (x ?ag) 1) 1) + ) + :effect (and (decrease (x ?ag) 1)) + ) + ) + """ + ) + DomainParser()(domain_str) From 3d949f3d2007fcc6f96d225710cc2cda62688b0e Mon Sep 17 00:00:00 2001 From: Christian Muise Date: Thu, 28 Dec 2023 10:36:22 -0500 Subject: [PATCH 2/3] Missed spacing. --- pddl/parser/domain.py | 2 ++ pddl/parser/problem.py | 2 ++ 2 files changed, 4 insertions(+) diff --git a/pddl/parser/domain.py b/pddl/parser/domain.py index afd2aa1..4cf04fe 100644 --- a/pddl/parser/domain.py +++ b/pddl/parser/domain.py @@ -462,11 +462,13 @@ def __init__(self): def __call__(self, text): """Call.""" + def handle_debug(e): print("\nLocation of parse error:") print(e.get_context(text)) print(e.interactive_parser.pretty()) print() + sys.tracebacklimit = 0 # noqa tree = self._parser.parse(text, on_error=handle_debug) sys.tracebacklimit = None # noqa diff --git a/pddl/parser/problem.py b/pddl/parser/problem.py index 2d14f58..8f6d868 100644 --- a/pddl/parser/problem.py +++ b/pddl/parser/problem.py @@ -244,11 +244,13 @@ def __init__(self): def __call__(self, text): """Call.""" + def handle_debug(e): print("\nLocation of parse error:") print(e.get_context(text)) print(e.interactive_parser.pretty()) print() + sys.tracebacklimit = 0 # noqa tree = self._parser.parse(text, on_error=handle_debug) sys.tracebacklimit = None # noqa From c44a7bcfd26c692873e7cee48797dbd5f8a45a14 Mon Sep 17 00:00:00 2001 From: Christian Muise Date: Thu, 28 Dec 2023 13:55:11 -0500 Subject: [PATCH 3/3] Workaround to have minus work as negation. --- pddl/parser/domain.lark | 1 + pddl/parser/domain.py | 7 ++++++- tests/test_parser/test_domain.py | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/pddl/parser/domain.lark b/pddl/parser/domain.lark index 6784fa2..9460cbe 100644 --- a/pddl/parser/domain.lark +++ b/pddl/parser/domain.lark @@ -76,6 +76,7 @@ constant: NAME f_exp: NUMBER | LPAR binary_op f_exp f_exp RPAR | LPAR multi_op f_exp+ RPAR + | LPAR MINUS f_exp+ RPAR | f_head f_head: NAME diff --git a/pddl/parser/domain.py b/pddl/parser/domain.py index 4cf04fe..394758e 100644 --- a/pddl/parser/domain.py +++ b/pddl/parser/domain.py @@ -368,7 +368,12 @@ def f_exp(self, args): return args[0] op = None if args[1] == Symbols.MINUS.value: - op = Minus + if len(args[2:-1]) == 1: + return Times(NumericValue(-1), args[2]) + elif len(args[2:-1]) == 2: + op = Minus + else: + raise PDDLParsingError(f"MINUS symbol used with {len(args[2:-1])} args") if args[1] == Symbols.PLUS.value: op = Plus if args[1] == Symbols.TIMES.value: diff --git a/tests/test_parser/test_domain.py b/tests/test_parser/test_domain.py index 974d86d..bd9849a 100644 --- a/tests/test_parser/test_domain.py +++ b/tests/test_parser/test_domain.py @@ -338,6 +338,7 @@ def test_minus_in_precondition() -> None: :parameters (?ag - agent) :precondition (and (< (- (x ?ag) 1) 1) + (< (- (x ?ag)) 1) ) :effect (and (decrease (x ?ag) 1)) ) @@ -345,3 +346,34 @@ def test_minus_in_precondition() -> None: """ ) DomainParser()(domain_str) + + +def test_multi_minus_in_precondition() -> None: + """Check minus in precondition.""" + domain_str = dedent( + """ + (define (domain cant-subtract-in-precondition) + (:requirements :strips :typing :numeric-fluents) + + (:types + agent - object + ) + + (:functions + (x ?l - agent) + ) + + (:action move-south + :parameters (?ag - agent) + :precondition (and + (< (- (x ?ag) 1 3) 1) + ) + :effect (and (decrease (x ?ag) 1)) + ) + ) + """ + ) + try: + DomainParser()(domain_str) + except Exception as e: + assert "MINUS symbol used with 3 args" in str(e)