Example #1
0
def comparison(json_file: dict) -> dict:
    """

    Logic layer function for calling correct JSON/XML conversion, running the comparison through our Python ALT
    interface and converting result back to JSON for REST API.

    :param json_file: `dictionary` containing the input

    :return: `dictionary` containing the output of comparison (true or false) OR `dictionary` with exception message \
    and exception type

    """
    try:
        lhs, lhs_type, rhs, rhs_type = Converter.json_to_xml(
            json_file, AlgorithmTypes.COMPARISON)

        with AltInterface() as interface:
            algorithm_result = interface.comparison(lhs, lhs_type, rhs,
                                                    rhs_type)

        result = Converter.xml_to_json(algorithm_result,
                                       AlgorithmTypes.COMPARISON)
        return result
    except (AltInterfaceException, Converter.JSONDecodeError,
            Converter.XMLDecodeError) as e:
        return {'exception': e.msg, 'type': e.exc_type}
Example #2
0
def transformation(json_file: dict) -> dict:
    """

    Logic layer function for calling correct JSON/XML conversion, running the transformation through our Python ALT
    interface and converting result back to JSON for REST API.

    :param json_file: `dictionary` containing the input (finite automaton, regular grammar or regexp)

    :return: `dictionary` containing the output of transformation (finite automaton, regular grammar or regexp) OR \
    `dictionary` with exception message and exception type

    """
    try:
        source, source_type, target_type = Converter.json_to_xml(
            json_file, AlgorithmTypes.TRANSFORMATION)

        with AltInterface() as interface:
            algorithm_result = interface.conversion(source, source_type,
                                                    target_type)

        result = Converter.xml_to_json(algorithm_result,
                                       AlgorithmTypes.TRANSFORMATION)
        return result
    except (AltInterfaceException, Converter.JSONDecodeError,
            Converter.XMLDecodeError) as e:
        return {'exception': e.msg, 'type': e.exc_type}
Example #3
0
def test_algorithm_result(interface: AltInterface, input_file: str,
                          algorithm: str, expected_file: str,
                          optional_param: str):
    """

    Testing given algorithm on given input and comparing the result with expected output.

    .. note::

        Bare on mind that this function is heavily testing comparison. If this test fails, don't forget to check also
        comparison function and wrapper!

    :param interface: `pytest fixture` returning :class:`~backend.python_interface.AltInterface` instance
    :param input_file: path to XML file containing input
    :param algorithm: algorithm to be run
    :param expected_file: path to XML file containing expected output
    :param optional_param: extra parameter for algorithms that need it (currently only regexp derivation and CYK)

    """
    xml_input = read_input(input_file)
    expected_output = read_input(expected_file)

    res = interface.algorithms(xml_input, algorithm, optional_param)

    if 'automaton' in algorithm:
        input_type = 'fa'
    elif 'grammar' in algorithm:
        input_type = 'cfg'
    elif 'regexp' in algorithm:
        input_type = 're'
    else:
        pytest.fail('Invalid algorithm passed as argument!!')
        return

    # When comparing step tables of minimization, just compare two strings
    if (algorithm == AlgorithmTypes.AUTOMATON_MINIMIZATION
            or algorithm == AlgorithmTypes.GRAMMAR_CYK
            or algorithm == AlgorithmTypes.GRAMMAR_CYK_NO_VERBOSE):
        assert res == expected_output
    else:
        # Also testing comparison. If this test fails, don't forget to check also that!
        res = interface.comparison(res, input_type, expected_output,
                                   input_type)
        assert res is True
Example #4
0
def interface() -> AltInterface:
    """

    Pytest fixture for exporting the :class:`~backend.python_interface.AltInterface` instance. Context manager is
    responsible for both setup and teardown (thanks to ``yield`` keyword).

    :return: new :class:`~backend.python_interface.AltInterface` instance
    """
    with AltInterface() as it:
        yield it
