Skip to content

Commit 68a6ce7

Browse files
authored
Merge pull request #133 from AI-Planning/sorted-types
Custom formatting for the types section.
2 parents 52444e5 + 16e90b1 commit 68a6ce7

File tree

22 files changed

+214
-115
lines changed

22 files changed

+214
-115
lines changed

pddl/formatter.py

Lines changed: 72 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -128,27 +128,85 @@ def print_typed_lists(
128128
to_string: Callable = str,
129129
):
130130
"""Print typed lists."""
131-
result = prefix + " "
131+
result = prefix
132132

133-
# names with no type will be printed at the end
134-
names_with_none_types = names_by_obj.pop(None, [])
133+
if ":types" in prefix:
134+
# for mypy, convert names_by_obj to a dict with keys being strings (or None) and values list of strings
135+
super_to_subs = {
136+
str(k) if k is not None else None: v for k, v in names_by_obj.items()
137+
}
138+
139+
# first print those types that have no parents
140+
subtypes = set()
141+
for subs in super_to_subs.values():
142+
subtypes |= set(subs)
143+
144+
no_parents = set(super_to_subs.keys()) - subtypes
145+
no_parents |= set(super_to_subs.get(None, []))
146+
no_parents |= set(super_to_subs.get("object", []))
147+
no_parents.discard(None)
148+
no_parents.discard("object")
135149

136-
# print typed constants, first sorted by type, then by constant name
137-
for type_tag, typed_names in sorted(
138-
names_by_obj.items(), key=lambda type_and_name: type_and_name[0] # type: ignore
139-
):
140150
result += (
141-
" ".join(sorted(to_string(n) for n in typed_names)) + " - " + type_tag + " " # type: ignore
151+
"\n "
152+
+ " ".join(sorted(to_string(n) for n in no_parents))
153+
+ " - object\n"
142154
)
143155

144-
if len(names_with_none_types) == 0:
145-
return result.strip() + postfix
156+
# sort the rest of the parent types based on (1) if their subtypes are already defined and (2) their name
157+
remaining = sorted(str(k) for k in super_to_subs if k not in ("object", None))
158+
ind = 0
159+
while remaining:
160+
# if the index is out of range, we have a cycle in the types
161+
if ind >= len(remaining):
162+
raise ValueError("Cycle in types")
163+
164+
# get the first type and its subtypes
165+
parent = remaining[ind]
166+
167+
# check if parent is a subtype of something remaining
168+
allsubtypes = set()
169+
for k in remaining:
170+
allsubtypes |= set(super_to_subs[k])
171+
if parent in allsubtypes:
172+
ind += 1
173+
else:
174+
# print the parent and its subtypes
175+
result += " " + (
176+
" ".join(sorted(to_string(n) for n in super_to_subs[parent]))
177+
+ " - "
178+
+ to_string(parent)
179+
+ "\n"
180+
)
181+
# remove the parent from the remaining list
182+
remaining.remove(parent)
183+
# reset the index to 0
184+
ind = 0
185+
186+
else:
187+
188+
result += " "
189+
190+
# names with no type will be printed at the end
191+
names_with_none_types = names_by_obj.pop(None, [])
192+
193+
# print typed constants, first sorted by type, then by constant name
194+
for type_tag, typed_names in sorted(
195+
names_by_obj.items(), key=lambda type_and_name: type_and_name[0] # type: ignore
196+
):
197+
result += (
198+
" ".join(sorted(to_string(n) for n in typed_names)) + " - " + type_tag + " " # type: ignore
199+
)
200+
201+
if len(names_with_none_types) == 0:
202+
return result.strip() + postfix
203+
204+
# print constants with no type
205+
result += " ".join(sorted(to_string(n) for n in names_with_none_types))
146206

147-
# print constants with no type
148-
result += " ".join(sorted(to_string(n) for n in names_with_none_types))
207+
if result == prefix + " ":
208+
result = result[:-1]
149209

150-
if result == prefix + " ":
151-
result = result[:-1]
152210
result += postfix
153211

154212
return result

