Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

An effect part of the condeff should be AndEffect and not And. #119

Merged
merged 9 commits into from
Aug 14, 2024
6 changes: 3 additions & 3 deletions pddl/_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@
from pddl.exceptions import PDDLValidationError
from pddl.helpers.base import check, ensure, ensure_set, find_cycle
from pddl.logic import Predicate
from pddl.logic.base import BinaryOp, QuantifiedCondition, UnaryOp
from pddl.logic.effects import AndEffect, Forall, When
from pddl.logic.base import And, BinaryOp, QuantifiedCondition, UnaryOp
from pddl.logic.effects import Forall, When
from pddl.logic.functions import (
BinaryFunction,
FunctionExpression,
Expand Down Expand Up @@ -285,7 +285,7 @@ def _(self, formula: QuantifiedCondition) -> None:
self.check_type(formula.condition)

@check_type.register
def _(self, effect: AndEffect) -> None:
def _(self, effect: And) -> None:
"""Check types annotations of a PDDL and-effect."""
self.check_type(effect.operands)

Expand Down
51 changes: 4 additions & 47 deletions pddl/logic/effects.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,57 +12,14 @@

"""This modules implements PDDL effects."""
import functools
from typing import AbstractSet, Collection, Generic, Optional, Sequence, TypeVar, Union
from typing import AbstractSet, Collection, Optional, Union

from pddl.helpers.base import _typed_parameters, ensure_set
from pddl.helpers.cache_hash import cache_hash
from pddl.logic import Variable
from pddl.logic.base import Atomic, Formula, Not, OneOf
from pddl.logic.base import And, Atomic, Formula, Not, OneOf
from pddl.parser.symbols import Symbols

EffectType = TypeVar("EffectType")


@cache_hash
@functools.total_ordering
haz marked this conversation as resolved.
Show resolved Hide resolved
class AndEffect(Generic[EffectType]):
"""Conjunction of effects."""

def __init__(self, *operands: EffectType):
"""
Initialize a conjunction of (conditional) effects.

:param operands: the operands.
"""
self._operands = list(operands)

@property
def operands(self) -> Sequence[EffectType]:
"""Get the operands."""
return tuple(self._operands)

def __str__(self) -> str:
"""Get the string representation."""
return f"({Symbols.AND.value} {' '.join(map(str, self.operands))})"

def __repr__(self) -> str:
"""Get an unambiguous string representation."""
return f"{type(self).__name__}({repr(self._operands)})"

def __eq__(self, other):
"""Compare with another object."""
return isinstance(other, type(self)) and self.operands == other.operands

def __lt__(self, other) -> bool:
"""Compare with another object."""
if isinstance(other, AndEffect):
return tuple(self.operands) < tuple(other.operands)
return super().__lt__(other) # type: ignore

def __hash__(self) -> int:
"""Compute the hash of the object."""
return hash((type(self), self.operands))


@cache_hash
@functools.total_ordering
Expand Down Expand Up @@ -167,5 +124,5 @@ def __lt__(self, other):

PEffect = Union[Atomic, Not]
CEffect = Union[Forall, When, OneOf, "PEffect"]
Effect = Union[AndEffect["CEffect"], CEffect]
CondEffect = Union[AndEffect["PEffect"], "PEffect"]
Effect = Union[And, CEffect]
CondEffect = Union[And, "PEffect"]
haz marked this conversation as resolved.
Show resolved Hide resolved
16 changes: 9 additions & 7 deletions pddl/parser/domain.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#

"""Implementation of the PDDL domain parser."""
from typing import Any, Dict, Optional, Set, Tuple
from typing import Any, Dict, List, Optional, Sequence, Set, Tuple

from lark import Lark, ParseError, Transformer

Expand All @@ -21,7 +21,7 @@
from pddl.exceptions import PDDLMissingRequirementError, PDDLParsingError
from pddl.helpers.base import assert_, call_parser
from pddl.logic.base import And, ExistsCondition, ForallCondition, Imply, Not, OneOf, Or
from pddl.logic.effects import AndEffect, Forall, When
from pddl.logic.effects import Forall, When
from pddl.logic.functions import Assign, Decrease, Divide
from pddl.logic.functions import EqualTo as FunctionEqualTo
from pddl.logic.functions import (
Expand Down Expand Up @@ -50,7 +50,7 @@
class DomainTransformer(Transformer[Any, Domain]):
"""Domain Transformer."""

def __init__(self, *args, **kwargs):
def __init__(self, *args, **kwargs) -> None:
"""Initialize the domain transformer."""
super().__init__(*args, **kwargs)

Expand Down Expand Up @@ -258,7 +258,7 @@ def effect(self, args):
if len(args) == 1:
return args[0]
if args[1] == Symbols.AND.value:
return AndEffect(*args[2:-1])
return And(*args[2:-1])
raise ValueError("case not recognized")

def c_effect(self, args):
Expand Down Expand Up @@ -337,10 +337,12 @@ def constant(self, args):
raise ParseError(f"Constant '{args[0]}' not defined.")
return constant

def _formula_skeleton(self, args):
def _formula_skeleton(self, args) -> Sequence[Variable]:
"""Process the '_formula_skeleton' rule."""
variable_data: Dict[str, Set[str]] = args[2]
variables = [Variable(var_name, tags) for var_name, tags in variable_data]
variable_data: Tuple[Tuple[str, Set[str]], ...] = args[2]
haz marked this conversation as resolved.
Show resolved Hide resolved
variables: List[Variable] = [
Variable(var_name, tags) for var_name, tags in variable_data
]
return variables

def atomic_formula_skeleton(self, args):
Expand Down
2 changes: 1 addition & 1 deletion pddl/parser/problem.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
class ProblemTransformer(Transformer[Any, Problem]):
"""Problem Transformer."""

def __init__(self):
def __init__(self) -> None:
"""Initialize the problem transformer."""
super().__init__()

Expand Down
8 changes: 4 additions & 4 deletions tests/fixtures/code_objects/blocksworld_fond.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from pddl.core import Domain, Problem
from pddl.logic import Constant
from pddl.logic.base import And, OneOf
from pddl.logic.effects import AndEffect, When
from pddl.logic.effects import When
from pddl.logic.helpers import constants, variables
from pddl.logic.predicates import EqualTo, Predicate
from pddl.requirements import Requirements
Expand Down Expand Up @@ -52,15 +52,15 @@ def blocksworld_fond_domain():
& ~EqualTo(x, table)
)
put_on_effect = OneOf(
AndEffect(
And(
on(x, y),
~on(x, z),
When(~EqualTo(z, table), clear(z)),
When(~EqualTo(y, table), ~clear(y)),
),
AndEffect(
And(
on(x, table),
When(~EqualTo(z, table), ~on(x, z) & clear(z)),
When(~EqualTo(z, table), And(~on(x, z), clear(z))),
When(~EqualTo(y, table), ~clear(y)),
),
)
Expand Down
23 changes: 10 additions & 13 deletions tests/fixtures/code_objects/blocksworld_ipc08.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
from pddl.action import Action
from pddl.core import Domain, Problem
from pddl.logic.base import And, OneOf
from pddl.logic.effects import AndEffect
from pddl.logic.helpers import constants, variables
from pddl.logic.predicates import EqualTo, Predicate
from pddl.requirements import Requirements
Expand Down Expand Up @@ -48,8 +47,8 @@ def blocksworld_domain():
pick_up_parameters = [b1, b2]
pick_up_precondition = ~EqualTo(b1, b2) & emptyhand & clear(b1) & on(b1, b2)
pick_up_effect = OneOf(
AndEffect(holding(b1), clear(b2), ~emptyhand, ~clear(b1), ~on(b1, b2)),
AndEffect(clear(b2), on_table(b1), ~on(b1, b2)),
And(holding(b1), clear(b2), ~emptyhand, ~clear(b1), ~on(b1, b2)),
And(clear(b2), on_table(b1), ~on(b1, b2)),
)
pick_up = Action(
pick_up_name, pick_up_parameters, pick_up_precondition, pick_up_effect
Expand All @@ -59,9 +58,7 @@ def blocksworld_domain():
pick_up_from_table_name = "pick-up-from-table"
pick_up_from_table_parameters = [b]
pick_up_from_table_precondition = emptyhand & clear(b) & on_table(b)
pick_up_from_table_effect = OneOf(
AndEffect(), AndEffect(holding(b), ~emptyhand, ~on_table(b))
)
pick_up_from_table_effect = OneOf(And(), And(holding(b), ~emptyhand, ~on_table(b)))
pick_up_from_table = Action(
pick_up_from_table_name,
pick_up_from_table_parameters,
Expand All @@ -74,8 +71,8 @@ def blocksworld_domain():
put_on_block_parameters = [b1, b2]
put_on_block_precondition = holding(b1) & clear(b2)
put_on_block_effect = OneOf(
AndEffect(on(b1, b2), emptyhand, clear(b1), ~holding(b1), ~clear(b2)),
AndEffect(on_table(b1), emptyhand, clear(b1), ~holding(b1)),
And(on(b1, b2), emptyhand, clear(b1), ~holding(b1), ~clear(b2)),
And(on_table(b1), emptyhand, clear(b1), ~holding(b1)),
)
put_on_block = Action(
put_on_block_name,
Expand All @@ -88,7 +85,7 @@ def blocksworld_domain():
put_down_name = "put-down"
put_down_parameters = [b]
put_down_precondition = holding(b)
put_down_effect = AndEffect(on_table(b), emptyhand, clear(b), ~holding(b))
put_down_effect = And(on_table(b), emptyhand, clear(b), ~holding(b))
put_down = Action(
put_down_name, put_down_parameters, put_down_precondition, put_down_effect
)
Expand All @@ -97,7 +94,7 @@ def blocksworld_domain():
pick_tower_parameters = [b1, b2, b3]
pick_tower_precondition = emptyhand & on(b1, b2) & on(b2, b3)
pick_tower_effect = OneOf(
AndEffect(), AndEffect(holding(b2), clear(b3), ~emptyhand, ~on(b2, b3))
And(), And(holding(b2), clear(b3), ~emptyhand, ~on(b2, b3))
)
pick_tower = Action(
pick_tower_name,
Expand All @@ -111,8 +108,8 @@ def blocksworld_domain():
put_tower_on_block_parameters = [b1, b2, b3]
put_tower_on_block_precondition = holding(b2) & on(b1, b2) & clear(b3)
put_tower_on_block_effect = OneOf(
AndEffect(on(b2, b3), emptyhand, ~holding(b2), ~clear(b3)),
AndEffect(on_table(b2), emptyhand, ~holding(b2)),
And(on(b2, b3), emptyhand, ~holding(b2), ~clear(b3)),
And(on_table(b2), emptyhand, ~holding(b2)),
)
put_tower_on_block = Action(
put_tower_on_block_name,
Expand All @@ -125,7 +122,7 @@ def blocksworld_domain():
put_tower_down_name = "put-tower-down"
put_tower_down_parameters = [b1, b2]
put_tower_down_precondition = holding(b2) & on(b1, b2)
put_tower_down_effect = AndEffect(on_table(b2), emptyhand, ~holding(b2))
put_tower_down_effect = And(on_table(b2), emptyhand, ~holding(b2))
put_tower_down = Action(
put_tower_down_name,
put_tower_down_parameters,
Expand Down
9 changes: 4 additions & 5 deletions tests/fixtures/code_objects/triangle_tireworld.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
from pddl.action import Action
from pddl.core import Domain, Problem
from pddl.logic.base import And, OneOf
from pddl.logic.effects import AndEffect
from pddl.logic.helpers import constants, variables
from pddl.logic.predicates import Predicate
from pddl.requirements import Requirements
Expand Down Expand Up @@ -46,10 +45,10 @@ def triangle_tireworld_domain():
move_car_name = "move-car"
move_car_parameters = [from_, to]
move_car_precondition = vehicleat(from_) & road(from_, to) & not_flattire
move_car_effect = AndEffect(
move_car_effect = And(
OneOf(
AndEffect(vehicleat(to), ~vehicleat(from_)),
AndEffect(vehicleat(to), ~vehicleat(from_), ~not_flattire),
And(vehicleat(to), ~vehicleat(from_)),
And(vehicleat(to), ~vehicleat(from_), ~not_flattire),
)
)
move_car = Action(
Expand All @@ -60,7 +59,7 @@ def triangle_tireworld_domain():
changetire_name = "changetire"
changetire_parameters = [loc]
changetire_precondition = spare_in(loc) & vehicleat(loc)
changetire_effect = AndEffect(~spare_in(loc), not_flattire)
changetire_effect = And(~spare_in(loc), not_flattire)
changetire = Action(
changetire_name,
changetire_parameters,
Expand Down
7 changes: 3 additions & 4 deletions tests/test_formatter.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@
from pddl.core import Domain, Problem
from pddl.formatter import domain_to_string, problem_to_string
from pddl.logic import Constant, Variable, constants
from pddl.logic.base import ForallCondition
from pddl.logic.effects import AndEffect
from pddl.logic.base import And, ForallCondition
from pddl.logic.functions import (
EqualTo,
GreaterEqualThan,
Expand Down Expand Up @@ -119,7 +118,7 @@ def test_numerical_hello_world_domain_formatter():
"say-hello-world",
parameters=[neighbor],
precondition=LesserEqualThan(hello_counter, NumericValue(3)),
effect=AndEffect(Increase(hello_counter, NumericValue(1))),
effect=And(Increase(hello_counter, NumericValue(1))),
)

domain = Domain(
Expand All @@ -137,7 +136,7 @@ def test_numerical_hello_world_domain_formatter():
" (:action say-hello-world",
" :parameters (?neighbor)",
" :precondition (<= (hello_counter ?neighbor) 3)",
" :effect (and (increase (hello_counter ?neighbor) 1))",
" :effect (increase (hello_counter ?neighbor) 1)",
haz marked this conversation as resolved.
Show resolved Hide resolved
" )",
")",
)
Expand Down
Loading