<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def add_edge(self, p_from, p_to, p_id=None):
 """ Adds an edge to the graph. The nodes will be added if they don't exist. The p_id is the id of the edge, if the client wishes to maintain this. """

        if not self.has_edge(p_from, p_to):
            if not self.has_node(p_from):
                self.add_node(p_from)

            if not self.has_node(p_to):
                self.add_node(p_to)

            self._edges[p_from].add(p_to)
            self._edge_numbers[(p_from, p_to)] = p_id