Example #5
0
def test_comparison(interface: AltInterface, input_file: str, source: str):
    """

    Basic comparison test. Takes input and compares it with itself.

    :param interface: `pytest fixture` returning :class:`~backend.python_interface.AltInterface` instance
    :param input_file: path to XML file containing input
    :param source: type of input

    """
    xml_input = read_input(input_file)

    res = interface.comparison(xml_input, source, xml_input, source)
    assert res is True
Example #6
0
def test_conversion(interface: AltInterface, input_file: str, source: str,
                    target: str):
    """

    Simple conversion test. Converts input to `target`, checks the output type, converts it back to `source` and compare
    it with original input.

    .. note::

        Bare on mind that this function is also slightly testing comparison. If this test fails, don't forget to check
        also comparison function and wrapper!

    :param interface: `pytest fixture` returning :class:`~backend.python_interface.AltInterface` instance
    :param input_file: path to XML file containing input
    :param source: type of input
    :param target: type of conversion output

    """
    if target == 'fa':
        result_type = '</NFA>'
    elif target == 'rg':
        result_type = '</RightRG>'
    elif target == 're':
        result_type = '</UnboundedRegExp>'
    else:
        pytest.fail('Invalid target passed as argument!!')
        return

    xml_input = read_input(input_file)
    res = interface.conversion(xml_input, source, target)
    assert res.endswith(result_type + '\n')

    res = interface.conversion(res, target, source)

    res = interface.comparison(xml_input, source, res, source)
    assert res is True
Example #7
0
def test_algorithm_run(interface: AltInterface, input_file: str,
                       algorithm: str, result_type: str, optional_param: str):
    """

    Simple algorithms test. Just run the given algorithm with given input and checks the output type.
    Testing whether the algorithm even runs and finishes without any problems.

    :param interface: `pytest fixture` returning :class:`~backend.python_interface.AltInterface` instance
    :param input_file: path to XML file containing input
    :param algorithm: algorithm to be run
    :param result_type: expected type of the output
    :param optional_param: extra parameter for algorithms that need it (currently only regexp derivation and CYK)

    """
    xml_input = read_input(input_file)
    res = interface.algorithms(xml_input, algorithm, optional_param)
    assert res.endswith(result_type + '\n')
Example #8
0
def _automaton_minimization(json_file: dict) -> dict:
    try:
        source = Converter.json_to_xml(json_file,
                                       AlgorithmTypes.AUTOMATON_MINIMIZATION)

        with AltInterface() as interface:
            algorithm_steps = interface.algorithms(
                source, AlgorithmTypes.AUTOMATON_MINIMIZATION)
            algorithm_result = interface.algorithms(
                source, AlgorithmTypes.AUTOMATON_MINIMIZATION_NO_VERBOSE)

        result = Converter.xml_to_json(algorithm_result,
                                       AlgorithmTypes.AUTOMATON_MINIMIZATION,
                                       steps=algorithm_steps)
        return result
    except (AltInterfaceException, Converter.JSONDecodeError,
            Converter.XMLDecodeError) as e:
        return {'exception': e.msg, 'type': e.exc_type}
Example #9
0
def _grammar_cyk(json_file: dict) -> dict:
    try:
        cyk_string, source = Converter.json_to_xml(json_file,
                                                   AlgorithmTypes.GRAMMAR_CYK)

        with AltInterface() as interface:
            algorithm_steps = interface.algorithms(source,
                                                   AlgorithmTypes.GRAMMAR_CYK,
                                                   cyk_string)
            algorithm_result = interface.algorithms(
                source, AlgorithmTypes.GRAMMAR_CYK_NO_VERBOSE, cyk_string)

        result = Converter.xml_to_json(algorithm_result,
                                       AlgorithmTypes.GRAMMAR_CYK,
                                       steps=algorithm_steps)
        return result
    except (AltInterfaceException, Converter.JSONDecodeError,
            Converter.XMLDecodeError) as e:
        return {'exception': e.msg, 'type': e.exc_type}
