@@ -17,20 +17,25 @@ class PDDL:
17
17
18
18
def __init__ (self , init , goals , actions ):
19
19
self .init = self .convert (init )
20
- self .goals = expr (goals )
20
+ self .goals = self . convert (goals )
21
21
self .actions = actions
22
22
23
- def convert (self , init ):
23
+ def convert (self , clauses ):
24
24
"""Converts strings into exprs"""
25
+ if not isinstance (clauses , Expr ):
26
+ if len (clauses ) > 0 :
27
+ clauses = expr (clauses )
28
+ else :
29
+ clauses = []
25
30
try :
26
- init = conjuncts (expr ( init ) )
31
+ clauses = conjuncts (clauses )
27
32
except AttributeError :
28
- init = expr ( init )
29
- return init
33
+ clauses = clauses
34
+ return clauses
30
35
31
36
def goal_test (self ):
32
37
"""Checks if the goals have been reached"""
33
- return all (goal in self .init for goal in conjuncts ( self .goals ) )
38
+ return all (goal in self .init for goal in self .goals )
34
39
35
40
def act (self , action ):
36
41
"""
@@ -61,34 +66,35 @@ class Action:
61
66
"""
62
67
63
68
def __init__ (self , action , precond , effect ):
64
- action = expr (action )
69
+ if isinstance (action , str ):
70
+ action = expr (action )
65
71
self .name = action .op
66
72
self .args = action .args
67
- self .precond , self .effect = self .convert (precond , effect )
73
+ self .precond = self .convert (precond )
74
+ self .effect = self .convert (effect )
68
75
69
76
def __call__ (self , kb , args ):
70
77
return self .act (kb , args )
71
78
72
- def convert (self , precond , effect ):
79
+ def convert (self , clauses ):
73
80
"""Converts strings into Exprs"""
81
+ if isinstance (clauses , Expr ):
82
+ clauses = conjuncts (clauses )
83
+ for i in range (len (clauses )):
84
+ if clauses [i ].op == '~' :
85
+ clauses [i ] = expr ('Not' + str (clauses [i ].args [0 ]))
74
86
75
- precond = precond .replace ('~' , 'Not' )
76
- if len (precond ) > 0 :
77
- precond = expr (precond )
78
- effect = effect .replace ('~' , 'Not' )
79
- if len (effect ) > 0 :
80
- effect = expr (effect )
87
+ elif isinstance (clauses , str ):
88
+ clauses = clauses .replace ('~' , 'Not' )
89
+ if len (clauses ) > 0 :
90
+ clauses = expr (clauses )
81
91
82
- try :
83
- precond = conjuncts (precond )
84
- except AttributeError :
85
- pass
86
- try :
87
- effect = conjuncts (effect )
88
- except AttributeError :
89
- pass
92
+ try :
93
+ clauses = conjuncts (clauses )
94
+ except AttributeError :
95
+ pass
90
96
91
- return precond , effect
97
+ return clauses
92
98
93
99
def substitute (self , e , args ):
94
100
"""Replaces variables in expression with their respective Propositional symbol"""
@@ -138,10 +144,10 @@ def act(self, kb, args):
138
144
def air_cargo ():
139
145
"""Air cargo problem"""
140
146
141
- return PDDL (init = 'At(C1, SFO) & At(C2, JFK) & At(P1, SFO) & At(P2, JFK) & Cargo(C1) & Cargo(C2) & Plane(P1) & Plane(P2) & Airport(SFO) & Airport(JFK)' ,
147
+ return PDDL (init = 'At(C1, SFO) & At(C2, JFK) & At(P1, SFO) & At(P2, JFK) & Cargo(C1) & Cargo(C2) & Plane(P1) & Plane(P2) & Airport(SFO) & Airport(JFK)' ,
142
148
goals = 'At(C1, JFK) & At(C2, SFO)' ,
143
149
actions = [Action ('Load(c, p, a)' ,
144
- precond = 'At(c, a) & At(p, a) & Cargo(c) & Plane(p) & Airport(a)' ,
150
+ precond = 'At(c, a) & At(p, a) & Cargo(c) & Plane(p) & Airport(a)' ,
145
151
effect = 'In(c, p) & ~At(c, a)' ),
146
152
Action ('Unload(c, p, a)' ,
147
153
precond = 'In(c, p) & At(p, a) & Cargo(c) & Plane(p) & Airport(a)' ,
@@ -207,6 +213,25 @@ def shopping_problem():
207
213
effect = 'At(y) & ~At(x)' )])
208
214
209
215
216
+ def socks_and_shoes ():
217
+ """Socks and shoes problem"""
218
+
219
+ return PDDL (init = '' ,
220
+ goals = 'RightShoeOn & LeftShoeOn' ,
221
+ actions = [Action ('RightShoe' ,
222
+ precond = 'RightSockOn' ,
223
+ effect = 'RightShoeOn' ),
224
+ Action ('RightSock' ,
225
+ precond = '' ,
226
+ effect = 'RightSockOn' ),
227
+ Action ('LeftShoe' ,
228
+ precond = 'LeftSockOn' ,
229
+ effect = 'LeftShoeOn' ),
230
+ Action ('LeftSock' ,
231
+ precond = '' ,
232
+ effect = 'LeftSockOn' )])
233
+
234
+
210
235
class Level :
211
236
"""
212
237
Contains the state of the planning problem
@@ -559,6 +584,26 @@ def goal_test(kb, goals):
559
584
return None
560
585
561
586
587
+ def socks_and_shoes_graphplan ():
588
+ pddl = socks_and_shoes ()
589
+ graphplan = GraphPlan (pddl )
590
+
591
+ def goal_test (kb , goals ):
592
+ return all (kb .ask (q ) is not False for q in goals )
593
+
594
+ goals = expr ('RightShoeOn, LeftShoeOn' )
595
+
596
+ while True :
597
+ if (goal_test (graphplan .graph .levels [- 1 ].kb , goals ) and graphplan .graph .non_mutex_goals (goals , - 1 )):
598
+ solution = graphplan .extract_solution (goals , - 1 )
599
+ if solution :
600
+ return solution
601
+
602
+ graphplan .graph .expand_graph ()
603
+ if len (graphplan .graph .levels ) >= 2 and graphplan .check_leveloff ():
604
+ return None
605
+
606
+
562
607
def linearize (solution ):
563
608
"""Converts a level-ordered solution into a linear solution"""
564
609
0 commit comments