<commit_before>"""Automata.py

Manipulation of and conversions between regular expressions,
deterministic finite automata, and nondeterministic finite automata.

<NAME>, UC Irvine, November 2003.
"""

import sys
import operator

from .partition_refinement import PartitionRefinement
from .sequence import Sequence
from .util import arbitrary_item


# Hack for Python 3 compatibility
try:
    unicode
except:
    unicode = str


class LanguageError(Exception):
    pass


class RegExpError(Exception):
    pass


def Language(A):
    """Convert automaton A into an object describing its language.
    This is distinct from class RegularLanguage in case we
    want to later add other types of automaton and nonregular languages.
    """
    return A.language()


class RegularLanguage:

    """Object representing the language recognized by a DFA or NFA.
    Available operations are testing whether a string is in the language,
    logical combinations, and subset and equality testing.
    """

    def __init__(self, arg):
        if isinstance(arg, FiniteAutomaton):
            self.recognizer = arg
        elif isinstance(arg, (str, unicode)):
            self.recognizer = RegExp(arg)
        else:
            raise LanguageError("Unrecognized constructor for RegularLanguage")

    def __contains__(self, inputsequence):
        return self.recognizer(inputsequence)

    def __eq__(self, other):
        if not isinstance(other, RegularLanguage):
            return None
        return self.recognizer.minimize() == other.recognizer.minimize()

    def __ne__(self, other):
        return not (self == other)

    def __le__(self, other):
        return not(self & ~ other)

    def __ge__(self, other):
        return not(other & ~ self)

    def __lt__(self, other):
        return self <= other and self != other

    def __gt__(self, other):
        return self >= other and self != other

    def __invert__(self):
        """Complement (with respect to alphabet) of language."""
        return Language(self.recognizer.complement())

    def __and__(self, other):
        """Intersection of two languages with the same alphabet."""
        if not isinstance(other, RegularLanguage):
            raise LanguageError("Unable to intersect nonregular language")
        return Language(self.recognizer.intersection(other.recognizer))

    def __or__(self, other):
        """Union of two languages with the same alphabet."""
        if not isinstance(other, RegularLanguage):
            raise LanguageError("Unable to intersect nonregular language")
        return Language(self.recognizer.union(other.recognizer))

    def __xor__(self, other):
        """Symmetric difference of two languages with the same alphabet."""
        if not isinstance(other, RegularLanguage):
            raise LanguageError("Unable to intersect nonregular language")
        return Language(self.recognizer.symmetricDifference(other.recognizer))

    def __nonzero__(self):
        """Is this the empty language?"""
        for x in self.recognizer.states():
            if x.isfinal():
                return True
        return False


class FiniteAutomaton:

    """Base class for DFA and NFA.  This class should not be instantiated
    on its own, but dispatches methods that are appropriate to both types
    of automaton by calling .asDFA() or .asNFA() to convert the automaton
    to the appropriate type.  All automaton instances should include the<commit_msg>Lowercase function name in automata.<commit_after>"""Manipulation of and conversions between regular expressions,
deterministic finite automata, and nondeterministic finite automata.

"""

import sys
import operator

from .partition_refinement import PartitionRefinement
from .sequence import Sequence
from .util import arbitrary_item


# Hack for Python 3 compatibility
try:
    unicode
except:
    unicode = str


class LanguageError(Exception):
    pass


class RegExpError(Exception):
    pass


def language(A):
    """Convert automaton A into an object describing its language.
    This is distinct from class RegularLanguage in case we
    want to later add other types of automaton and nonregular languages.
    """
    return A.language()


class RegularLanguage:

    """Object representing the language recognized by a DFA or NFA.
    Available operations are testing whether a string is in the language,
    logical combinations, and subset and equality testing.
    """

    def __init__(self, arg):
        if isinstance(arg, FiniteAutomaton):
            self.recognizer = arg
        elif isinstance(arg, (str, unicode)):
            self.recognizer = RegExp(arg)
        else:
            raise LanguageError("Unrecognized constructor for RegularLanguage")

    def __contains__(self, inputsequence):
        return self.recognizer(inputsequence)

    def __eq__(self, other):
        if not isinstance(other, RegularLanguage):
            return None
        return self.recognizer.minimize() == other.recognizer.minimize()

    def __ne__(self, other):
        return not (self == other)

    def __le__(self, other):
        return not(self & ~ other)

    def __ge__(self, other):
        return not(other & ~ self)

    def __lt__(self, other):
        return self <= other and self != other

    def __gt__(self, other):
        return self >= other and self != other

    def __invert__(self):
        """Complement (with respect to alphabet) of language."""
        return language(self.recognizer.complement())

    def __and__(self, other):
        """Intersection of two languages with the same alphabet."""
        if not isinstance(other, RegularLanguage):
            raise LanguageError("Unable to intersect nonregular language")
        return language(self.recognizer.intersection(other.recognizer))

    def __or__(self, other):
        """Union of two languages with the same alphabet."""
        if not isinstance(other, RegularLanguage):
            raise LanguageError("Unable to intersect nonregular language")
        return language(self.recognizer.union(other.recognizer))

    def __xor__(self, other):
        """Symmetric difference of two languages with the same alphabet."""
        if not isinstance(other, RegularLanguage):
            raise LanguageError("Unable to intersect nonregular language")
        return language(self.recognizer.symmetricDifference(other.recognizer))

    def __nonzero__(self):
        """Is this the empty language?"""
        for x in self.recognizer.states():
            if x.isfinal():
                return True
        return False


class FiniteAutomaton:

    """Base class for DFA and NFA.  This class should not be instantiated
    on its own, but dispatches methods that are appropriate to both types
    of automaton by calling .asDFA() or .asNFA() to convert the automaton
    to the appropriate type.  All automaton instances should include the
{'fraction_non_alphanumeric': 0.07898550724637682, 'fraction_numerical': 0.0008695652173913044, 'mean_word_length': 3.042765084944347, 'pattern_counts': {'":': 0, '<': 6, '<?xml version=': 0, '>': 6, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2080074', 'n_tokens_mistral': 1770, 'n_tokens_neox': 1673, 'n_words': 665}