def flatten(self): from mocdp.comp.flattening.flatten import cndp_flatten return cndp_flatten(self)
def cndp_makecanonical(ndp, name_inner_muxed='_inner_muxed', s_muxed='_muxed'): """ Returns a composite with only one ndp, called <named_inner_muxed>. If there were cycles, then this will also have a signal caled s_muxed and there will be one connection to it. raises DPSemanticErrorNotConnected """ assert isinstance(ndp, CompositeNamedDP), type(ndp) try: ndp.check_fully_connected() except NotConnected as e: msg = 'Cannot put in canonical form because not all subproblems are connected.' raise_wrapped(DPSemanticErrorNotConnected, e, msg, compact=True) fnames = ndp.get_fnames() rnames = ndp.get_rnames() # First, we flatten it ndp = cndp_flatten(ndp) assert ndp.get_fnames() == fnames assert ndp.get_rnames() == rnames # then we compact it (take the product of edges) # Note also that this abstract() the children; # however, because we flattened before, this is redundant, # as every DP is a SimpleDP ndp = ndp.compact() assert ndp.get_fnames() == fnames assert ndp.get_rnames() == rnames # Check that we have some cycles G = get_connection_multigraph(ndp.get_connections()) cycles = list(simple_cycles(G)) if not cycles: ndp_inner = ndp cycles_names = [] else: # then we choose which edges to remove connections_to_cut = choose_connections_to_cut( connections=ndp.get_connections(), name2dp=ndp.get_name2ndp()) connections_to_cut = list(connections_to_cut) n = len(connections_to_cut) cycles_names = list(['cut%d' % _ for _ in range(n)]) ndp_inner = cndp_create_one_without_some_connections( ndp, connections_to_cut, cycles_names) assert ndp_inner.get_fnames() == fnames + cycles_names assert ndp_inner.get_rnames() == rnames + cycles_names if cycles_names: ndp_inner_muxed = add_muxes(ndp_inner, cs=cycles_names, s_muxed=s_muxed) mux_signal = s_muxed assert ndp_inner_muxed.get_fnames() == fnames + [mux_signal] assert ndp_inner_muxed.get_rnames() == rnames + [mux_signal] else: ndp_inner_muxed = ndp_inner name2ndp = {} name2ndp[name_inner_muxed] = ndp_inner_muxed connections = [] connect_functions_to_outside(name2ndp, connections, ndp_name=name_inner_muxed, fnames=fnames) connect_resources_to_outside(name2ndp, connections, ndp_name=name_inner_muxed, rnames=rnames) if cycles_names: connections.append( Connection(name_inner_muxed, mux_signal, name_inner_muxed, mux_signal)) outer = CompositeNamedDP.from_parts(name2ndp=name2ndp, connections=connections, fnames=fnames, rnames=rnames) return outer
def cndp_makecanonical(ndp, name_inner_muxed="_inner_muxed", s_muxed="_muxed"): """ Returns a composite with only one ndp, called <named_inner_muxed>. If there were cycles, then this will also have a signal caled s_muxed and there will be one connection to it. raises DPSemanticErrorNotConnected """ assert isinstance(ndp, CompositeNamedDP), type(ndp) try: ndp.check_fully_connected() except NotConnected as e: msg = "Cannot put in canonical form because not all subproblems are connected." raise_wrapped(DPSemanticErrorNotConnected, e, msg, compact=True) fnames = ndp.get_fnames() rnames = ndp.get_rnames() # First, we flatten it ndp = cndp_flatten(ndp) assert ndp.get_fnames() == fnames assert ndp.get_rnames() == rnames # then we compact it (take the product of edges) # Note also that this abstract() the children; # however, because we flattened before, this is redundant, # as every DP is a SimpleDP ndp = ndp.compact() assert ndp.get_fnames() == fnames assert ndp.get_rnames() == rnames # Check that we have some cycles G = get_connection_multigraph(ndp.get_connections()) cycles = list(simple_cycles(G)) if not cycles: ndp_inner = ndp cycles_names = [] else: # then we choose which edges to remove connections_to_cut = choose_connections_to_cut(connections=ndp.get_connections(), name2dp=ndp.get_name2ndp()) connections_to_cut = list(connections_to_cut) n = len(connections_to_cut) cycles_names = list(["cut%d" % _ for _ in range(n)]) ndp_inner = cndp_create_one_without_some_connections(ndp, connections_to_cut, cycles_names) assert ndp_inner.get_fnames() == fnames + cycles_names assert ndp_inner.get_rnames() == rnames + cycles_names if cycles_names: ndp_inner_muxed = add_muxes(ndp_inner, cs=cycles_names, s_muxed=s_muxed) mux_signal = s_muxed assert ndp_inner_muxed.get_fnames() == fnames + [mux_signal] assert ndp_inner_muxed.get_rnames() == rnames + [mux_signal] else: ndp_inner_muxed = ndp_inner name2ndp = {} name2ndp[name_inner_muxed] = ndp_inner_muxed connections = [] connect_functions_to_outside(name2ndp, connections, ndp_name=name_inner_muxed, fnames=fnames) connect_resources_to_outside(name2ndp, connections, ndp_name=name_inner_muxed, rnames=rnames) if cycles_names: connections.append(Connection(name_inner_muxed, mux_signal, name_inner_muxed, mux_signal)) outer = CompositeNamedDP.from_parts(name2ndp=name2ndp, connections=connections, fnames=fnames, rnames=rnames) return outer