<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def create_graph_from_adjacency_matrix(adjacency_matrix):
 """Generates a graph from an adjacency matrix specification. Returns a tuple containing the graph and a list-mapping of node ids to matrix column indices. The graph will be an UndirectedGraph if the provided adjacency matrix is symmetric. The graph will be a DirectedGraph if the provided adjacency matrix is not symmetric. Ref: http://mathworld.wolfram.com/AdjacencyMatrix.html"""

    if is_adjacency_matrix_symmetric(adjacency_matrix):
        graph = UndirectedGraph()
    else:
        graph = DirectedGraph()

    node_column_mapping = []

    num_columns = len(adjacency_matrix)
    for _ in range(num_columns):
        node_id = graph.new_node()
        node_column_mapping.append(node_id)

    for j in range(num_columns):
        for i in range(num_columns):
            if adjacency_matrix[j][i]:
                jnode_id = node_column_mapping[j]
                inode_id = node_column_mapping[i]
                # Because of our adjacency matrix encoding, [j][i] in our code corresponds to [i][j] in a traditional matrix interpretation
                # Thus, we need to put an edge from node i to node j if [j][i] in our code is non-zero
                graph.new_edge(inode_id, jnode_id)

    return (graph, node_column_mapping)