Задание №2 — Построение таблицы истинности
Миша заполнял таблицу истинности функции F
но успел заполнить лишь фрагмент из трёх различных её строк, даже не указав, какому столбцу таблицы соответствует каждая из переменных w, x, y, z:
| F | ||||
| 1 | 0 | 0 | 0 | |
| 0 | ||||
| 1 | 1 | 0 | ||
| 0 | 1 | 0 |
Определите, какому столбцу таблицы соответствует каждая из переменных w, x, y, z. В ответе напишите буквы w, x, y, z в том порядке, в котором идут соответствующие им столбцы (сначала буква, соответствующая первому столбцу; затем буква соответствующая второму столбцу, и т. д.). Буквы в ответе пишите подряд, никаких разделителей между буквами ставить не нужно.
Пример. Функция F задана выражением зависящим от двух переменных, а фрагмент таблицы имеет следующий вид:
| F | ||
| 0 | 1 | 0 |
В этом случае первому столбцу соответствует переменная y,а второму столбцу — переменная x. В ответе следует написать yx.
Правильный ответ
wyxz
Пояснение
Решение:
Функция зависит от четырёх переменных, поэтому её полная таблица истинности содержит строк, а расставить переменные w, x, y, z по четырём столбцам можно способами.
Найдём все наборы, на которых . Таких наборов всего четыре (значения записаны в «алфавитном» порядке ):
| w | x | y | z | F |
|---|---|---|---|---|
| 0 | 0 | 0 | 0 | 0 |
| 1 | 0 | 0 | 0 | 0 |
| 1 | 1 | 0 | 0 | 0 |
| 1 | 1 | 1 | 0 | 0 |
Значит, каждая строка фрагмента — это одна из этих четырёх строк, только с переставленными столбцами. Но в каком порядке идут сами строки фрагмента, неизвестно, поэтому соответствие «столбец → переменная» надёжнее всего установить перебором всех 24 расстановок.
Отдельно обратим внимание на условие: строки фрагмента различны. Поэтому проверка расстановки такая: для каждой строки фрагмента находим все её дополнения, дающие нужное значение , и убеждаемся, что из этих дополнений можно выбрать попарно различные строки.
Всё это удобно поручить программе. В Python импликация — это a <= b, а эквиваленция — это a == b.
from itertools import product, permutations
def F(w, x, y, z):
return int(((not ((x == y) or (x == w))) or z) or (not (y <= w)))
# фрагмент таблицы: '.' — незаполненная клетка, второе число — значение F
frag = [('100.', 0),
('....', 0),
('11..', 0),
('.01.', 0)]
def fits(mask, vals):
return all(m == '.' or int(m) == v for m, v in zip(mask, vals))
for p in permutations('wxyz'):
# для каждой строки фрагмента — все её допустимые дополнения
variants = []
for mask, f in frag:
variants.append([vals for vals in product((0, 1), repeat=4)
if fits(mask, vals) and F(**dict(zip(p, vals))) == f])
# строки фрагмента должны быть попарно различны
for lines in product(*variants):
if len(set(lines)) == len(lines):
print(''.join(p))
break
Программа печатает единственную расстановку — wyxz.
Проверим её вручную. Столбцы идут в порядке ; восстановим пустые клетки (восстановленные значения выделены курсивом):
| w | y | x | z | F |
|---|---|---|---|---|
| 1 | 0 | 0 | 0 | 0 |
| 0 | 0 | 0 | 0 | 0 |
| 1 | 1 | 1 | 0 | 0 |
| 1 | 0 | 1 | 0 | 0 |
Все строки различны, известные клетки совпадают с фрагментом, и функция на них принимает требуемые значения — расстановка найдена верно.
Ответ: wyxz