# 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)
            lhs_typing=lhs_typing,
            p_typing=p_typing,
            rhs_typing_rel=rhs_typing,
            p_lhs=rule.p_lhs,
            p_rhs=rule.p_rhs)

    # Check the instance
    _check_instance(
        hierarchy, graph_id, rule.lhs, instance, lhs_typing)

    # Check consistency of the (autocompleted) rhs/p/lhs typings
    if lhs_typing is not None and rhs_typing is not None:
        try:
            _check_self_consistency(
                hierarchy, lhs_typing)
        except ReGraphError as e:
            raise RewritingError(
                "Typing of the lhs is self inconsistent: %s" % str(e)
            )
        try:
            _check_p_consistency(
                hierarchy, rule.p_lhs, rule.cloned_nodes(), p_typing)
        except ReGraphError as e:
            raise RewritingError(
                "Typing of the preserved part is "
                "self inconsistent: {}".format(e)
            )
        try:
            _check_self_consistency(
                hierarchy, rhs_typing, strict)

# 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)

            lhs_typing=lhs_typing,
            p_typing=p_typing,
            rhs_typing_rel=rhs_typing,
            p_lhs=rule.p_lhs,
            p_rhs=rule.p_rhs)

    # Check the instance
    _check_instance(
        hierarchy, graph_id, rule.lhs, instance, lhs_typing)

    # Check consistency of the (autocompleted) rhs/p/lhs typings
    if lhs_typing is not None and rhs_typing is not None:
        try:
            _check_self_consistency(
                hierarchy, lhs_typing)
        except ReGraphError as e:
            raise RewritingError(
                "Typing of the lhs is self inconsistent: %s" % str(e)
            )
        try:
            _check_p_consistency(
                hierarchy, rule.p_lhs, rule.cloned_nodes(), p_typing)
        except ReGraphError as e:
            raise RewritingError(
                "Typing of the preserved part is "
                "self inconsistent: {}".format(e)
            )
        try:
            _check_self_consistency(
                hierarchy, rhs_typing, strict)

        except ReGraphError as e: