Skip to content

Commit

Permalink
add total cost and metric classes, and fix formatting issues
Browse files Browse the repository at this point in the history
  • Loading branch information
francescofuggitti committed Oct 9, 2023
1 parent b3d9d1d commit 004b842
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 1 deletion.
3 changes: 2 additions & 1 deletion pddl/custom_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,8 @@ def to_types(names: Dict[namelike, Optional[namelike]]) -> Dict[name, Optional[n
def _is_a_keyword(word: str, ignore: Optional[AbstractSet[str]] = None) -> bool:
"""Check that the word is not a keyword."""
ignore_set = ensure_set(ignore)
return word not in ignore_set and word in ALL_SYMBOLS
# we remove the TOTAL_COST because it is not a keyword but a special function
return word not in ignore_set and word in ALL_SYMBOLS - {Symbols.TOTAL_COST.value}


def _check_not_a_keyword(
Expand Down
1 change: 1 addition & 0 deletions pddl/formatter.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ def problem_to_string(problem: Problem) -> str:
"(:init ", problem.init, ")\n", is_mandatory=True
)
body += f"{'(:goal ' + str(problem.goal) + ')'}\n"
body += f"{'(:metric ' + str(problem.metric) + ')'}\n" if problem.metric else ""
result = result + "\n" + indent(body, indentation) + "\n)"
result = _remove_empty_lines(result)
return result
63 changes: 63 additions & 0 deletions pddl/logic/functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,69 @@ def __lt__(self, other):
return super().__lt__(other)


class TotalCost(Function):
"""A class for the total-cost function in PDDL."""

def __init__(self):
"""Initialize the function."""
super().__init__("total-cost")


class Metric(Atomic):
"""A class for the metric function in PDDL."""

MINIMIZE = "minimize"
MAXIMIZE = "maximize"

def __init__(self, function: Function, optimization: str = MINIMIZE):
"""
Initialize the metric function.
:param function: function to minimize or maximize.
:param optimization: whether to minimize or maximize the function.
"""
self._function = function
self._optimization = optimization
self._validate()

@property
def function(self) -> Function:
"""Get the function."""
return self._function

@property
def optimization(self) -> str:
"""Get the optimization."""
return self._optimization

def _validate(self):
"""Validate the metric."""
assert_(
self.optimization in {self.MAXIMIZE, self.MINIMIZE},
"Optimization metric not recognized.",
)

def __str__(self) -> str:
"""Get the string representation."""
return f"{self.optimization} {self.function}"

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

def __eq__(self, other):
"""Override equal operator."""
return (
isinstance(other, Metric)
and self.function == other.function
and self.optimization == other.optimization
)

def __hash__(self):
"""Get the hash of a Metric."""
return hash((self.function, self.optimization))


class FunctionOperator(Atomic):
"""Operator for to numerical fluent."""

Expand Down
3 changes: 3 additions & 0 deletions pddl/parser/symbols.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ class Symbols(Enum):
PROBLEM = "problem"
REQUIREMENTS = ":requirements"
TYPES = ":types"
METRIC = ":metric"
WHEN = "when"
GREATER_EQUAL = ">="
GREATER = ">"
Expand All @@ -58,6 +59,7 @@ class Symbols(Enum):
ASSIGN = "assign"
INCREASE = "increase"
DECREASE = "decrease"
TOTAL_COST = "total-cost"


ALL_SYMBOLS: Set[str] = {v.value for v in Symbols}
Expand All @@ -83,6 +85,7 @@ class RequirementSymbols(Enum):
NON_DETERMINISTIC = ":non-deterministic"
FLUENTS = ":fluents"
NUMERIC_FLUENTS = ":numeric-fluents"
ACTION_COSTS = ":action-costs"

def strip(self) -> str:
"""Strip the leading colon."""
Expand Down
1 change: 1 addition & 0 deletions pddl/requirements.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ class Requirements(Enum):
NON_DETERMINISTIC = RS.NON_DETERMINISTIC.strip()
FLUENTS = RS.FLUENTS.strip()
NUMERIC_FLUENTS = RS.NUMERIC_FLUENTS.strip()
ACTION_COSTS = RS.ACTION_COSTS.strip()

@classmethod
def quantified_precondition_requirements(cls) -> Set["Requirements"]:
Expand Down

0 comments on commit 004b842

Please sign in to comment.