Example #10
0
def test_epsilon_trim_det_min(interface: AltInterface, automaton: str):
    """

    Testing sequence of automata algorithms: epsilon transition removal, automaton trim, determinization and
    minimization. In each step checking for valid output type.

    :param interface: `pytest fixture` returning :class:`~backend.python_interface.AltInterface` instance
    :param automaton: path to XML file containing input automaton

    """
    res = read_input(automaton)

    for algorithm, result_type in [
        (AlgorithmTypes.AUTOMATON_EPSILON_REMOVAL, '</NFA>'),
        (AlgorithmTypes.AUTOMATON_TRIM, '</NFA>'),
        (AlgorithmTypes.AUTOMATON_DETERMINIZATION, '</DFA>'),
        (AlgorithmTypes.AUTOMATON_MINIMIZATION_NO_VERBOSE, '</DFA>')
    ]:
        res = interface.algorithms(res, algorithm)
        assert res.endswith(result_type + '\n')
Example #11
0
def _grammar_left_recursion(json_file: dict) -> dict:
    """

    Logic layer function for calling correct JSON/XML conversion, running the left recursion removal through our Python\
    ALT interface and converting the result back to JSON for REST API.

    :param json_file: `dictionary` containing the input (context-free grammar)

    :return: `dictionary` containing the output of left recursion removal (context-free grammar without left recursion)\
    OR `dictionary` with exception message and exception type

    """
    try:
        source = Converter.json_to_xml(
            json_file, AlgorithmTypes.GRAMMAR_LEFT_RECURSION_REMOVAL)

        # Calling left recursion removal in four steps, saving steps in an array
        with AltInterface() as interface:
            after_reduction = interface.algorithms(
                source, AlgorithmTypes.GRAMMAR_REDUCTION)
            after_epsilon = interface.algorithms(
                after_reduction, AlgorithmTypes.GRAMMAR_EPSILON_REMOVAL)
            after_unit = interface.algorithms(
                after_epsilon, AlgorithmTypes.GRAMMAR_UNIT_RULES_REMOVAL)
            after_recursion = interface.algorithms(
                after_unit, AlgorithmTypes.GRAMMAR_LEFT_RECURSION_REMOVAL)

        algorithm_steps = {
            'after_reduction': after_reduction,
            'after_epsilon': after_epsilon,
            'after_unit': after_unit
        }

        result = Converter.xml_to_json(
            after_recursion,
            AlgorithmTypes.GRAMMAR_LEFT_RECURSION_REMOVAL,
            steps=algorithm_steps)
        return result
    except (AltInterfaceException, Converter.JSONDecodeError,
            Converter.XMLDecodeError) as e:
        return {'exception': e.msg, 'type': e.exc_type}
Example #12
0
def _grammar_cnf(json_file: dict) -> dict:
    """

    Logic layer function for calling correct JSON/XML conversion, running the CNF conversion through our Python ALT
    interface and converting the result back to JSON for REST API.

    :param json_file: `dictionary` containing the input (context-free grammar)

    :return: `dictionary` containing the output of CNF conversion (context-free grammar in CNF) OR `dictionary` with \
    exception message and exception type

    """
    try:
        source = Converter.json_to_xml(json_file,
                                       AlgorithmTypes.GRAMMAR_CNF_CONVERSION)

        # Calling CNF transformation in four steps (following BI-AAG practice), saving steps in an array
        with AltInterface() as interface:
            after_reduction = interface.algorithms(
                source, AlgorithmTypes.GRAMMAR_REDUCTION)
            after_epsilon = interface.algorithms(
                after_reduction, AlgorithmTypes.GRAMMAR_EPSILON_REMOVAL)
            after_unit = interface.algorithms(
                after_epsilon, AlgorithmTypes.GRAMMAR_UNIT_RULES_REMOVAL)
            after_cnf = interface.algorithms(
                after_unit, AlgorithmTypes.GRAMMAR_CNF_CONVERSION)

        algorithm_steps = {
            'after_reduction': after_reduction,
            'after_epsilon': after_epsilon,
            'after_unit': after_unit,
        }

        result = Converter.xml_to_json(after_cnf,
                                       AlgorithmTypes.GRAMMAR_CNF_CONVERSION,
                                       steps=algorithm_steps)
        return result
    except (AltInterfaceException, Converter.JSONDecodeError,
            Converter.XMLDecodeError) as e:
        return {'exception': e.msg, 'type': e.exc_type}
