Неверная выходная аннотация в средстве проверки доказательств выражений логики

Я разрабатываю скрипт проверки доказательств алгебры логики на Python, он анализирует выражения и выводит ответ, являются ли они аксиомами, гипотезами, выведенными Modus Ponens или неизвестными. Однако я столкнулся с проблемой, когда некоторые строки неправильно помечаются как «[Неизвестно]», несмотря на то, что они, по-видимому, соответствуют критериям аксиом или Modus Ponens.

Например, учитывая ввод:

|-A&B->A
|-A&B->B
А&Б|-А
А&Б|-Б
А&Б|-Б->А->Б&А
А&Б|-А->Б&А
А&Б|-Б&А
|-А&Б->Б&А

Ожидаемые аннотации для строк 5 и 6 относятся к аксиомам или Modus Ponens, но я получаю «[Неизвестно]». В частности, строка 5 должна быть признана аксиомой 3, но это не так. Вот фрагмент кода, отвечающий за анализ и аннотирование выражений:

# Определения функций для parse_expression, check_parentheses, Split_expression и т. д.

def is_axiom(expression):
    def matches(expr, pattern):
        # Проверка, является ли шаблон строкой (в этом случае он может соответствовать любому выражению)
        if isinstance(pattern, str):
            return True
        # Проверка структурного соответствия выражения и шаблона
        if isinstance(expr, tuple) and isinstance(pattern, tuple) and expr[0] == pattern[0] and len(expr) == len(pattern):
            # Дополнительная проверка для аксиом 4 и 5
            if pattern in [('->', ('&', 'A', 'B'), 'A'), ('->', ('&', 'A', 'B'), 'B')]:
                # Проверяем, соответствует ли последний элемент выражения последнему элементу шаблона
                return expr[-1] == pattern[-1] and all(matches(e, p) for e, p in zip(expr[1:], pattern[1:]))
            # Стандартная проверка всех элементов выражения и шаблона
            return all(matches(e, p) for e, p in zip(expr[1:], pattern[1:]))
        return False

    # Шаблоны аксиом представлены в виде кортежей
    axiom_patterns = [
        ('->', 'A', ('->', 'B', 'A')),  # A -> B -> A
        ('->', ('->', 'A', 'B'), ('->', ('->', 'A', ('->', 'B', 'C')), ('->', 'A', 'C'))),  # (A -> B) -> (A -> B -> C) -> (A -> C)
        ('->', 'A', ('->', 'B', ('&', 'A', 'B'))),  # A -> B -> A & B
        ('->', ('&', 'A', 'B'), 'A'),  # A & B -> A
        ('->', ('&', 'A', 'B'), 'B'),  # A & B -> B
        ('->', 'A', ('|', 'A', 'B')),  # A -> A | B
        ('->', 'B', ('|', 'A', 'B')),  # B -> A | B
        ('->', ('->', 'A', 'C'), ('->', ('->', 'B', 'C'), ('->', ('|', 'A', 'B'), 'C'))),  # (A -> C) -> (B -> C) -> (A | B -> C)
        ('->', ('->', 'A', 'B'), ('->', ('->', 'A', ('NOT', 'B')), ('NOT', 'A'))),  # (A -> B) -> (A -> !B) -> !A
        ('->', ('NOT', ('NOT', 'A')), 'A')  # !!A -> A
    ]

   # Проверка соответствия выражения одному из шаблонов аксиом
    for i, pattern in enumerate(axiom_patterns, 1):
        if matches(expression, pattern):
            return i  # Возвращаем номер аксиомы, если найдено соответствие
    return None  # Возвращаем None, если выражение не соответствует ни одному из шаблонов аксиом

     ...
def apply_modus_ponens(proof_lines, current_index):
    if current_index >= len(proof_lines):
        return None

    current_context, current_conclusion = proof_lines[current_index]

    for index_implication, (context_implication, conclusion_implication) in enumerate(proof_lines[:current_index]):
        # Проверяем, является ли заключение импликацией, и совпадает ли второй компонент импликации с текущим заключением
        if (isinstance(conclusion_implication, tuple) and conclusion_implication[0] == '->' and
                conclusion_implication[2] == current_conclusion):
            # Ищем утверждение A в предшествующих строках, включая строку с импликацией
            for index_a, (context_a, conclusion_a) in enumerate(proof_lines[:index_implication + 1]):
                if conclusion_a == conclusion_implication[1]:
                    # Проверяем, является ли контекст импликации подмножеством текущего контекста
                    if set(context_implication).issubset(set(current_context)):
                        return (index_a + 1, index_implication + 1)

    return None

     ...
def can_be_proved(proof_lines, index):
    conclusion = proof_lines[index][1]

    axiom_result = is_axiom(conclusion)
    if axiom_result is not None:
        return f"Ax. {axiom_result}"
    
    if is_hypothesis(conclusion, proof_lines[index][0]):
        return "Hypothesis"
    
    mp_result = apply_modus_ponens(proof_lines, index)
    if mp_result:
        return f"M.P. {mp_result[0]}, {mp_result[1]}"
    
    deduced_lines = apply_deduction_theorem(proof_lines[:index + 1])
    for deduced_pair in deduced_lines:
        if deduced_pair[1] == index + 1:
            return f"Ded. {deduced_pair[0]}"

    return "Unknown"
     ...

# Другие важные функции и основная логика программы

Я подозреваю, что проблема может быть в функциях is_axiom или can_be_proved, или, возможно, в том, как я анализирую и разделяю выражения. Может Modus Ponens?


Ответы (0 шт):