# Path: sdopt/nodes/types.py
# def is_sum_node(node_dict):
#     return node_dict[NodeAttr.type] == ntype.SUM
# 
# def is_var_node(node_dict):
#     return node_dict[NodeAttr.type] == ntype.VAR
# 
# Path: sdopt/nodes/attributes.py
# class NodeAttr:
#     bounds    =  1
#     con_num   =  2
#     d_term    =  3
#     display   =  4
#     input_ord =  5
#     n_term    =  6
#     name      =  7
#     node_id   =  8
#     number    =  9
#     operation = 10
#     type      = 11
#     var_num   = 12


from array import array
from collections import defaultdict
from ..nodes.types import is_sum_node, is_var_node
from ..nodes.attributes import NodeAttr
    from matplotlib import pyplot as plt
import networkx as nx
import six
    out_edges = dag.edge[node_to_del]
    # In case we already deleted the new parent in a previous round; reparent
    # would insert it again and that node would have an empty dict
    assert new_parent in dag, '{}, {}'.format(new_parent, node_to_del)
    assert_source(dag, node_to_del)
    remove_node(dag, node_to_del)
    for child_id, edge_dict in six.iteritems(out_edges):
        dag.add_edge(new_parent, child_id, edge_dict)
        replace(dag.node[child_id][NodeAttr.input_ord], node_to_del, new_parent)

def remove_node(dag, n):
    d = dag.node[n]
    assert NodeAttr.bounds not in d, d
    dag.remove_node(n)

def reverse_edge_to_get_def_var(dag, sum_node_id, var_node_id):
    # lambda * <var node> + <lin. comb.> + d = bounds
    #   node id:   n+1            n
    # <var node> = (-1/lambda) * ( <lin. comb.> + d - bounds)
    #
    # add the new reversed edge
    e = dag[var_node_id][sum_node_id]
    e['weight'] = -1.0/e['weight']
    add_edge(dag, sum_node_id, var_node_id, e)
    # drop the old edge
    dag.remove_edge(var_node_id, sum_node_id)
    # update the sum node
    d = dag.node[sum_node_id]
    # d_term -= rhs
    d_term = d.get(NodeAttr.d_term, 0.0) - d[NodeAttr.bounds].l# l == u == rhs

# Path: sdopt/nodes/types.py
# def is_sum_node(node_dict):
#     return node_dict[NodeAttr.type] == ntype.SUM
# 
# def is_var_node(node_dict):
#     return node_dict[NodeAttr.type] == ntype.VAR
# 
# Path: sdopt/nodes/attributes.py
# class NodeAttr:
#     bounds    =  1
#     con_num   =  2
#     d_term    =  3
#     display   =  4
#     input_ord =  5
#     n_term    =  6
#     name      =  7
#     node_id   =  8
#     number    =  9
#     operation = 10
#     type      = 11
#     var_num   = 12


# Path: sdopt/representation/dag_util.py
from array import array
from collections import defaultdict
from ..nodes.types import is_sum_node, is_var_node
from ..nodes.attributes import NodeAttr
    from matplotlib import pyplot as plt
import networkx as nx
import six

    out_edges = dag.edge[node_to_del]
    # In case we already deleted the new parent in a previous round; reparent
    # would insert it again and that node would have an empty dict
    assert new_parent in dag, '{}, {}'.format(new_parent, node_to_del)
    assert_source(dag, node_to_del)
    remove_node(dag, node_to_del)
    for child_id, edge_dict in six.iteritems(out_edges):
        dag.add_edge(new_parent, child_id, edge_dict)
        replace(dag.node[child_id][NodeAttr.input_ord], node_to_del, new_parent)

def remove_node(dag, n):
    d = dag.node[n]
    assert NodeAttr.bounds not in d, d
    dag.remove_node(n)

def reverse_edge_to_get_def_var(dag, sum_node_id, var_node_id):
    # lambda * <var node> + <lin. comb.> + d = bounds
    #   node id:   n+1            n
    # <var node> = (-1/lambda) * ( <lin. comb.> + d - bounds)
    #
    # add the new reversed edge
    e = dag[var_node_id][sum_node_id]
    e['weight'] = -1.0/e['weight']
    add_edge(dag, sum_node_id, var_node_id, e)
    # drop the old edge
    dag.remove_edge(var_node_id, sum_node_id)
    # update the sum node
    d = dag.node[sum_node_id]
    # d_term -= rhs
    d_term = d.get(NodeAttr.d_term, 0.0) - d[NodeAttr.bounds].l# l == u == rhs

    d[NodeAttr.d_term] = d_term                                #already asserted