예제 #1
0
def test_simple_algorithm_result(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 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)

    json_input = XMLConverter.xml_to_json(xml_input)
    json_output = XMLConverter.xml_to_json(expected_output)

    result = logic_layer.simple_algorithm(json_input, algorithm)

    to_compare = {'lhs': result, 'rhs': json_output}
    res = logic_layer.comparison(to_compare)
    assert res['result'] is True
예제 #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}
예제 #3
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}
예제 #4
0
def test_fails():
    """

    Testing invalid requests for :mod:`~backend.logic_layer` that should always fail.

    """

    # Passing invalid name of algorithm
    json_input = XMLConverter.xml_to_json(read_input(REGEXPS + '/regexp.xml'))
    res = logic_layer.simple_algorithm(json_input, 'regexp_trimmm')
    assert res['exception'] == 'Unknown algorithm passed as parameter!'
    assert res['type'] is AltInterfaceException

    # Omitting the optional parameter which is mandatory for some algorithms
    res = logic_layer.simple_algorithm(json_input,
                                       AlgorithmTypes.REGEXP_DERIVATION)
    assert res['exception'] == 'Invalid JSON structure'
    assert res['type'] is XMLConverter.JSONDecodeError

    # Passing invalid input type
    res = logic_layer.simple_algorithm(
        json_input, AlgorithmTypes.AUTOMATON_DETERMINIZATION)
    assert 'Entry overload' in res['exception']
    assert 'not available' in res['exception']
    assert res['type'] is AltInterfaceException

    # Missing 'target' in transformation input
    res = logic_layer.transformation(json_input)
    assert res['exception'] == 'Invalid JSON structure'
    assert res['type'] is XMLConverter.JSONDecodeError

    # Passing invalid target type to transformation
    json_input_transformation = {'source': json_input, 'target': 'NFA'}
    res = logic_layer.transformation(json_input_transformation)
    assert res['exception'] == 'Unknown \'to\' parameter passed as parameter!'
    assert res['type'] is AltInterfaceException

    # Trying to convert ENFA to RG
    json_input = XMLConverter.xml_to_json(
        read_input(AUTOMATA + '/ENFA1.EPSILON.xml'))
    json_input_transformation = {'source': json_input, 'target': 'rg'}
    res = logic_layer.transformation(json_input_transformation)
    assert 'Entry overload' in res['exception']
    assert 'not available' in res['exception']
    assert res['type'] is AltInterfaceException

    # Trying to compare FA and CFG
    json_input2 = XMLConverter.xml_to_json(
        read_input(GRAMMARS + '/CFG1.UNIT.xml'))
    json_input_comparison = {'lhs': json_input, 'rhs': json_input2}
    res = logic_layer.comparison(json_input_comparison)
    assert 'Entry overload' in res['exception']
    assert 'not available' in res['exception']
    assert res['type'] is AltInterfaceException
예제 #5
0
def test_recursion_cnf_result(input_file: str, algorithm: str,
                              expected_file: str):
    xml_input = read_input(input_file)
    expected_output = read_input(expected_file)

    json_input = XMLConverter.xml_to_json(xml_input)
    expected_json = XMLConverter.xml_to_json(expected_output)

    result = logic_layer.simple_algorithm(json_input, algorithm)

    to_compare = {'lhs': result['result'], 'rhs': expected_json}
    assert result['result'] == expected_json
    res = logic_layer.comparison(to_compare)
    assert res['result'] is True
예제 #6
0
def test_recursion_cnf_run(input_file: str, algorithm: str, result_type: str):
    json_input = XMLConverter.xml_to_json(read_input(input_file))
    res = logic_layer.simple_algorithm(json_input, algorithm)
    assert 'after_reduction' in res.keys()
    assert 'after_epsilon' in res.keys()
    assert 'after_unit_rules' in res.keys()
    assert result_type == res['result']['type']
예제 #7
0
def test_derivation_result(input_file: str, expected_file: str,
                           optional_param: str):
    xml_input = read_input(input_file)
    expected_output = read_input(expected_file)

    json_input = XMLConverter.xml_to_json(xml_input)
    json_output = XMLConverter.xml_to_json(expected_output)

    json_input = {'regexp': json_input, 'derivation_string': optional_param}
    result = logic_layer.simple_algorithm(json_input,
                                          AlgorithmTypes.REGEXP_DERIVATION)
    result = result['steps'][-1]

    to_compare = {'lhs': result, 'rhs': json_output}
    res = logic_layer.comparison(to_compare)
    assert res['result'] is True
