-
Notifications
You must be signed in to change notification settings - Fork 42
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
Autonomous processes events #629
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@hstairs Thanks fo this, it looks good but there are few things I would do before merging:
- Add some tests in the examples showing the new feature
- Add EVENTS to the kind and handle it
- Do not inherit the
Event
class fromInstantaneousAction
, in many places we check withisinstance(x, InstantaneousAction)
- I am ok with limiting ourselves with linear derivatives for now, but I would design the interface of processes to be generic, otherwise it is very hard to change it in the future. Also, the parser and the code should raise meaningful exceptions when a non-linear case is encountered, now they operate wrongly.
@@ -526,6 +552,8 @@ def _parse_exp( | |||
solved.append(self._em.FluentExp(problem.fluent(exp.value))) | |||
elif problem.has_object(exp.value): # object | |||
solved.append(self._em.ObjectExp(problem.object(exp.value))) | |||
elif exp.value == "#t": | |||
solved.append(self._em.Int(1)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't we need to model this explicitly?
I see this works for the linear case, but how can we catch an expression like (* #t #t)
and raise an exception?
I think we shall handle this in a more principled way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In PDDL+ we can express first time derivatives only, meaning that effects are always going to be (* #t exp) where exp is to be #t-free (citing from the PDDL+ paper). Note that exp is not required to be linear or am I enforcing that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Having said that there is definitely a cleaner way to parse that!
unified_planning/model/action.py
Outdated
|
||
|
||
class Process(Action): | ||
"""This is the `Process` class, which implements the abstract `Process` class.""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
? It seems to me it implements the abstract Action
class 😄
I thinkit is not too bad to have processes and events to be Action
s, even though they are semantically different. In hindsight we might have called the abstract action class somethig else.
@alvalentini maybe we can consider a refactoring of this name, eventually...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One could call this transition, and I have hinted at something like that to Alessandro...but it is a major change no?
unified_planning/model/action.py
Outdated
Adds the given `derivative effect` to the `process's effects`. | ||
|
||
:param fluent: The `fluent` objective of the time derivative definition. | ||
:param value: The given `fluent` is incremented by the given `value`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment is wrong, and I think that how we model derivatives is a central issue that shall be very well documented.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure!
unified_planning/model/action.py
Outdated
|
||
@property | ||
def preconditions(self) -> List["up.model.fnode.FNode"]: | ||
"""Returns the `list` of the `Action` `preconditions`.""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All the comments in this class are copy-pasted, we need to replace Action
with Process
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep
unified_planning/model/action.py
Outdated
) | ||
|
||
|
||
class Event(InstantaneousAction): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is kind of dangerous: beware that isinstance(x, InstantaneousAction)
would return True
if x is an Event. I get that we save some code duplication, but here I would inherit from Action
only... Then, maybe we can create a mixin to avoid the code duplication
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For example, https://github.com/aiplan4eu/unified-planning/blob/master/unified_planning/model/mixins/actions_set.py#L60 is probably broken by this choice
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yep
@@ -331,6 +331,10 @@ def _get_static_and_unused_fluents( | |||
unused_fluents.clear() | |||
for f in se.fluents: | |||
static_fluents.discard(f.fluent()) | |||
elif isinstance(a, up.model.action.Process): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about events here? Again, they are probably absorbed by the isinstance(a, up.model.action.InstantaneousAction)
, so we need to fix this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yep
@@ -682,6 +686,9 @@ def _kind_factory(self) -> "_KindFactory": | |||
for goal in chain(*self._timed_goals.values(), self._goals): | |||
factory.update_problem_kind_expression(goal) | |||
factory.update_problem_kind_initial_state(self) | |||
self.processes | |||
if len(list(self.processes)) > 0: | |||
factory.kind.set_time("PROCESSES") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add also some flags for events!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not sure we need to differentiate processes and events. I think a flag (likely not "processes") for both is fine
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One further comment: if we only have events we need to find a way to understand the semantics. I am not sure this case is well documented in the syntax of PDDL+. For instance, ENHSP considers temporal only a problem where there is at least one process. I don't see any use for events only (as they are understood in PDDL+) as events make sense if triggered by something which is changed as an effect of some passage of time.
@@ -1003,6 +1010,8 @@ def update_problem_kind_action( | |||
if len(action.simulated_effects) > 0: | |||
self.kind.set_simulated_entities("SIMULATED_EFFECTS") | |||
self.kind.set_time("CONTINUOUS_TIME") | |||
elif isinstance(action, up.model.action.Process): | |||
pass |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should add PROCESSES
to the kind
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yep, connected with the previous
process_temporal_kind = ProblemKind(version=LATEST_PROBLEM_KIND_VERSION) | ||
process_temporal_kind.set_problem_class("ACTION_BASED") | ||
process_temporal_kind.set_time("PROCESSES") | ||
process_temporal_kind.set_time("CONTINUOUS_TIME") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no FLAT_TYPING here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't FLAT_TYPING a restriction on the kind of types we can define (like no hierarchy)? If so, there is no restriction here, or I didn't understand this :)
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #629 +/- ##
==========================================
+ Coverage 85.36% 85.38% +0.01%
==========================================
Files 202 204 +2
Lines 27319 27653 +334
==========================================
+ Hits 23322 23611 +289
- Misses 3997 4042 +45 ☔ View full report in Codecov by Sentry. |
…have done the most of the work to get the modeler formulate the problem and solve it through PDDL+ planner with the PDDLWriter.
…aneous transitions (including events). Polished comments, add the identification of the problem kind and finally added an example. Need to double check things
…hich is called derivative. This way we can have the semantics a bit more explicit in the code
…ion of up-enhsp for testing purposes
…I testing workflow
ea544c8
to
aabe009
Compare
I guess I addressed the requested changes and added a few more tests together with a running example. I think there can be other possible refactoring in the structure of action/event/processes/sensing/durativeactions but I run out of time and did only some of them. |
Hello, I started looking a bit into this and I think I could help a bit with the refactoring that was previously mentioned in the other comments. |
In this branch we add support for PDDL+ specification. The branch includes extensions to the problem representation (so allowing to specify processes and events), pddl writer (so allowing to use domain independent off-the-shelf PDDL+ solvers), pddl reader (so allowing get PDDL+ specifications into up data structures). There is some design choice that would need discussion though.