Hi,
Just a remark here, creating an object as the result of an action would go completely against the closed world assumption. While indeed europa allows to run a problem without closing the world it raises a lot of issues and this especially when you consider that they are done through tokens that can be created by tokens (which in turns can be removed should the planner need to backtrack but there’s even more than that)
Now for the more simple aspect conditions and effect of actions are tokens (i.e. temporally scoped predicates) as opposed to objects which are things that exist during all the plan. So creating an object as en effect of an action is creating something that is permanent which is a pure and simple contradiction.
Now allowing to create objects in a temporal scoped token (action or predicate) also raises the question of their scope.
- Do they exist only until the end of the token or is their scope until the end of the mission ?
- if the token is removed (due to a backtrack for example) does the object created is removed too ? (technically, based on the way EUROPA::Id references counts this would be indeed what would happened to your object as of right now)
- does the object impacts constraints that where established before this object was created ?
This last one is important indeed picture the objects:
class Node {
Node() {}
}
class Edge {
Node from, to;
DirectPath(Node a, Node b) {
from = a;
to = b;
}
}
Now our initial instantiation is:
Node a = new Node();
Edge ab = new Edge(a,b);
So far there’s no way to go to d the only paths that exists are from a to b and from b to c (and by transitivity you can go from a to c)
Now lets have a robot class that have the action Move
class Robot extends Timeline {
predicate At {
Node pos;
}
action Move {}
// ...
}
Robot::Move {
meets(effect At dest);
met_by(condition At source);
Edge path;
path.from == source.pos;
}
Robot roby = new Robot();
Now lets try to instantiate our problem
// roby is initially at a
fact(Robot.At initial);
initial.object.specify(roby)
initial.start.specify(0);
initial.pos == a;
// we want roby to be at d in the future)
rejectable(Robot.At final);
final.object.specify(roby);
final.start >= 1;
final.pos == d;
Well there’s no way to go to d so the problem will lend up identify that the “final” goal need to be rejected.
But wait you said that actions could create objects then what prohibit us to create a path later on, but we rejected final already, does that mean that we were wrong ?
Of course you can say “but the planner should have see my create_path action and identify that it can create a new path” Ok but what if this action is in a class that has no instance yet but can be created through create_class_that_can_create_path ?
You see that suddenly you have a problem that is order of magnitude more complex than if you considered the classic “closed world assumption” if you let the plan modify the world it means that every time it restrict the domain of a variable there’s the possibility that this restriction is no longer valid due to new truth emerging in the future which makes then the maintinance of constraints much more complex, we are already dealing with a PSPACE problem adding this kind of operation would lead the problem solver in a complexity class way beyond this.