# Path: regraph/exceptions.py
# class ReGraphError(ReGraphException):
#     """Exception for errors in ReGraph."""
# 
# class RewritingError(ReGraphException):
#     """Exceptions class for errors in rewriting in a hierarchy."""
# 
# class HierarchyError(ReGraphException):
#     """Exceptions class for hierarchy handling."""
# 
# class InvalidHomomorphism(ReGraphException):
#     """Exceptions class for invalid homomorphisms."""
# 
# Path: regraph/utils.py
# def keys_by_value(dictionary, val):
#     """Get keys of a dictionary by a value."""
#     res = []
#     for key, value in dictionary.items():
#         if value == val:
#             res.append(key)
#     return res
# 
# def format_typing(typing):
#     if typing is None:
#         typing = dict()
#     new_typing = dict()
#     for key, value in typing.items():
#         if type(value) == dict:
#             new_typing[key] = copy.deepcopy(value)
#         else:
#             try:
#                 if len(value) == 2:
#                     new_typing[key] = copy.deepcopy(value)
#                 elif len(value) == 1:
#                     new_typing[key] = copy.deepcopy(value[0])
#             except:
#                 raise ReGraphError("Typing format is not valid!")
#     return new_typing
# 
# def normalize_typing_relation(typing_rel):
#     new_typing_rel = format_typing(typing_rel)
#     for g, typing_rel in new_typing_rel.items():
#         for key, values in typing_rel.items():
#             value_set = set()
#             if type(values) == str:
#                 value_set.add(values)
#             else:
#                 try:
#                     for v in values:
#                         value_set.add(v)
#                 except TypeError:
#                     value_set.add(values)
#             if len(value_set) > 0:
#                 new_typing_rel[g][key] = value_set
#     return new_typing_rel


import networkx as nx
from networkx.exception import NetworkXNoPath
from regraph.exceptions import (ReGraphError,
                                RewritingError,
                                HierarchyError,
                                InvalidHomomorphism)
from regraph.utils import (keys_by_value,
                           format_typing,
                           normalize_typing_relation)
from regraph.networkx.category_utils import (check_homomorphism,
                                             compose,
                                             is_monic)
                            "path from '%s' to '%s'!" % (s, t)
                        )
                    if rhs_h != new_rhs_h:
                        raise HierarchyError(
                            "Invalid rhs typing: homomorphism does not "
                            "commute with an existing " +
                            "path from '%s' to '%s'!" % (s, t)
                        )
            except(nx.NetworkXNoPath):
                pass
    return


def _check_consistency(hierarchy, source, target, mapping=None):
    all_paths = dict(nx.all_pairs_shortest_path(hierarchy))

    paths_to_source = {}
    paths_from_target = {}
    for s in hierarchy.nodes():
        if source in all_paths[s].keys():
            paths_to_source[s] = all_paths[s][source]
        if s == target:
            for key in all_paths[target].keys():
                paths_from_target[key] = all_paths[target][key]

    for s in paths_to_source.keys():
        if hierarchy._path_from_rule(paths_to_source[s]):
            for t in paths_from_target.keys():
                # find homomorphism from s to t via new path
                if s == source:

# Path: regraph/exceptions.py
# class ReGraphError(ReGraphException):
#     """Exception for errors in ReGraph."""
# 
# class RewritingError(ReGraphException):
#     """Exceptions class for errors in rewriting in a hierarchy."""
# 
# class HierarchyError(ReGraphException):
#     """Exceptions class for hierarchy handling."""
# 
# class InvalidHomomorphism(ReGraphException):
#     """Exceptions class for invalid homomorphisms."""
# 
# Path: regraph/utils.py
# def keys_by_value(dictionary, val):
#     """Get keys of a dictionary by a value."""
#     res = []
#     for key, value in dictionary.items():
#         if value == val:
#             res.append(key)
#     return res
# 
# def format_typing(typing):
#     if typing is None:
#         typing = dict()
#     new_typing = dict()
#     for key, value in typing.items():
#         if type(value) == dict:
#             new_typing[key] = copy.deepcopy(value)
#         else:
#             try:
#                 if len(value) == 2:
#                     new_typing[key] = copy.deepcopy(value)
#                 elif len(value) == 1:
#                     new_typing[key] = copy.deepcopy(value[0])
#             except:
#                 raise ReGraphError("Typing format is not valid!")
#     return new_typing
# 
# def normalize_typing_relation(typing_rel):
#     new_typing_rel = format_typing(typing_rel)
#     for g, typing_rel in new_typing_rel.items():
#         for key, values in typing_rel.items():
#             value_set = set()
#             if type(values) == str:
#                 value_set.add(values)
#             else:
#                 try:
#                     for v in values:
#                         value_set.add(v)
#                 except TypeError:
#                     value_set.add(values)
#             if len(value_set) > 0:
#                 new_typing_rel[g][key] = value_set
#     return new_typing_rel


# Path: regraph/backends/networkx/utils/type_checking.py
import networkx as nx
from networkx.exception import NetworkXNoPath
from regraph.exceptions import (ReGraphError,
                                RewritingError,
                                HierarchyError,
                                InvalidHomomorphism)
from regraph.utils import (keys_by_value,
                           format_typing,
                           normalize_typing_relation)
from regraph.networkx.category_utils import (check_homomorphism,
                                             compose,
                                             is_monic)

                            "path from '%s' to '%s'!" % (s, t)
                        )
                    if rhs_h != new_rhs_h:
                        raise HierarchyError(
                            "Invalid rhs typing: homomorphism does not "
                            "commute with an existing " +
                            "path from '%s' to '%s'!" % (s, t)
                        )
            except(nx.NetworkXNoPath):
                pass
    return


def _check_consistency(hierarchy, source, target, mapping=None):
    all_paths = dict(nx.all_pairs_shortest_path(hierarchy))

    paths_to_source = {}
    paths_from_target = {}
    for s in hierarchy.nodes():
        if source in all_paths[s].keys():
            paths_to_source[s] = all_paths[s][source]
        if s == target:
            for key in all_paths[target].keys():
                paths_from_target[key] = all_paths[target][key]

    for s in paths_to_source.keys():
        if hierarchy._path_from_rule(paths_to_source[s]):
            for t in paths_from_target.keys():
                # find homomorphism from s to t via new path
                if s == source:

                    raise HierarchyError(