diff --git a/planning.py b/planning.py index d9a152e9a..e31cd2f87 100644 --- a/planning.py +++ b/planning.py @@ -17,20 +17,25 @@ class PDDL: def __init__(self, init, goals, actions): self.init = self.convert(init) - self.goals = expr(goals) + self.goals = self.convert(goals) self.actions = actions - def convert(self, init): + def convert(self, clauses): """Converts strings into exprs""" + if not isinstance(clauses, Expr): + if len(clauses) > 0: + clauses = expr(clauses) + else: + clauses = [] try: - init = conjuncts(expr(init)) + clauses = conjuncts(clauses) except AttributeError: - init = expr(init) - return init + clauses = clauses + return clauses def goal_test(self): """Checks if the goals have been reached""" - return all(goal in self.init for goal in conjuncts(self.goals)) + return all(goal in self.init for goal in self.goals) def act(self, action): """ @@ -61,34 +66,35 @@ class Action: """ def __init__(self, action, precond, effect): - action = expr(action) + if isinstance(action, str): + action = expr(action) self.name = action.op self.args = action.args - self.precond, self.effect = self.convert(precond, effect) + self.precond = self.convert(precond) + self.effect = self.convert(effect) def __call__(self, kb, args): return self.act(kb, args) - def convert(self, precond, effect): + def convert(self, clauses): """Converts strings into Exprs""" + if isinstance(clauses, Expr): + clauses = conjuncts(clauses) + for i in range(len(clauses)): + if clauses[i].op == '~': + clauses[i] = expr('Not' + str(clauses[i].args[0])) - precond = precond.replace('~', 'Not') - if len(precond) > 0: - precond = expr(precond) - effect = effect.replace('~', 'Not') - if len(effect) > 0: - effect = expr(effect) + elif isinstance(clauses, str): + clauses = clauses.replace('~', 'Not') + if len(clauses) > 0: + clauses = expr(clauses) - try: - precond = conjuncts(precond) - except AttributeError: - pass - try: - effect = conjuncts(effect) - except AttributeError: - pass + try: + clauses = conjuncts(clauses) + except AttributeError: + pass - return precond, effect + return clauses def substitute(self, e, args): """Replaces variables in expression with their respective Propositional symbol""" @@ -138,10 +144,10 @@ def act(self, kb, args): def air_cargo(): """Air cargo problem""" - 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)', + 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)', goals='At(C1, JFK) & At(C2, SFO)', actions=[Action('Load(c, p, a)', - precond='At(c, a) & At(p, a) & Cargo(c) & Plane(p) & Airport(a)', + precond='At(c, a) & At(p, a) & Cargo(c) & Plane(p) & Airport(a)', effect='In(c, p) & ~At(c, a)'), Action('Unload(c, p, a)', precond='In(c, p) & At(p, a) & Cargo(c) & Plane(p) & Airport(a)', @@ -207,6 +213,25 @@ def shopping_problem(): effect='At(y) & ~At(x)')]) +def socks_and_shoes(): + """Socks and shoes problem""" + + return PDDL(init='', + goals='RightShoeOn & LeftShoeOn', + actions=[Action('RightShoe', + precond='RightSockOn', + effect='RightShoeOn'), + Action('RightSock', + precond='', + effect='RightSockOn'), + Action('LeftShoe', + precond='LeftSockOn', + effect='LeftShoeOn'), + Action('LeftSock', + precond='', + effect='LeftSockOn')]) + + class Level: """ Contains the state of the planning problem @@ -559,6 +584,26 @@ def goal_test(kb, goals): return None +def socks_and_shoes_graphplan(): + pddl = socks_and_shoes() + graphplan = GraphPlan(pddl) + + def goal_test(kb, goals): + return all(kb.ask(q) is not False for q in goals) + + goals = expr('RightShoeOn, LeftShoeOn') + + while True: + if (goal_test(graphplan.graph.levels[-1].kb, goals) and graphplan.graph.non_mutex_goals(goals, -1)): + solution = graphplan.extract_solution(goals, -1) + if solution: + return solution + + graphplan.graph.expand_graph() + if len(graphplan.graph.levels) >= 2 and graphplan.check_leveloff(): + return None + + def linearize(solution): """Converts a level-ordered solution into a linear solution"""