searching for solutions def heuristic(self,node)"""gives the heuristic value of node returns if not overridden in the hmap ""if node in self hmapreturn self hmap[nodeelsereturn def __repr__(self)"""returns string representation of the search problem""res="for arc in self arcsres +str(arc)+return res the following is used for the depth-first search implementation below searchproblem py -(continued def neighbor_nodes(self,node)"""returns an iterator over the neighbors of node""return (path to_node for path in self neighs[node]paths searcher will return path from the start node to goal node python list is not suitable representation for pathas many search algorithms consider multiple paths at onceand these paths should share initial parts of the path if we wanted to do this with python listswe would need to keep copying the listwhich can be expensive if the list is long an alternative representation is used here in terms of recursive data structure that can share subparts path is eithera node (representing path of length or pathinitial and an arcwhere the from node of the arc is the node at the end of initial these cases are distinguished in the following code by having arc none if the path has length in which case initial is the node of the path python yield is used for enumerations only searchproblem py -(continued class path(object)""" path is either node or path followed by an arc"" def __init__(self,initial,arc=none)"""initial is either node (in which case arc is noneor path (in which case arc is an object of type arc)""self initial initial version june