I have a robot that has to transport each component present in the warehouse to the working table, this can be done only after identifying the component and only one component at time can be picked up. To align with a real context, I should "lost" the identification of the component when the robot leaves the site, while the component in the hand should remain identified.
Looking at the PDDL wiki, I found that forall cannot be used in effect, but the plan seems to work. Is the implementation of the action robot_move correct?
(:action robot_move
:parameters (?from - site ?to - site ?c - component ?g1 - gripper ?g2 - gripper)
:precondition (and (at-robby ?from) (different ?g1 ?g2) (or (connected ?from ?to) (connected ?to ?from)) (or (free ?g1) (free ?g2))) ; This force the robot to move only one component at time from the warehouse
:effect(and (not (at-robby ?from)) (at-robby ?to)
(forall (?c - component)
(when (and (at ?c ?from) (identified_component ?c))
(not (identified_component ?c)))) ; When the robot moves from a site, the identified components are not identified anymore
(when (or (picked_up ?c ?g1) (picked_up ?c ?g2))
(and (not (at ?c ?from)) (at ?c ?to) (identified_component ?c)))) ; When the robot moves the component, the component moves with it and it is identified
)
I think it would technically work, and you absolutely can use forall
in an effect. But there are some simplifications you can make:
(:action robot_move
:parameters (?from ?to - site ?c - component ?g1 ?g2 - gripper)
:precondition (and
(at-robby ?from)
(different ?g1 ?g2)
; I'd suggest defining both to avoid the or
(or (connected ?from ?to) (connected ?to ?from))
; I'd suggest having just a `(holding ?c)` predicate that mirrors this -- again to avoid or
(or (free ?g1) (free ?g2)) ; This force the robot to move only one component at time from the warehouse
)
:effect(and
(not (at-robby ?from)) (at-robby ?to)
; When the robot moves from a site, the identified components are not identified anymore
(forall (?c - component) (not (identified_component ?c))))
; When the robot moves the component, the component moves with it and it is identified
(not (at ?c ?from))
(at ?c ?to)
(identified_component ?c)
)
Some notes:
or
in a condition, it creates axioms which makes things harder to solve. Avoid if at all possible.connected
predicates never change (i.e., they're static), then define them both ways.