Example #13
0
def _regexp_derivation(json_file: dict) -> dict:
    """

    Logic layer function for calling correct JSON/XML conversion, running the derivation through our Python ALT
    interface and converting the result back to JSON for REST API.

    :param json_file: `dictionary` containing the input (regexp and derivation string)

    :return: `dictionary` containing the output of derivation (result, steps and trimmed_Steps) OR `dictionary` with \
    exception message and exception type

    """
    try:
        derivation_string, source = Converter.json_to_xml(
            json_file, AlgorithmTypes.REGEXP_DERIVATION)
        algorithm_steps = []
        trimmed_algorithm_steps = []

        # Derivation of regexp is called separately for each character of derivation string
        with AltInterface() as interface:
            for c in derivation_string:
                source = interface.algorithms(source,
                                              AlgorithmTypes.REGEXP_DERIVATION,
                                              c)
                algorithm_steps.append(source)
                source = interface.algorithms(source,
                                              AlgorithmTypes.REGEXP_TRIM)
                trimmed_algorithm_steps.append(source)

        result = Converter.xml_to_json(None,
                                       AlgorithmTypes.REGEXP_DERIVATION,
                                       steps=algorithm_steps,
                                       trimmed_steps=trimmed_algorithm_steps)
        return result
    except (AltInterfaceException, Converter.JSONDecodeError,
            Converter.XMLDecodeError) as e:
        return {'exception': e.msg, 'type': e.exc_type}
Example #14
0
def simple_algorithm(json_file: dict, algorithm_name: str) -> dict:
    """

    Logic layer function for calling correct JSON/XML conversion, running the algorithm through our Python ALT interface
    and converting the result back to JSON for REST API.

    :param json_file: `dictionary` containing the input (automaton, grammar or regexp)
    :param algorithm_name: `string` representing name of the algorithm to be used (see \
    :class:`~backend.AlgorithmTypes`) for available algorithm names

    :return: `dictionary` containing the output of given algorithm (automaton, grammar or regexp) OR `dictionary` with \
    exception message and exception type

    """
    try:
        if algorithm_name == AlgorithmTypes.AUTOMATON_MINIMIZATION:
            return _automaton_minimization(json_file)
        elif algorithm_name == AlgorithmTypes.REGEXP_DERIVATION:
            return _regexp_derivation(json_file)
        elif algorithm_name == AlgorithmTypes.GRAMMAR_LEFT_RECURSION_REMOVAL:
            return _grammar_left_recursion(json_file)
        elif algorithm_name == AlgorithmTypes.GRAMMAR_CNF_CONVERSION:
            return _grammar_cnf(json_file)
        elif algorithm_name == AlgorithmTypes.GRAMMAR_CYK:
            return _grammar_cyk(json_file)
        else:
            source = Converter.json_to_xml(json_file, algorithm_name)

            with AltInterface() as interface:
                algorithm_result = interface.algorithms(source, algorithm_name)

            result = Converter.xml_to_json(algorithm_result, algorithm_name)
            return result
    except (AltInterfaceException, Converter.JSONDecodeError,
            Converter.XMLDecodeError) as e:
        return {'exception': e.msg, 'type': e.exc_type}