Verified Commit 6fbed012 authored by Vladimír Štill's avatar Vladimír Štill
Browse files

Implement CFG support in fja_checker

parent 246aaca6
Loading
Loading
Loading
Loading
+117 −45
Original line number Diff line number Diff line
from typing import Tuple
import reg
import cfl
import sys
import signal

@@ -52,7 +53,7 @@ def nfa_transform(string: str, automaton_type: str) -> reg.NFA:
        parser = reg.Parser()
        return parser.str_to_nfa(string)

    except reg.Parser.ParsingError as message:
    except reg.ParsingError as message:
        print("Parsing error:", message)
        exit(1)

@@ -91,31 +92,14 @@ def check_task(dfa: reg.DFA, task: str) -> bool:
    return True


def main():
    signal.alarm(60)

    # Get string with student's solution.
    with open(sys.argv[1]) as student_file:
        student_string = student_file.read()

    # Get string with teacher's solution and type of the task.
    for argument in sys.argv:
        if argument[:2] == "-o":
            teacher_string = argument[2:]

    try:
        task_prefix, teacher_string = teacher_string.split(":", 1)
        teacher_type, task = get_task(task_prefix)

        student_solution = dfa_transform(student_string, task)
        teacher_solution = dfa_transform(teacher_string, teacher_type)

        #
def check_empty(student_solution, teacher_solution):
    if teacher_solution.is_empty() and student_solution.is_empty():
        print("Správné řešení.")
        exit(0)

        elif student_solution.characters != teacher_solution.characters:

def check_alphabets(student_alpha, teacher_alpha, task: str) -> None:
    if student_alpha != teacher_alpha:
        # TODO ask also print both alphabets?
        # reg.Parser.names_to_str(student_solution.characters)

@@ -131,25 +115,113 @@ def main():
        print("Nesprávné řešení.")
        exit(1)

        result = reg.DFA.is_equivalent(student_solution, teacher_solution)
        if check_task(student_solution, task) and result:

def exit_correct():
    print("Správné řešení.")
    exit(0)


def exit_incorrect():
    print("Nesprávné řešení.")
    exit(1)


def print_extra_word_ce(student_word):
    print("Příklad slova, které je ve studentově řešení a není v zadaném jazyce: ", student_word)


def print_missing_word_ce(teacher_word):
    print("Příklad slova, které chybí ve studentově řešení a je v zadaném jazyce: ", teacher_word)


def dfa_task(teacher_type, teacher_string, task, student_string):
    student_solution = dfa_transform(student_string, task)
    teacher_solution = dfa_transform(teacher_string, teacher_type)

    check_empty(student_solution=student_solution,
                teacher_solution=teacher_solution)

    check_alphabets(student_alpha=student_solution.characters,
                    teacher_alpha=teacher_solution.characters, task=task)

    result = reg.DFA.is_equivalent(student_solution, teacher_solution)
    if check_task(student_solution, task) and result:
        exit_correct()

    if not result:
        student_word, teacher_word = result.left_counterexample, result.right_counterexample

        if student_word is None:
            print("Studentovo řešení je podmnožinou zadaného jazyka.")
        else:
                print("Příklad slova, které je ve studentově řešení a není v zadaném jazyce: ", student_word)
            print_extra_word_ce(student_word)

        if teacher_word is None:
            print("Studentovo řešení je nadmnožinou zadaného jazyka.")
        else:
                print("Příklad slova, které chybí ve studentově řešení a je v zadaném jazyce: ", teacher_word)
            print_missing_word_ce(teacher_word)

        print("Nesprávné řešení.")
    exit_incorrect()


def cfg_task(teacher_type: str, teacher_string: str, task: str,
             student_string: str) -> None:
    parser = reg.Parser()
    try:
        teacher_solution = parser.str_to_cfg(teacher_string)
    except reg.ParsingError as message:
        print(f"Error parsing teacher's solution: {message}")
        exit(1)

    try:
        student_solution = parser.str_to_cfg(student_string)
    except reg.ParsingError as message:
        print(f"Error parsing student's solution: {message}")
        exit(1)

    check_empty(student_solution=student_solution,
                teacher_solution=teacher_solution)

    check_alphabets(student_alpha=student_solution.terminals,
                    teacher_alpha=teacher_solution.terminals, task="GRA")

    equals = cfl.CFG.is_equivalent_test(student_solution, teacher_solution)

    if equals:
        exit_correct()

    if equals.left_counterexample is not None:
        print_extra_word_ce(equals.left_counterexample)
    if equals.right_counterexample:
        print_missing_word_ce(equals.right_counterexample)

    exit_incorrect()


def main():
    signal.alarm(60)

    # Get string with student's solution.
    with open(sys.argv[1]) as student_file:
        student_string = student_file.read()

    # Get string with teacher's solution and type of the task.
    for argument in sys.argv:
        if argument[:2] == "-o":
            teacher_string = argument[2:]

    try:
        task_prefix, teacher_string = teacher_string.split(":", 1)
        teacher_type, task = get_task(task_prefix)

        if teacher_type == "DFA":
            dfa_task(teacher_type=teacher_type, teacher_string=teacher_string,
                     task=task, student_string=student_string)
        elif teacher_type == "CFG":
            cfg_task(teacher_type=teacher_type, teacher_string=teacher_string,
                     task=task, student_string=student_string)
        else:
            print(f"Invalid question type {task_prefix}")
            exit(1)

    except Exception as ex: