# Path: penman/exceptions.py
# class GraphError(PenmanError):
#     """Raised on invalid graph structures or operations."""
# 
# Path: penman/types.py

# 
# Path: penman/epigraph.py
# class Epidatum(object):


from typing import (Union, Optional, Mapping, List, Dict, Set, NamedTuple)
from collections import defaultdict
from penman.exceptions import GraphError
from penman.types import (
    Variable,
    Constant,
    Role,
    Target,
    BasicTriple,
    Triples,
)
from penman.epigraph import Epidata
import copy
              role: Role = None,
              target: Variable = None) -> List[Edge]:
        """
        Return edges filtered by their *source*, *role*, or *target*.

        Edges don't include terminal triples (concepts or attributes).
        """
        variables = self.variables()
        return [Edge(*t)
                for t in self._filter_triples(source, role, target)
                if t[1] != CONCEPT_ROLE and t[2] in variables]

    def attributes(self,
                   source: Optional[Variable] = None,
                   role: Role = None,
                   target: Constant = None) -> List[Attribute]:
        """
        Return attributes filtered by their *source*, *role*, or *target*.

        Attributes don't include concept triples or those where the
        target is a nonterminal.
        """
        variables = self.variables()
        return [Attribute(*t)
                for t in self._filter_triples(source, role, target)
                if t[1] != CONCEPT_ROLE and t[2] not in variables]

    def _filter_triples(self,
                        source: Optional[Variable],
                        role: Optional[Role],

# Path: penman/exceptions.py
# class GraphError(PenmanError):
#     """Raised on invalid graph structures or operations."""
# 
# Path: penman/types.py

# 
# Path: penman/epigraph.py
# class Epidatum(object):


# Path: penman/graph.py
from typing import (Union, Optional, Mapping, List, Dict, Set, NamedTuple)
from collections import defaultdict
from penman.exceptions import GraphError
from penman.types import (
    Variable,
    Constant,
    Role,
    Target,
    BasicTriple,
    Triples,
)
from penman.epigraph import Epidata
import copy

              role: Role = None,
              target: Variable = None) -> List[Edge]:
        """
        Return edges filtered by their *source*, *role*, or *target*.

        Edges don't include terminal triples (concepts or attributes).
        """
        variables = self.variables()
        return [Edge(*t)
                for t in self._filter_triples(source, role, target)
                if t[1] != CONCEPT_ROLE and t[2] in variables]

    def attributes(self,
                   source: Optional[Variable] = None,
                   role: Role = None,
                   target: Constant = None) -> List[Attribute]:
        """
        Return attributes filtered by their *source*, *role*, or *target*.

        Attributes don't include concept triples or those where the
        target is a nonterminal.
        """
        variables = self.variables()
        return [Attribute(*t)
                for t in self._filter_triples(source, role, target)
                if t[1] != CONCEPT_ROLE and t[2] not in variables]

    def _filter_triples(self,
                        source: Optional[Variable],
                        role: Optional[Role],

                        target: Optional[Target]) -> List[BasicTriple]: