Search code examples
pddl

PDDL forall to initialize objects


I'm currently studying PDDL and am trying to develop simple examples. However, I'm experiencing some difficulties with the syntax and the usage of certain functionalities.

Specifically, I'm attempting to initialize the positions of some objects using the forall construct. I'm unsure if it is possible to use forall in the init section. I haven't found any supporting documentation or information to the contrary.

Domain code

(define (domain industrial_manufacturing)
    (:requirements :strips :typing :negative-preconditions :equality :universal-preconditions)

    (:types
        location
        box
        supply
        robotic_agent

        valve bolt screw tool - supply
     )

    (:constants
        tool1 tool2 - tool
    )

    (:predicates
        (adjacent ?l1 - location ?l2 - location)
        (belong ?ws - work_station ?l - location)

        (full ?b - box ?s - supply)
        (empty ?b - box)

        (loaded ?b - box ?r - robotic_agent)
        (unloaded ?b - box)

        (occupied ?r - robotic_agent ?b - box)
        (free ?r - robotic_agent)

        (at_box ?b - box ?l - location)
        (at_robot ?r - robotic_agent ?l - location)
        (at_supply ?s - supply ?l - location)

        (need_supply ?ws - work_station ?s - supply)
    )

    ; Moves a free robot between two locations, if it is not already there
    (:action move_free_robot
        :parameters (?r - robotic_agent ?from ?to - location)
        :precondition (and
            (not (= ?from ?to))
            (adjacent ?from ?to)
            (at_robot ?r ?from) 
            (free ?r)
        )

        :effect (and
            (at_robot ?r ?to)
            (not (at_robot ?r ?from))
        )
    )
)

Problem code

(define (problem industrial_manufacturing)
    (:domain industrial_manufacturing)

    (:objects 
        location1 location2 - location

        box1 - box

        warehouse - location
        valve1 valve2 - valve
        bolt1 bolt2 - bolt
        screw1 screw2 - screw

        robot1 - robotic_agent
    )

    (:init
        ; locations
        (adjacent warehouse location1)
        (adjacent warehouse location2)

        (adjacent location1 warehouse)
        (adjacent location2 warehouse)

        ; boxes
        (empty box1)
        (unloaded box1)
        (at_box box1 warehouse)

        ; robots
        (free robot1)
        (at_robot robot1 warehouse)

        ; supplies
        ; (at_supply valve1 warehouse)
        ; (at_supply valve2 warehouse)
        
        ; (at_supply tool1 warehouse)
        ; (at_supply tool2 warehouse)
        
        ; (at_supply bolt1 warehouse)
        ; (at_supply bolt2 warehouse)
        
        ; (at_supply screw1 warehouse)
        ; (at_supply screw2 warehouse)

                ; forall section
        (forall (?i - (either screw valve bolt tool))
                (at_supply ?i warehouse))
    )

    (:goal 
        (at_robot robot1 location1)
    )
)

If I run the code as it is, I obtain the following error:

INFO     Running translator.
INFO     translator stdin: None
INFO     translator time limit: None
INFO     translator memory limit: None
INFO     translator command line string: /usr/bin/python3 /workspace/downward/builds/release/bin/translate/translate.py /tmp/tmpa9ayjy78/domain.pddl /tmp/tmpa9ayjy78/problem.pddl --sas-file output.sas
Parsing...
b'Traceback (most recent call last):&#13;&#10;  File "/workspace/downward/builds/release/bin/translate/translate.py", line 727, in <module>&#13;&#10;    main()&#13;&#10;  File "/workspace/downward/builds/release/bin/translate/translate.py", line 686, in main&#13;&#10;    domain_filename=options.domain, task_filename=options.task)&#13;&#10;  File "/workspace/downward/builds/release/bin/translate/pddl_parser/pddl_file.py", line 33, in open&#13;&#10;    return parsing_functions.parse_task(domain_pddl, task_pddl)&#13;&#10;  File "/workspace/downward/builds/release/bin/translate/pddl_parser/parsing_functions.py", line 298, in parse_task&#13;&#10;    task_name, task_domain_name, task_requirements, objects, init, goal, use_metric = parse_task_pddl(task_pddl, type_dict, predicate_dict)&#13;&#10;  File "/workspace/downward/builds/release/bin/translate/pddl_parser/parsing_functions.py", line 456, in parse_task_pddl&#13;&#10;    atom = pddl.Atom(fact[0], fact[1:])&#13;&#10;  File "/workspace/downward/builds/release/bin/translate/pddl/conditions.py", line 226, in __init__&#13;&#10;    self.hash = hash((self.__class__, self.predicate, self.args))&#13;&#10;TypeError: unhashable type: \'list\'&#13;&#10;'
translate exit code: 30

Driver aborting after translate

I'm not sure how to interpret it.

If I comment out the forall section and uncomment the supply section, everything works.

I've also tried with different planners, but the result is always the same. Unfortunately, I don't always have a log of the error like the one above.

I'm new to PDDL, so I apologize if I'm using the terminology incorrectly.

Additionally, if you have any suggestions for documentation and a good online planner, please let me know.


Solution

  • PDDL's forall cannot be used in the initial state specification of planning problems. The initial state specification must be a list of positive literals (non-negated ground -- fully-instantiated -- facts).

    You must expand that forall into the corresponding set of facts: