docs: def astar(problem, graph_search=False, viewer=None):
      '''
      A* search.
  
      If graph_search=True, will avoid exploring repeated states.
      Requires: SearchProblem.actions, SearchProblem.result,
      SearchProblem.is_goal, SearchProblem.cost, and SearchProblem.heuristic.
      '''
      return _search(problem,
                     BoundedPriorityQueue(),
                     graph_search=graph_search,
                     node_factory=SearchNodeStarOrdered,
                     graph_replace_when_better=True,
                     viewer=viewer)