pddl/parser/domain.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,9 @@ def types(self, args):
100100
have_type_hierarchy = any(types_definition.values())
101101
if have_type_hierarchy and not has_typing_requirement:
102102
raise PDDLMissingRequirementError(Requirements.TYPING)
103+
for k in types_definition:
104+
if types_definition[k] == Symbols.OBJECT.value:
105+
types_definition[k] = None
103106
return dict(types=types_definition)
104107

105108
def constants(self, args):

tests/fixtures/pddl_files/acrobatics/domain.pddl

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33

44
(define (domain acrobatics)
55
(:requirements :typing :strips :non-deterministic :negative-preconditions)
6-
(:types location)
6+
(:types
7+
location - object
8+
)
79
(:predicates
810
(up)
911
(position ?p - location)
@@ -32,7 +34,7 @@
3234
(:action walk-right
3335
:parameters (?from - location ?to - location)
3436
:precondition (and (not (broken-leg)) (not (up)) (position ?from) (next-fwd ?from ?to))
35-
:effect (and (position ?to) (not (position ?from)))
37+
:effect (and (position ?to) (not (position ?from)))
3638
)
3739

3840
(:action climb
@@ -42,7 +44,7 @@
4244
)
4345

4446
(:action climb-down
45-
:parameters ()
47+
:parameters ()
4648
:precondition (and (not (broken-leg)) (up))
4749
:effect (and (not (up)))
4850
)
@@ -54,12 +56,12 @@
5456
;; 4) agent falls from the beam, does not break its leg and falls at destination position
5557
;; 5) agent falls from the beam, breaks its leg and fall at destination position
5658
;; 6) agent falls on the beam at the destination position
57-
59+
5860
(:action jump-over
5961
:parameters ( ?from - location ?middle - location ?to - location )
6062
:precondition (and (not (broken-leg)) (up) (position ?from) (next-fwd ?from ?middle) (next-fwd ?middle ?to))
6163
:effect (oneof
62-
(and (not (up)) (broken-leg))
64+
(and (not (up)) (broken-leg))
6365
(and (not (up)) (broken-leg) (position ?middle) (not (position ?from)))
6466
(and (not (up)) (position ?middle) (not (position ?from)))
6567
(and (not (up)) (broken-leg) (position ?to) (not (position ?from)))

tests/fixtures/pddl_files/barman-sequential-optimal/domain.pddl

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
(cocktail-part2 ?c - cocktail ?i - ingredient))
2121

2222
(:functions (total-cost) - number)
23-
23+
2424
(:action grasp
2525
:parameters (?h - hand ?c - container)
2626
:precondition (and (ontable ?c) (handempty ?h))
@@ -36,7 +36,7 @@
3636
(handempty ?h)
3737
(ontable ?c)
3838
(increase (total-cost) 1)))
39-
39+
4040
(:action fill-shot
4141
:parameters (?s - shot ?i - ingredient ?h1 ?h2 - hand ?d - dispenser)
4242
:precondition (and (holding ?h1 ?s)
@@ -53,7 +53,7 @@
5353

5454
(:action refill-shot
5555
:parameters (?s - shot ?i - ingredient ?h1 ?h2 - hand ?d - dispenser)
56-
:precondition (and (holding ?h1 ?s)
56+
:precondition (and (holding ?h1 ?s)
5757
(handempty ?h2)
5858
(dispenses ?d ?i)
5959
(empty ?s)
@@ -73,7 +73,7 @@
7373
(:action clean-shot
7474
:parameters (?s - shot ?b - beverage ?h1 ?h2 - hand)
7575
:precondition (and (holding ?h1 ?s)
76-
(handempty ?h2)
76+
(handempty ?h2)
7777
(empty ?s)
7878
(used ?s ?b))
7979
:effect (and (not (used ?s ?b))
@@ -85,7 +85,7 @@
8585
:precondition (and (holding ?h1 ?s)
8686
(contains ?s ?i)
8787
(empty ?d)
88-
(clean ?d)
88+
(clean ?d)
8989
(shaker-level ?d ?l)
9090
(next ?l ?l1))
9191
:effect (and (not (contains ?s ?i))
@@ -108,7 +108,7 @@
108108
(next ?l ?l1))
109109
:effect (and (not (contains ?s ?i))
110110
(contains ?d ?i)
111-
(empty ?s)
111+
(empty ?s)
112112
(not (shaker-level ?d ?l))
113113
(shaker-level ?d ?l1)
114114
(increase (total-cost) 1)))
@@ -134,7 +134,7 @@
134134
(empty ?s))
135135
:effect (and (clean ?s)
136136
(increase (total-cost) 1)))
137-
137+
138138
(:action shake
139139
:parameters (?b - cocktail ?d1 ?d2 - ingredient ?s - shaker ?h1 ?h2 - hand)
140140
:precondition (and (holding ?h1 ?s)
@@ -143,7 +143,7 @@
143143
(contains ?s ?d2)
144144
(cocktail-part1 ?b ?d1)
145145
(cocktail-part2 ?b ?d2)
146-
(unshaked ?s))
146+
(unshaked ?s))
147147
:effect (and (not (unshaked ?s))
148148
(not (contains ?s ?d1))
149149
(not (contains ?s ?d2))
@@ -166,4 +166,4 @@
166166
(shaker-level ?s ?l1)
167167
(not (shaker-level ?s ?l))
168168
(increase (total-cost) 1)))
169-
)
169+
)

tests/fixtures/pddl_files/beam-walk/domain.pddl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33

44
(define (domain beam-walk)
55
(:requirements :typing :strips :non-deterministic :negative-preconditions)
6-
(:types location)
6+
(:types
7+
location - object
8+
)
79
(:predicates
810
(up)
911
(position ?p - location)

tests/fixtures/pddl_files/blocksworld-ipc08/domain.pddl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
(define (domain blocks-domain)
22
(:requirements :non-deterministic :equality :typing :negative-preconditions)
3-
(:types block)
3+
(:types
4+
block - object
5+
)
46
(:predicates (holding ?b - block) (emptyhand) (on-table ?b - block) (on ?b1 ?b2 - block) (clear ?b - block))
57
(:action pick-up
68
:parameters (?b1 ?b2 - block)
79
:precondition (and (not (= ?b1 ?b2)) (emptyhand) (clear ?b1) (on ?b1 ?b2))
810
:effect
9-
(oneof
11+
(oneof
1012
(and (holding ?b1) (clear ?b2) (not (emptyhand)) (not (clear ?b1)) (not (on ?b1 ?b2)))
1113
(and (clear ?b2) (on-table ?b1) (not (on ?b1 ?b2))))
1214
)

tests/fixtures/pddl_files/cave-diving-sequential-optimal/domain.pddl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55

66
(define (domain cave-diving-adl)
77
(:requirements :typing :action-costs :adl :numeric-fluents :action-costs)
8-
(:types location diver tank quantity)
8+
(:types
9+
location diver tank quantity - object
10+
)
911
(:predicates
1012
(at-tank ?t - tank ?l - location)
1113
(in-storage ?t - tank)
@@ -34,7 +36,7 @@
3436
(:action hire-diver
3537
:parameters (?d1 - diver)
3638
:precondition (and (available ?d1)
37-
(not (in-water))
39+
(not (in-water))
3840
)
3941
:effect (and (at-surface ?d1)
4042
(not (available ?d1))

tests/fixtures/pddl_files/doors/domain.pddl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
(define (domain doors)
22
(:requirements :typing :strips :non-deterministic :negative-preconditions)
3-
(:types location door)
3+
(:types
4+
location door - object
5+
)
46
(:predicates (open ?d - door)
57
(closed ?d - door)
68
(player-at ?loc - location)
@@ -49,4 +51,4 @@
4951
:effect (and (player-at ?to) (not (player-at ?from))
5052
(oneof (and (open ?d1) (not (closed ?d1))) (and (closed ?d1) (not (open ?d1)))))
5153
)
52-
)
54+
)

tests/fixtures/pddl_files/elevators/domain.pddl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
(define (domain elevators)
22
(:requirements :non-deterministic :negative-preconditions :equality :typing)
3-
(:types elevator floor pos coin)
3+
(:types
4+
elevator floor pos coin - object
5+
)
46
(:constants f1 - floor p1 - pos)
57
(:predicates (dec_f ?f ?g - floor) (dec_p ?p ?q - pos) (in ?e - elevator ?f - floor) (at ?f - floor ?p - pos) (shaft ?e - elevator ?p - pos) (inside ?e - elevator) (gate ?f - floor ?p - pos) (coin-at ?c - coin ?f - floor ?p - pos) (have ?c - coin))
68
(:action go-up

tests/fixtures/pddl_files/first-responders-ipc08/domain.pddl

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
(define (domain first-response)
2-
(:requirements :typing
2+
(:requirements :typing
33
:equality
44
:negative-preconditions
55
:disjunctive-preconditions
66
:universal-preconditions
77
:conditional-effects
88
:existential-preconditions
99
:non-deterministic)
10-
(:types location victim status fire_unit medical_unit)
10+
(:types
11+
location victim status fire_unit medical_unit - object
12+
)
1113
(:constants healthy hurt dying - status)
12-
(:predicates
14+
(:predicates
1315
(fire ?l - location)
1416
(nfire ?l - location)
1517
(victim-at ?v - victim ?l - location)
@@ -26,7 +28,7 @@
2628
(:action drive-fire-unit
2729
:parameters (?u - fire_unit ?from - location ?to - location)
2830
:precondition (and (fire-unit-at ?u ?from)
29-
(adjacent ?to ?from)
31+
(adjacent ?to ?from)
3032
(not (fire ?to))
3133
)
3234
:effect (and (fire-unit-at ?u ?to) (not (fire-unit-at ?u ?from)))
@@ -41,7 +43,7 @@
4143
:effect (and (medical-unit-at ?u ?to) (not (medical-unit-at ?u ?from)))
4244
)
4345

44-
46+
4547

4648
(:action load-fire-unit
4749
:parameters (?u - fire_unit ?l - location)
@@ -51,11 +53,11 @@
5153
(:action load-medical-unit
5254
:parameters (?u - medical_unit ?l - location ?v - victim)
5355
:precondition (and (medical-unit-at ?u ?l) (victim-at ?v ?l))
54-
:effect (and (have-victim-in-unit ?v ?u)
56+
:effect (and (have-victim-in-unit ?v ?u)
5557
(not (victim-at ?v ?l))))
5658

57-
58-
59+
60+
5961
(:action unload-fire-unit
6062
:parameters (?u - fire_unit ?l ?l1 - location)
6163
:precondition (and (fire-unit-at ?u ?l)
@@ -73,26 +75,26 @@
7375

7476
(:action treat-victim-on-scene-medical
7577
:parameters (?u - medical_unit ?l - location ?v - victim)
76-
:precondition (and (medical-unit-at ?u ?l)
78+
:precondition (and (medical-unit-at ?u ?l)
7779
(victim-at ?v ?l)
7880
(victim-status ?v hurt))
79-
:effect (oneof (and) (and (victim-status ?v healthy)
81+
:effect (oneof (and) (and (victim-status ?v healthy)
8082
(not (victim-status ?v hurt)))))
8183

8284
(:action treat-victim-on-scene-fire
8385
:parameters (?u - fire_unit ?l - location ?v - victim)
84-
:precondition (and (fire-unit-at ?u ?l)
86+
:precondition (and (fire-unit-at ?u ?l)
8587
(victim-at ?v ?l)
8688
(victim-status ?v hurt))
87-
:effect (oneof (and) (and (victim-status ?v healthy)
89+
:effect (oneof (and) (and (victim-status ?v healthy)
8890
(not (victim-status ?v hurt)))))
8991

9092
(:action treat-victim-at-hospital
9193
:parameters (?v - victim ?l - location)
9294
:precondition (and (victim-at ?v ?l)
93-
(hospital ?l))
94-
:effect (and (victim-status ?v healthy)
95+
(hospital ?l))
96+
:effect (and (victim-status ?v healthy)
9597
(not (victim-status ?v hurt))
9698
(not (victim-status ?v dying))))
97-
98-
)
99+
100+
)

0 commit comments

Comments
 (0)