for pname in all_applicable_planners:
  with OneshotPlanner(name=pname) as planner:
    res = planner.solve(problem)
    print(res)
  *** Credits ***

  * In operation mode `OneshotPlanner` at line 2 of `/tmp/ipykernel_4328/3657586449.py`, you are using the following planning engine:

  * Engine name: Fast Downward

  * Developers:  Uni Basel team and contributors (cf. https://github.com/aibasel/downward/blob/main/README.md)

  * Description: Fast Downward is a domain-independent classical planning system.



status: SOLVED_SATISFICING

engine: Fast Downward

plan: SequentialPlan:

    pickup(d)

    stack(d, e)

    pickup(m)

    stack(m, o)

    unstack(d, e)

    putdown(d)

    pickup(e)

    stack(e, m)

    pickup(d)

    stack(d, e)

  *** Credits ***

  * In operation mode `OneshotPlanner` at line 2 of `/tmp/ipykernel_4328/3657586449.py`, you are using the following planning engine:

  * Engine name: Fast Downward

  * Developers:  Uni Basel team and contributors (cf. https://github.com/aibasel/downward/blob/main/README.md)

  * Description: Fast Downward is a domain-independent classical planning system.



status: SOLVED_SATISFICING

engine: Fast Downward (with optimality guarantee)

plan: SequentialPlan:

    pickup(m)

    stack(m, o)

    pickup(e)

    stack(e, m)

    pickup(d)

    stack(d, e)

  *** Credits ***

  * In operation mode `OneshotPlanner` at line 2 of `/tmp/ipykernel_4328/3657586449.py`, you are using the following planning engine:

  * Engine name: SymK

  * Developers:  David Speck (cf. https://github.com/speckdavid/symk/blob/master/README.md )

  * Description: SymK is a state-of-the-art domain-independent optimal and top-k planner.



status: SOLVED_SATISFICING

engine: SymK

plan: SequentialPlan:

    pickup(m)

    stack(m, o)

    pickup(e)

    stack(e, m)

    pickup(d)

    stack(d, e)

  *** Credits ***

  * In operation mode `OneshotPlanner` at line 2 of `/tmp/ipykernel_4328/3657586449.py`, you are using the following planning engine:

  * Engine name: SymK

  * Developers:  David Speck (cf. https://github.com/speckdavid/symk/blob/master/README.md )

  * Description: SymK is a state-of-the-art domain-independent optimal and top-k planner.



status: SOLVED_SATISFICING

engine: SymK (with optimality guarantee)

plan: SequentialPlan:

    pickup(m)

    stack(m, o)

    pickup(e)

    stack(e, m)

    pickup(d)

    stack(d, e)

  *** Credits ***

  * In operation mode `OneshotPlanner` at line 2 of `/tmp/ipykernel_4328/3657586449.py`, you are using the following planning engine:

  * Engine name: ENHSP

  * Developers:  Enrico Scala

  * Description: Expressive Numeric Heuristic Search Planner.



---------------------------------------------------------------------------

FileNotFoundError                         Traceback (most recent call last)

Cell In[12], line 3

      1 for pname in all_applicable_planners:

      2   with OneshotPlanner(name=pname) as planner:

----> 3     res = planner.solve(problem)

      4     print(res)



File /workspaces/engineering-ai-agents/.venv/lib/python3.11/site-packages/unified_planning/engines/mixins/oneshot_planner.py:80, in OneshotPlannerMixin.solve(self, problem, heuristic, timeout, output_stream)

     78     msg = f"The problem has no quality metrics but the engine is required to be optimal!"

     79     raise up.exceptions.UPUsageError(msg)

---> 80 return self._solve(problem, heuristic, timeout, output_stream)



File /workspaces/engineering-ai-agents/.venv/lib/python3.11/site-packages/unified_planning/engines/pddl_planner.py:178, in PDDLPlanner._solve(self, problem, heuristic, timeout, output_stream)

    174 process_start = time.time()

    175 if output_stream is None:

    176     # If we do not have an output stream to write to, we simply call

    177     # a subprocess and retrieve the final output and error with communicate

--> 178     process = subprocess.Popen(

    179         cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE

    180     )

    181     timeout_occurred: bool = False

    182     proc_out: List[str] = []



File /opt/rye/py/cpython@3.11.11/lib/python3.11/subprocess.py:1026, in Popen.__init__(self, args, bufsize, executable, stdin, stdout, stderr, preexec_fn, close_fds, shell, cwd, env, universal_newlines, startupinfo, creationflags, restore_signals, start_new_session, pass_fds, user, group, extra_groups, encoding, errors, text, umask, pipesize, process_group)

   1022         if self.text_mode:

   1023             self.stderr = io.TextIOWrapper(self.stderr,

   1024                     encoding=encoding, errors=errors)

-> 1026     self._execute_child(args, executable, preexec_fn, close_fds,

   1027                         pass_fds, cwd, env,

   1028                         startupinfo, creationflags, shell,

   1029                         p2cread, p2cwrite,

   1030                         c2pread, c2pwrite,

   1031                         errread, errwrite,

   1032                         restore_signals,

   1033                         gid, gids, uid, umask,

   1034                         start_new_session, process_group)

   1035 except:

   1036     # Cleanup if the child failed starting.

   1037     for f in filter(None, (self.stdin, self.stdout, self.stderr)):



File /opt/rye/py/cpython@3.11.11/lib/python3.11/subprocess.py:1955, in Popen._execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, restore_signals, gid, gids, uid, umask, start_new_session, process_group)

   1953     err_msg = os.strerror(errno_num)

   1954 if err_filename is not None:

-> 1955     raise child_exception_type(errno_num, err_msg, err_filename)

   1956 else:

   1957     raise child_exception_type(errno_num, err_msg)



FileNotFoundError: [Errno 2] No such file or directory: 'java'

The unified_planning.plot package provides useful functions to visually plot many objects

import unified_planning.plot as plt

plt.plot_causal_graph(problem=problem,figsize=(40,40))
plt.plot_plan(res.plan)
  *** Credits ***

  * In operation mode `Compiler` at line 1163 of `/workspaces/engineering-ai-agents/.venv/lib/python3.11/site-packages/unified_planning/model/problem.py`, you are using the following planning engine:

  * Engine name: Fast Downward

  * Developers:  Uni Basel team and contributors (cf. https://github.com/aibasel/downward/blob/main/README.md)

  * Description: Fast Downward is a domain-independent classical planning system.



---------------------------------------------------------------------------

ModuleNotFoundError                       Traceback (most recent call last)

File /workspaces/engineering-ai-agents/.venv/lib/python3.11/site-packages/networkx/drawing/nx_agraph.py:301, in pygraphviz_layout(G, prog, root, args)

    300 try:

--> 301     import pygraphviz

    302 except ImportError as err:



ModuleNotFoundError: No module named 'pygraphviz'



The above exception was the direct cause of the following exception:



ImportError                               Traceback (most recent call last)

Cell In[8], line 3

      1 import unified_planning.plot as plt

----> 3 plt.plot_causal_graph(problem=problem,figsize=(40,40))

      4 plt.plot_plan(res.plan)



File /workspaces/engineering-ai-agents/.venv/lib/python3.11/site-packages/unified_planning/plot/causal_graph_plot.py:139, in plot_causal_graph(problem, filename, figsize, top_bottom, generate_node_label, arrowsize, node_size, node_color, edge_color, font_size, font_color, generate_edge_label, edge_font_size, edge_font_color, draw_networkx_kwargs, draw_networkx_edge_labels_kwargs)

    130 edge_labels_set: Dict[Tuple[FNode, FNode], Set[str]] = {

    131     k: set(edge_label_function(e.action, e.actual_parameters) for e in v)

    132     for k, v in edge_actions.items()

    133 }

    135 edge_labels: Dict[Tuple[FNode, FNode], str] = {

    136     edge: ", ".join(labels) for edge, labels in edge_labels_set.items() if labels

    137 }

--> 139 fig, ax, pos = draw_base_graph(

    140     graph,

    141     figsize=figsize,

    142     top_bottom=top_bottom,

    143     generate_node_label=generate_node_label,

    144     arrowsize=arrowsize,

    145     node_size=node_size,

    146     node_color=node_color,

    147     edge_color=edge_color,

    148     font_size=font_size,

    149     font_color=font_color,

    150     draw_networkx_kwargs=draw_networkx_kwargs,

    151     prog="dot",

    152 )

    153 nx.draw_networkx_edge_labels(

    154     graph,

    155     pos,

   (...)    160     **draw_networkx_edge_labels_kwargs,

    161 )

    162 if filename is None:



File /workspaces/engineering-ai-agents/.venv/lib/python3.11/site-packages/unified_planning/plot/utils.py:96, in draw_base_graph(graph, figsize, top_bottom, generate_node_label, arrowsize, node_size, node_color, edge_color, font_size, font_color, draw_networkx_kwargs, prog)

     93 fig = plt.figure(figsize=figsize)

     94 ax = fig.add_subplot()

---> 96 pos = _generate_positions(graph, prog=prog, top_bottom=top_bottom)

     98 nx.draw_networkx(

     99     graph,

    100     pos,

   (...)    111     **draw_networkx_kwargs,

    112 )

    113 return fig, ax, pos



File /workspaces/engineering-ai-agents/.venv/lib/python3.11/site-packages/unified_planning/plot/utils.py:140, in _generate_positions(graph, prog, top_bottom)

    137 else:

    138     new_graph.graph.setdefault("graph", {})["rankdir"] = "LR"

--> 140 new_pos = nx.nx_agraph.graphviz_layout(new_graph, prog=prog)

    142 pos = {id_to_node[i]: value for i, value in new_pos.items()}

    144 return pos



File /workspaces/engineering-ai-agents/.venv/lib/python3.11/site-packages/networkx/drawing/nx_agraph.py:257, in graphviz_layout(G, prog, root, args)

    226 def graphviz_layout(G, prog="neato", root=None, args=""):

    227     """Create node positions for G using Graphviz.

    228 

    229     Parameters

   (...)    255     see https://gitlab.com/graphviz/graphviz/-/issues/1767 for more info.

    256     """

--> 257     return pygraphviz_layout(G, prog=prog, root=root, args=args)



File /workspaces/engineering-ai-agents/.venv/lib/python3.11/site-packages/networkx/drawing/nx_agraph.py:303, in pygraphviz_layout(G, prog, root, args)

    301     import pygraphviz

    302 except ImportError as err:

--> 303     raise ImportError("requires pygraphviz http://pygraphviz.github.io/") from err

    304 if root is not None:

    305     args += f"-Groot={root}"



ImportError: requires pygraphviz http://pygraphviz.github.io/

Specifying the engine name

We can also explicitly specify the name of the engine we want to use (and optionally custom parameters). The interface, after the openation mode is identical.

with OneshotPlanner(name="lpg") as planner:
  res = planner.solve(problem)
  print(res)
  *** Credits ***

  * In operation mode `OneshotPlanner` at line 1 of `/tmp/ipykernel_4328/719035379.py`, you are using the following planning engine:

  * Engine name: LPG

  * Developers:  UNIBS Team

  * Description: LPG is a planner based on local search and planning graphs.



/workspaces/engineering-ai-agents/.venv/lib/python3.11/site-packages/unified_planning/engines/mixins/oneshot_planner.py:76: UserWarning: We cannot establish whether lpg can solve this problem!
  warn(msg)
---------------------------------------------------------------------------

PermissionError                           Traceback (most recent call last)

Cell In[9], line 2

      1 with OneshotPlanner(name="lpg") as planner:

----> 2   res = planner.solve(problem)

      3   print(res)



File /workspaces/engineering-ai-agents/.venv/lib/python3.11/site-packages/unified_planning/engines/mixins/oneshot_planner.py:80, in OneshotPlannerMixin.solve(self, problem, heuristic, timeout, output_stream)

     78     msg = f"The problem has no quality metrics but the engine is required to be optimal!"

     79     raise up.exceptions.UPUsageError(msg)

---> 80 return self._solve(problem, heuristic, timeout, output_stream)



File /workspaces/engineering-ai-agents/.venv/lib/python3.11/site-packages/unified_planning/engines/pddl_planner.py:178, in PDDLPlanner._solve(self, problem, heuristic, timeout, output_stream)

    174 process_start = time.time()

    175 if output_stream is None:

    176     # If we do not have an output stream to write to, we simply call

    177     # a subprocess and retrieve the final output and error with communicate

--> 178     process = subprocess.Popen(

    179         cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE

    180     )

    181     timeout_occurred: bool = False

    182     proc_out: List[str] = []



File /opt/rye/py/cpython@3.11.11/lib/python3.11/subprocess.py:1026, in Popen.__init__(self, args, bufsize, executable, stdin, stdout, stderr, preexec_fn, close_fds, shell, cwd, env, universal_newlines, startupinfo, creationflags, restore_signals, start_new_session, pass_fds, user, group, extra_groups, encoding, errors, text, umask, pipesize, process_group)

   1022         if self.text_mode:

   1023             self.stderr = io.TextIOWrapper(self.stderr,

   1024                     encoding=encoding, errors=errors)

-> 1026     self._execute_child(args, executable, preexec_fn, close_fds,

   1027                         pass_fds, cwd, env,

   1028                         startupinfo, creationflags, shell,

   1029                         p2cread, p2cwrite,

   1030                         c2pread, c2pwrite,

   1031                         errread, errwrite,

   1032                         restore_signals,

   1033                         gid, gids, uid, umask,

   1034                         start_new_session, process_group)

   1035 except:

   1036     # Cleanup if the child failed starting.

   1037     for f in filter(None, (self.stdin, self.stdout, self.stderr)):



File /opt/rye/py/cpython@3.11.11/lib/python3.11/subprocess.py:1955, in Popen._execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, restore_signals, gid, gids, uid, umask, start_new_session, process_group)

   1953     err_msg = os.strerror(errno_num)

   1954 if err_filename is not None:

-> 1955     raise child_exception_type(errno_num, err_msg, err_filename)

   1956 else:

   1957     raise child_exception_type(errno_num, err_msg)



PermissionError: [Errno 13] Permission denied: '/workspaces/engineering-ai-agents/.venv/lib/python3.11/site-packages/up_lpg/lpg'

Parallel solving

We can even execute more than one planner in parallel and use this “parallel portfolio” as a normal planner.

with OneshotPlanner(names=["tamer", "fast-downward"]) as planner:
  res = planner.solve(problem)
  print(res)
  *** Credits ***

  * In operation mode `OneshotPlanner` at line 1 of `/tmp/ipykernel_4328/1972089550.py`, you are using a parallel planning engine with the following components:

  * Engine name: Tamer

  * Developers:  FBK Tamer Development Team

  * Description: Tamer offers the capability to generate a plan for classical, numerical and temporal problems.

  *              For those kind of problems tamer also offers the possibility of validating a submitted plan.

  * Engine name: Fast Downward

  * Developers:  Uni Basel team and contributors (cf. https://github.com/aibasel/downward/blob/main/README.md)

  * Description: Fast Downward is a domain-independent classical planning system.



status: SOLVED_SATISFICING

engine: Tamer

plan: SequentialPlan:

    pickup(m)

    stack(m, o)

    pickup(e)

    stack(e, m)

    pickup(d)

    stack(d, e)

The interface is the same!

All engines supporting an OperationMode are required to support the same interface and being interchangeable.

all_applicable_planners = get_all_applicable_engines(problem_kind=problem.kind, operation_mode=OperationMode.ONESHOT_PLANNER)
print(all_applicable_planners)
['fast-downward', 'fast-downward-opt', 'symk', 'symk-opt', 'enhsp', 'enhsp-opt', 'enhsp-any', 'tamer', 'aries', 'oversubscription[fast-downward]', 'oversubscription[fast-downward-opt]', 'oversubscription[symk]', 'oversubscription[symk-opt]', 'oversubscription[enhsp]', 'oversubscription[enhsp-opt]', 'oversubscription[enhsp-any]', 'oversubscription[tamer]', 'oversubscription[aries]']
Back to top