def flatten_graph(output_graph, graph, templates, context, edge_node_ids, arg_map):
    components = {}
    for e in graph.edge_info:
        copy_edge = ValueInfo()
        if is_literal(e):
            uid = str(e)
            copy_edge.CopyFrom(graph.edge_info[e])
            copy_edge.name = uid
        elif (e in arg_map.keys()):
            uid = (context + e)
            copy_edge.CopyFrom(arg_map[e])
            copy_edge.attributes['alias'].CopyFrom(hdfgutils.make_attribute('alias', arg_map[e].name))
        else:
            uid = (context + e)
            copy_edge.CopyFrom(graph.edge_info[e])
            copy_edge.name = uid
        if ((e in graph.input) and (e not in output_graph.input)):
            output_graph.input.extend([uid])
        elif ((e in graph.state) and (e not in output_graph.state)):
            output_graph.state.extend([uid])
        elif ((e in graph.output) and (e not in output_graph.output)):
            output_graph.output.extend([uid])
        elif ((e in graph.parameters) and (e not in output_graph.parameters)):
            output_graph.parameters.extend([uid])
        if (graph.name != 'main'):
            ordered_args = hdfgutils.get_attribute_value(graph.attributes['ordered_args'])
        else:
            ordered_args = []
        if ('dimensions' in list(copy_edge.attributes)):
            dims = hdfgutils.get_attribute_value(copy_edge.attributes['dimensions'])
            new_dims = []
            for d in dims:
                if (d in arg_map.keys()):
                    new_dims.append(arg_map[d].name)
                else:
                    new_dims.append(d)
            copy_edge.attributes['dimensions'].CopyFrom(hdfgutils.make_attribute('dimensions', new_dims))
        if (uid not in edge_node_ids['edges'].keys()):
            edge_node_ids['edges'][uid] = str(len(edge_node_ids['edges'].keys()))
            output_graph.edge_info[uid].CopyFrom(copy_edge)
            if (e not in arg_map.keys()):
                output_graph.edge_info[uid].gid = int(edge_node_ids['edges'][uid])
                output_graph.edge_info[uid].attributes['component_type'].CopyFrom(hdfgutils.make_attribute('component_type', graph.op_type))
    for n in graph.sub_graph:
        op_cat = n.op_cat
        if (op_cat == 'component'):
            if (n.op_type in components.keys()):
                components[n.op_type] += 1
                new_context = (((context + n.op_type) + str(components[n.op_type])) + '/')
            else:
                components[n.op_type] = 0
                new_context = (((context + n.op_type) + str(components[n.op_type])) + '/')
            instance_args = hdfgutils.get_attribute_value(n.attributes['ordered_args'])
            ctemplate = templates[n.op_type]
            signature_args = hdfgutils.get_attribute_value(ctemplate.attributes['ordered_args'])
            carg_map = create_map(instance_args, signature_args, graph.edge_info, ctemplate.edge_info, templates[n.op_type])
            update_statement_graphs(ctemplate, output_graph, new_context)
            flatten_graph(output_graph, ctemplate, templates, new_context, edge_node_ids, carg_map)
        else:
            new = update_node(n, context, arg_map)
            if (new.name not in edge_node_ids['nodes'].keys()):
                edge_node_ids['nodes'][new.name] = str(len(edge_node_ids['nodes'].keys()))
            new.gid = int(edge_node_ids['nodes'][new.name])
            output_graph.sub_graph.extend([new])
def flatten_graph(output_graph, graph, templates, context, edge_node_ids, arg_map):
    components = {}
    for e in graph.edge_info:
        copy_edge = ValueInfo()
        if is_literal(e):
            uid = str(e)
            copy_edge.CopyFrom(graph.edge_info[e])
            copy_edge.name = uid
        elif (e in arg_map.keys()):
            uid = (context + e)
            copy_edge.CopyFrom(arg_map[e])
            copy_edge.attributes['alias'].CopyFrom(hdfgutils.make_attribute('alias', arg_map[e].name))
        else:
            uid = (context + e)
            copy_edge.CopyFrom(graph.edge_info[e])
            copy_edge.name = uid
        if ((e in graph.input) and (e not in output_graph.input)):
            output_graph.input.extend([uid])
        elif ((e in graph.state) and (e not in output_graph.state)):
            output_graph.state.extend([uid])
        elif ((e in graph.output) and (e not in output_graph.output)):
            output_graph.output.extend([uid])
        elif ((e in graph.parameters) and (e not in output_graph.parameters)):
            output_graph.parameters.extend([uid])
        if (graph.name != 'main'):
            ordered_args = hdfgutils.get_attribute_value(graph.attributes['ordered_args'])
        else:
            ordered_args = []
        if ('dimensions' in list(copy_edge.attributes)):
            dims = hdfgutils.get_attribute_value(copy_edge.attributes['dimensions'])
            new_dims = []
            for d in dims:
                if (d in arg_map.keys()):
                    new_dims.append(arg_map[d].name)
                else:
                    new_dims.append(d)
            copy_edge.attributes['dimensions'].CopyFrom(hdfgutils.make_attribute('dimensions', new_dims))
        if (uid not in edge_node_ids['edges'].keys()):
            edge_node_ids['edges'][uid] = str(len(edge_node_ids['edges'].keys()))
            output_graph.edge_info[uid].CopyFrom(copy_edge)
            if (e not in arg_map.keys()):
                output_graph.edge_info[uid].gid = int(edge_node_ids['edges'][uid])
                output_graph.edge_info[uid].attributes['component_type'].CopyFrom(hdfgutils.make_attribute('component_type', graph.op_type))
    for n in graph.sub_graph:
        op_cat = n.op_cat
        if (op_cat == 'component'):
            if (n.op_type in components.keys()):
                components[n.op_type] += 1
                new_context = (((context + n.op_type) + str(components[n.op_type])) + '/')
            else:
                components[n.op_type] = 0
                new_context = (((context + n.op_type) + str(components[n.op_type])) + '/')
            instance_args = hdfgutils.get_attribute_value(n.attributes['ordered_args'])
            ctemplate = templates[n.op_type]
            signature_args = hdfgutils.get_attribute_value(ctemplate.attributes['ordered_args'])
            carg_map = create_map(instance_args, signature_args, graph.edge_info, ctemplate.edge_info, templates[n.op_type])
            update_statement_graphs(ctemplate, output_graph, new_context)
            flatten_graph(output_graph, ctemplate, templates, new_context, edge_node_ids, carg_map)
        else:
            new = update_node(n, context, arg_map)
            if (new.name not in edge_node_ids['nodes'].keys()):
                edge_node_ids['nodes'][new.name] = str(len(edge_node_ids['nodes'].keys()))
            new.gid = int(edge_node_ids['nodes'][new.name])
            output_graph.sub_graph.extend([new])