Skip to content

Commit

Permalink
Updated semantic of DISCRETE_NUMBERS and CONTINUOUS_NUMBERS
Browse files Browse the repository at this point in the history
  • Loading branch information
alvalentini committed Jul 6, 2023
1 parent f9eba25 commit cfeb48c
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 25 deletions.
5 changes: 1 addition & 4 deletions unified_planning/io/ma_pddl_writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,10 +175,7 @@ def _write_domain(self):
out.write(" :disjunctive-preconditions")
if self.problem_kind.has_equalities():
out.write(" :equality")
if (
self.problem_kind.has_continuous_numbers()
or self.problem_kind.has_discrete_numbers()
):
if self.problem_kind.has_numeric_fluents():
out.write(" :numeric-fluents")
if self.problem_kind.has_conditional_effects():
out.write(" :conditional-effects")
Expand Down
3 changes: 1 addition & 2 deletions unified_planning/io/pddl_writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -400,8 +400,7 @@ def _write_domain(self, out: IO[str]):
if self.problem_kind.has_equalities():
out.write(" :equality")
if (
self.problem_kind.has_continuous_numbers()
or self.problem_kind.has_discrete_numbers()
self.problem_kind.has_numeric_fluents()
or self.problem_kind.has_fluents_in_actions_cost()
):
out.write(" :numeric-fluents")
Expand Down
46 changes: 38 additions & 8 deletions unified_planning/model/mixins/metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,11 @@ def _update_kind_metric(
metric, up.model.metrics.MinimizeExpressionOnFinalState
)
kind.set_quality_metrics("FINAL_VALUE")
t = metric.expression.type
if t.is_int_type():
kind.set_numbers("DISCRETE_NUMBERS")
elif t.is_real_type():
kind.set_numbers("CONTINUOUS_NUMBERS")
(
is_linear,
fnode_to_only_increase, # positive fluents in minimize can only be increased
Expand All @@ -117,6 +122,11 @@ def _update_kind_metric(
metric, up.model.metrics.MaximizeExpressionOnFinalState
)
kind.set_quality_metrics("FINAL_VALUE")
t = metric.expression.type
if t.is_int_type():
kind.set_numbers("DISCRETE_NUMBERS")
elif t.is_real_type():
kind.set_numbers("CONTINUOUS_NUMBERS")
(
is_linear,
fnode_to_only_decrease, # positive fluents in maximize can only be decreased
Expand All @@ -134,19 +144,27 @@ def _update_kind_metric(
elif metric.is_minimize_action_costs():
assert isinstance(metric, up.model.metrics.MinimizeActionCosts)
kind.set_quality_metrics("ACTIONS_COST")
if metric.default is not None:
t = metric.default.type
if t.is_int_type():
kind.set_numbers("DISCRETE_NUMBERS")
elif t.is_real_type():
kind.set_numbers("CONTINUOUS_NUMBERS")
for f in fve.get(metric.default):
if f.fluent() in static_fluents:
kind.set_actions_cost_kind("STATIC_FLUENTS_IN_ACTIONS_COST")
else:
kind.set_actions_cost_kind("FLUENTS_IN_ACTIONS_COST")
for cost in metric.costs.values():
t = cost.type
if t.is_int_type():
kind.set_numbers("DISCRETE_NUMBERS")
elif t.is_real_type():
kind.set_numbers("CONTINUOUS_NUMBERS")
if cost is None:
raise UPProblemDefinitionError(
"The cost of an Action can't be None."
)
if metric.default is not None:
for f in fve.get(metric.default):
if f.fluent() in static_fluents:
kind.set_actions_cost_kind(
"STATIC_FLUENTS_IN_ACTIONS_COST"
)
else:
kind.set_actions_cost_kind("FLUENTS_IN_ACTIONS_COST")
for f in fve.get(cost):
if f.fluent() in static_fluents:
kind.set_actions_cost_kind("STATIC_FLUENTS_IN_ACTIONS_COST")
Expand All @@ -157,9 +175,21 @@ def _update_kind_metric(
elif metric.is_minimize_sequential_plan_length():
kind.set_quality_metrics("PLAN_LENGTH")
elif metric.is_oversubscription():
assert isinstance(metric, up.model.metrics.Oversubscription)
kind.set_quality_metrics("OVERSUBSCRIPTION")
for c in metric.goals.values():
if isinstance(c, int):
kind.set_numbers("DISCRETE_NUMBERS")
else:
kind.set_numbers("CONTINUOUS_NUMBERS")
elif metric.is_temporal_oversubscription():
assert isinstance(metric, up.model.metrics.TemporalOversubscription)
kind.set_quality_metrics("TEMPORAL_OVERSUBSCRIPTION")
for c in metric.goals.values():
if isinstance(c, int):
kind.set_numbers("DISCRETE_NUMBERS")
else:
kind.set_numbers("CONTINUOUS_NUMBERS")
else:
assert False, "Unknown quality metric"
return fluents_to_only_increase, fluents_to_only_decrease
31 changes: 25 additions & 6 deletions unified_planning/model/problem.py
Original file line number Diff line number Diff line change
Expand Up @@ -663,7 +663,12 @@ def _kind_factory(self) -> "_KindFactory":
if len(self._timed_effects) > 0:
factory.kind.set_time("CONTINUOUS_TIME")
factory.kind.set_time("TIMED_EFFECTS")
for effect_list in self._timed_effects.values():
for t, effect_list in self._timed_effects.items():
if t.delay != 0:
if isinstance(t.delay, int):
factory.kind.set_numbers("DISCRETE_NUMBERS")
else:
factory.kind.set_numbers("CONTINUOUS_NUMBERS")
for effect in effect_list:
factory.update_problem_kind_effect(effect)
if len(self._timed_goals) > 0:
Expand All @@ -674,7 +679,13 @@ def _kind_factory(self) -> "_KindFactory":
factory.kind.set_constraints_kind("STATE_INVARIANTS")
else:
factory.kind.set_constraints_kind("TRAJECTORY_CONSTRAINTS")
for goal_list in self._timed_goals.values():
for i, goal_list in self._timed_goals.items():
for t in [i.lower, i.upper]:
if t.delay != 0:
if isinstance(t.delay, int):
factory.kind.set_numbers("DISCRETE_NUMBERS")
else:
factory.kind.set_numbers("CONTINUOUS_NUMBERS")
for goal in goal_list:
factory.update_problem_kind_expression(goal)
for goal in self._goals:
Expand Down Expand Up @@ -751,10 +762,7 @@ def __init__(

def finalize(self) -> "up.model.ProblemKind":
"""Once all features have been added, remove unnecessary features that were added preventively."""
if (
not self.kind.has_continuous_numbers()
and not self.kind.has_discrete_numbers()
):
if not self.kind.has_numeric_fluents():
self.kind.unset_problem_type("SIMPLE_NUMERIC_PLANNING")
else:
if not self.kind.has_simple_numeric_planning():
Expand Down Expand Up @@ -928,6 +936,8 @@ def update_action_parameter(self, param: "up.model.Parameter"):

def update_action_duration(self, duration: "up.model.DurationInterval"):
lower, upper = duration.lower, duration.upper
self.update_problem_kind_type(lower.type)
self.update_problem_kind_type(upper.type)
if lower != upper:
self.kind.set_time("DURATION_INEQUALITIES")
free_vars = self.environment.free_vars_extractor.get(
Expand All @@ -949,6 +959,11 @@ def update_action_timed_condition(
):
if span.lower.delay != 0 or span.upper.delay != 0:
for t in [span.lower, span.upper]:
if t.delay != 0:
if isinstance(t.delay, int):
self.kind.set_numbers("DISCRETE_NUMBERS")
else:
self.kind.set_numbers("CONTINUOUS_NUMBERS")
if (t.is_from_start() and t.delay > 0) or (
t.is_from_end() and t.delay < 0
):
Expand All @@ -959,6 +974,10 @@ def update_action_timed_condition(

def update_action_timed_effect(self, t: "up.model.Timing", eff: "up.model.Effect"):
if t.delay != 0:
if isinstance(t.delay, int):
self.kind.set_numbers("DISCRETE_NUMBERS")
else:
self.kind.set_numbers("CONTINUOUS_NUMBERS")
if (t.is_from_start() and t.delay > 0) or (t.is_from_end() and t.delay < 0):
self.kind.set_time("INTERMEDIATE_CONDITIONS_AND_EFFECTS")
else:
Expand Down
4 changes: 0 additions & 4 deletions unified_planning/test/test_problem.py
Original file line number Diff line number Diff line change
Expand Up @@ -524,10 +524,6 @@ def test_simple_numeric_planning_kind(self):
"robot_decrease",
"robot_locations_connected",
"robot_locations_visited",
"robot_fluent_of_user_type_with_int_id",
"basic_int_fluent_param",
"basic_bounded_int_action_param",
"basic_unbounded_int_action_param",
"sched:basic",
"sched:resource_set",
"sched:jobshop-ft06-operators",
Expand Down
2 changes: 1 addition & 1 deletion unified_planning/test/test_protobuf_io.py
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,7 @@ def test_all_problems(self):
problem_pb = self.pb_writer.convert(problem)
problem_up = self.pb_reader.convert(problem_pb)

self.assertEqual(problem, problem_up)
self.assertEqual(problem, problem_up, name)
self.assertEqual(
hash(problem),
hash(problem_up),
Expand Down

0 comments on commit cfeb48c

Please sign in to comment.