Загрузка данных


from itertools import product

NAMES = "xyz"

def table(f, n: int) -> list:
    return [(values, int(f(*values))) for values in product((0, 1), repeat=n)]

def print_table(rows: list) -> None:
    n = len(rows[0][0])
    print(*NAMES[:n], "f")
    for values, result in rows:
        print(*values, result)

def literal(name: str, value: int, positive_if: int) -> str:
    return name if value == positive_if else "¬" + name

def minterms(rows: list) -> list:
    n = len(rows[0][0])
    return [" ∧ ".join(literal(NAMES[i], values[i], 1) for i in range(n))
            for values, result in rows if result == 1]

def maxterms(rows: list) -> list:
    n = len(rows[0][0])
    return ["(" + " ∨ ".join(literal(NAMES[i], values[i], 0) for i in range(n)) + ")"
            for values, result in rows if result == 0]

def sdnf(rows: list) -> str:
    terms = minterms(rows)
    return " ∨ ".join(terms) if terms else "0"

def sknf(rows: list) -> str:
    clauses = maxterms(rows)
    return " ∧ ".join(clauses) if clauses else "1"

def sdnf_function(rows: list):
    ones = [values for values, result in rows if result == 1]
    return lambda *values: int(tuple(values) in ones)

def equivalent(f1, f2, n: int) -> bool:
    return all(int(f1(*v)) == int(f2(*v)) for v in product((0, 1), repeat=n))

def compare(f1, f2, n: int) -> bool:
    print(*NAMES[:n], "исходная упрощённая")
    for values in product((0, 1), repeat=n):
        print(*values, int(f1(*values)), int(f2(*values)))
    return equivalent(f1, f2, n)

def task1():
    rows = table(lambda x, y: x and y, 2)
    print_table(rows)
    print("СДНФ:", sdnf(rows)) # x ∧ y
    print("СКНФ:", sknf(rows)) # (x ∨ y) ∧ (x ∨ ¬y) ∧ (¬x ∨ y)

def task2():
    rows = table(lambda x, y: x or y, 2)
    print_table(rows)
    print("СКНФ:", sknf(rows)) # (x ∨ y)

def task3():
    rows = table(lambda x, y, z: x or (y and z), 3)
    print_table(rows)
    print("СДНФ:", sdnf(rows))

def task4():
    rows = table(lambda x, y, z: (x and y) or (x and z), 3)
    print_table(rows)
    print("СКНФ:", sknf(rows))

def task5():
    # x ∧ (x ∨ y) = x (поглощение)
    original = lambda x, y: x and (x or y)
    simplified = lambda x, y: x
    print("Эквивалентны:", compare(original, simplified, 2))

def task6():
    # (x ∧ y) ∨ (x ∧ y ∧ z) = x ∧ y ∧ (1 ∨ z) = x ∧ y
    original = lambda x, y, z: (x and y) or (x and y and z)
    simplified = lambda x, y, z: x and y
    print("Эквивалентны:", compare(original, simplified, 3))

def task7():
    bits = input("Значения функции от x, y, z (8 бит, например 11101000): ")
    if len(bits) != 8:
        raise ValueError("Нужно ровно 8 бит")
    rows = [(values, int(bits[i])) for i, values in enumerate(product((0, 1), repeat=3))]
    print_table(rows)
    print("СДНФ:", sdnf(rows))
    print("СКНФ:", sknf(rows))

def task8():
    # (x ∧ y) ∨ (¬x ∧ y) = (x ∨ ¬x) ∧ y = y
    original = lambda x, y, z: (x and y) or ((not x) and y)
    rows = table(original, 3)
    print_table(rows)
    print("СДНФ:", sdnf(rows))
    print("Количество минтермов:", len(minterms(rows)))
    simplified = lambda x, y, z: y
    from_sdnf = sdnf_function(rows)
    print(*NAMES, "исходная СДНФ упрощённая")
    for values in product((0, 1), repeat=3):
        print(*values, int(original(*values)), from_sdnf(*values), int(simplified(*values)))
    print("Исходная == СДНФ:", equivalent(original, from_sdnf, 3))
    print("Исходная == упрощённая:", equivalent(original, simplified, 3))
    print("СДНФ == упрощённая:", equivalent(from_sdnf, simplified, 3))
    print("Результат: f = y")

match int(input("Номер задания: ")):
    case 1:
        task1()
    case 2:
        task2()
    case 3:
        task3()
    case 4:
        task4()
    case 5:
        task5()
    case 6:
        task6()
    case 7:
        task7()
    case 8:
        task8()