예제 #8
0
def test_cyk_run(input_file: str, result_type: str, optional_param: str):
    json_input = XMLConverter.xml_to_json(read_input(input_file))
    json_input = {'grammar': json_input, 'cyk_string': optional_param}

    res = logic_layer.simple_algorithm(json_input, AlgorithmTypes.GRAMMAR_CYK)
    assert 'step_table' in res.keys()
    assert 'result' in res.keys()
    assert res['result'] is True or res['result'] is False
예제 #9
0
def test_cyk_result(input_file: str, expected_file: str,
                    expected_file_table: str, optional_param: str):
    xml_input = read_input(input_file)
    expected_output = read_input(expected_file)
    expected_output_table = read_input(expected_file_table)

    json_input = XMLConverter.xml_to_json(xml_input)
    expected_json = XMLConverter.xml_to_json(expected_output,
                                             AlgorithmTypes.GRAMMAR_CYK,
                                             steps=expected_output_table)

    json_input = {'grammar': json_input, 'cyk_string': optional_param}
    result = logic_layer.simple_algorithm(json_input,
                                          AlgorithmTypes.GRAMMAR_CYK)

    assert result['result'] == expected_json['result']
    assert result['step_table'] == expected_json['step_table']
예제 #10
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}
예제 #11
0
def test_derivation_run(input_file: str, result_type: str,
                        optional_param: str):
    json_input = XMLConverter.xml_to_json(read_input(input_file))
    json_input = {'regexp': json_input, 'derivation_string': optional_param}

    res = logic_layer.simple_algorithm(json_input,
                                       AlgorithmTypes.REGEXP_DERIVATION)
    assert 'steps' in res.keys()
    assert 'trimmed_steps' in res.keys()
    assert result_type == res['steps'][-1]['type']
예제 #12
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}
예제 #13
0
def test_minimization_result(input_file: str, expected_file: str,
                             expected_file_table: str):
    xml_input = read_input(input_file)
    expected_output = read_input(expected_file)
    expected_output_table = read_input(expected_file_table)

    json_input = XMLConverter.xml_to_json(xml_input)
    expected_json = XMLConverter.xml_to_json(
        expected_output,
        AlgorithmTypes.AUTOMATON_MINIMIZATION,
        steps=expected_output_table)

    result = logic_layer.simple_algorithm(
        json_input, AlgorithmTypes.AUTOMATON_MINIMIZATION)

    to_compare = {'lhs': result['result'], 'rhs': expected_json['result']}
    res = logic_layer.comparison(to_compare)
    assert res['result'] is True
    assert result['steps'] == expected_json['steps']
예제 #14
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}
예제 #15
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}
예제 #16
0
def test_comparison(input_file: str):
    """

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

    :param input_file: path to XML file containing input

    """
    xml_input = XMLConverter.xml_to_json(read_input(input_file))
    json_file = {'lhs': xml_input, 'rhs': xml_input}

    res = logic_layer.comparison(json_file)
    assert res['result'] is True
예제 #17
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}
예제 #18
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}
예제 #19
0
def test_epsilon_trim_det_min(automaton: str):
    """

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

    :param automaton: path to XML file containing input automaton

    """
    res = XMLConverter.xml_to_json(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 = logic_layer.simple_algorithm(res, algorithm)
        assert result_type == res['type']
예제 #20
0
def test_simple_algorithm_run(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.

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

    """
    json_input = XMLConverter.xml_to_json(read_input(input_file))
    res = logic_layer.simple_algorithm(json_input, algorithm)

    if algorithm == AlgorithmTypes.AUTOMATON_MINIMIZATION:
        assert 'steps' in res.keys()
        assert result_type == res['result']['type']
    else:
        assert result_type == res['type']
예제 #21
0
def test_transformation(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 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 = XMLConverter.xml_to_json(read_input(input_file))
    json_file = {'target': target, 'source': xml_input}

    # Converting to target
    res = logic_layer.transformation(json_file)
    assert result_type == res['type']

    json_file = {'target': source, 'source': res}
    # Converting back to source
    res = logic_layer.transformation(json_file)

    json_file = {'lhs': res, 'rhs': xml_input}
    res = logic_layer.comparison(json_file)
    assert res['result'] is True