-- | Given a TypedGraphMorphism tgm, creates an isomorphic TypedGraphMorphism
-- tgm' where the nodes and edges in the domain have the same ids as the ones in
-- the codomain
reflectIdsFromCodomain :: TypedGraphMorphism a b -> TypedGraphMorphism a b
reflectIdsFromCodomain tgm =
  let
    typedA = domainGraph tgm
    typedB = codomainGraph tgm
    tGraph = typeGraph typedA
    typedB' = GM.empty Untyped.empty tGraph
    nodes = nodeIds $ domainGraph tgm
    edges' = map fst . edges $ domainGraph tgm
    initial = buildTypedGraphMorphism typedB' typedB (GM.empty (toUntypedGraph typedB') (toUntypedGraph typedB))
    addNodes = foldr (\n -> createNodeOnDomain (applyNodeIdUnsafe tgm n) (GM.applyNodeIdUnsafe typedA n) (applyNodeIdUnsafe tgm n)) initial nodes
    addEdges = foldr (\e ->
      createEdgeOnDomain (applyEdgeIdUnsafe tgm (edgeId e))
                         (applyNodeIdUnsafe tgm (sourceId e))
                         (applyNodeIdUnsafe tgm (targetId e))
                         (GM.applyEdgeIdUnsafe typedA (edgeId e))
                         (applyEdgeIdUnsafe tgm (edgeId e))) addNodes edges'
   in addEdges
reflectIdsFromCodomain :: TypedGraphMorphism a b -> TypedGraphMorphism a b
reflectIdsFromCodomain tgm =
  let
    typedA = domainGraph tgm
    typedB = codomainGraph tgm
    tGraph = typeGraph typedA
    typedB' = GM.empty Untyped.empty tGraph
    nodes = nodeIds $ domainGraph tgm
    edges' = map fst . edges $ domainGraph tgm
    initial = buildTypedGraphMorphism typedB' typedB (GM.empty (toUntypedGraph typedB') (toUntypedGraph typedB))
    addNodes = foldr (\n -> createNodeOnDomain (applyNodeIdUnsafe tgm n) (GM.applyNodeIdUnsafe typedA n) (applyNodeIdUnsafe tgm n)) initial nodes
    addEdges = foldr (\e ->
      createEdgeOnDomain (applyEdgeIdUnsafe tgm (edgeId e))
                         (applyNodeIdUnsafe tgm (sourceId e))
                         (applyNodeIdUnsafe tgm (targetId e))
                         (GM.applyEdgeIdUnsafe typedA (edgeId e))
                         (applyEdgeIdUnsafe tgm (edgeId e))) addNodes edges'
   in addEdges
reflectIdsFromCodomain tgm =
  let
    typedA = domainGraph tgm
    typedB = codomainGraph tgm
    tGraph = typeGraph typedA
    typedB' = GM.empty Untyped.empty tGraph
    nodes = nodeIds $ domainGraph tgm
    edges' = map fst . edges $ domainGraph tgm
    initial = buildTypedGraphMorphism typedB' typedB (GM.empty (toUntypedGraph typedB') (toUntypedGraph typedB))
    addNodes = foldr (\n -> createNodeOnDomain (applyNodeIdUnsafe tgm n) (GM.applyNodeIdUnsafe typedA n) (applyNodeIdUnsafe tgm n)) initial nodes
    addEdges = foldr (\e ->
      createEdgeOnDomain (applyEdgeIdUnsafe tgm (edgeId e))
                         (applyNodeIdUnsafe tgm (sourceId e))
                         (applyNodeIdUnsafe tgm (targetId e))
                         (GM.applyEdgeIdUnsafe typedA (edgeId e))
                         (applyEdgeIdUnsafe tgm (edgeId e))) addNodes edges'
   in addEdges