Курс№15. Логические выражения с параметром A0%
Теория · номер 15 из 27

Логические выражения с параметром A

Дана формула с неизвестным A, и она должна быть истинна при всех x. Формулу переводим в Python, перебираем A и проверяем. Один шаблон закрывает почти все задачи.

9 разделов~45 минут1 первичный балл
  1. 1Что проверяет номер
  2. 2Формула в Python и общий шаблон
  3. 3ДЕЛ: делимость
  4. 4Поразрядная конъюнкция
  5. 5Неравенства с двумя переменными
  6. 6Отрезки
  7. 7Множества
  8. 8Проверяем руками
  9. 9Ловушки и домашка
Раздел 1 из 9

Что проверяет номер

Дана логическая формула с неизвестным A. Это может быть число, отрезок или множество. Надо найти такое A, при котором формула истинна для всех x. Именно это значат слова «тождественно истинна».

A это число

Спрашивают наименьшее или наибольшее A. Формулы с делимостью, поразрядным И и неравенствами.

ДЕЛ(x, 128) → (¬ДЕЛ(x, A) → ¬ДЕЛ(x, 80)). Для какого наибольшего A формула истинна при любом x?

A это отрезок или множество

Спрашивают длину отрезка или сумму элементов множества.

P = [15; 40], Q = [30; 65]. Какова наименьшая длина отрезка A для формулы P → ((Q ∧ ¬A) → ¬P)?

Основной способ это код: перебираем A и проверяем формулу на большом диапазоне x. Руками проверяем себя в конце урока.

Ответы к примерам

В первом примере A = 640, во втором длина 10. Как их получить, разберём дальше.

Раздел 2 из 9

Формула в Python и общий шаблон

В условииВ Python
¬not
∧and
∨or
→<=
≡==

Импликация записывается через <=, потому что True <= False это False, а все остальные сочетания дают True. Как раз так работает импликация: ложна она только тогда, когда из истины следует ложь.

Ловушка: скобки обязательны

В логике порядок действий такой: ¬, ∧, ∨, →, ≡. А в Python сравнения <= и == выполняются раньше, чем not, and и or. Поэтому каждую импликацию и эквивалентность бери в скобки вместе с обеими частями.

Вот что будет без скобок. Формула A → (B ∧ C) при A = 0 истинна, а запись без скобок даёт другое:

python
print(False <= True and False)     # Python считает (False <= True) and False
print(False <= (True and False))   # а так как надо

Общий шаблон

Описываем формулу функцией f, перебираем A и проверяем, что f истинна для всех x. Функция all(...) истинна, когда истинна каждая проверка внутри.

python
def d(n, m):
    return n % m == 0                 # n делится на m

def f(x, A):
    return d(x, 128) <= ((not d(x, A)) <= (not d(x, 80)))

print(max(A for A in range(1, 1000) if all(f(x, A) for x in range(1, 2000))))

Ответ 640. Если нужно наименьшее значение, max меняем на min. Диапазон x берём с запасом: range(1, 2000) для обычных чисел, range(0, 4000) для поразрядных.

Раздел 3 из 9

ДЕЛ: делимость

ДЕЛ(n, m) значит «n делится на m без остатка». Пишем функцию d, а дальше формулу из условия. Пример с наибольшим A был в прошлом разделе, вот пример с наименьшим:

python
def d(n, m):
    return n % m == 0

def f(x, A):
    return d(x, A) <= (d(x, 18) or (not d(x, 24)))

print(min(A for A in range(1, 200) if all(f(x, A) for x in range(1, 2000))))
Попробуй самучебная задача

Для какого наибольшего натурального числа A формула ДЕЛ(x, 36) → (¬ДЕЛ(x, A) → ¬ДЕЛ(x, 60)) тождественно истинна?

Раздел 4 из 9

Поразрядная конъюнкция

x & 52 это поразрядное И: единица стоит только в тех разрядах, где она есть у обоих чисел. Сравнение с нулём пишется без скобок вокруг x & 52, потому что & в Python выполняется раньше, чем != и ==.

python
def f(x, A):
    return ((x & 52 != 0) and (x & 48 == 0)) <= (not (x & A == 0))

print(min(A for A in range(1, 2000) if all(f(x, A) for x in range(0, 4000))))

В условии обычно написано x & A ≠ 0, поэтому not (x & A == 0) можно записать и как x & A != 0.

Попробуй самучебная задача

Для какого наименьшего натурального числа A формула ((x & 44 ≠ 0) ∧ (x & 12 = 0)) → (x & A ≠ 0) тождественно истинна при любом целом неотрицательном x?

Раздел 5 из 9

Неравенства с двумя переменными

Тут внутри all два перебора: по x и по y.

python
def f(x, y, A):
    return (x + 2 * y != 58) or (A > 2 * x) or (A > y)

print(min(A for A in range(1, 200)
          if all(f(x, y, A) for x in range(1, 500) for y in range(1, 500))))

Такой код уже работает пару секунд. Если он упирается в лимит времени, подбери диапазоны меньше, но так, чтобы опасные значения в них попадали. В примере важны только пары, где x + 2y = 58, значит x и y не больше 58.

Попробуй самучебная задача

Для какого наименьшего натурального числа A формула (x + 3y ≠ 60) ∨ (A > x) ∨ (A > y) тождественно истинна при любых натуральных x и y?

Раздел 6 из 9

Отрезки

Тут A это отрезок [a1; a2], а спрашивают его длину. Проверять все x не нужно. Значение формулы меняется только у концов отрезков, поэтому берём опасные точки: концы отрезков из условия и точки чуть левее и правее. Концы A ищем среди них же.

python
def f(x):
    P = 15 <= x <= 40
    Q = 30 <= x <= 65
    A = a1 <= x <= a2
    return P <= ((Q and (not A)) <= (not P))

d = [y for x in (15, 30, 40, 65) for y in (x, x - 0.1, x + 0.1)]
n = []
for a1 in d:
    for a2 in d:
        if a2 >= a1 and all(f(x) for x in d):
            n.append(a2 - a1)
print(round(min(n)))

Здесь a1 и a2 внутри f берутся из цикла снаружи. round нужен, потому что из-за 0.1 длина получается с хвостиком.

Попробуй самучебная задача

На числовой прямой даны отрезки P = [12; 50] и Q = [35; 70]. Какова наименьшая длина отрезка A, при которой формула P → ((Q ∧ ¬A) → ¬P) тождественно истинна?

Раздел 7 из 9

Множества

Тут A это множество чисел. Начинаем с пустого и идём по всем x. Если формула ложна, значит этот x обязан быть в A, и мы его добавляем.

python
a = set()

def f(a):
    P = x in {2, 4, 6, 8, 10, 12}
    Q = x in {4, 5, 6, 7, 8}
    A = x in a
    return (P <= (not Q)) or A

for x in range(1, 100):
    if f(a) == 0:                  # формула ложна
        a.add(x)                   # значит, x обязан быть в A
print(sorted(a))
print(sum(a))

Тут x внутри f тоже берётся из цикла снаружи. Если множество нужно не наименьшее, а наибольшее, стартуем с a = set(range(1, 100)) и убираем лишнее через a.remove(x).

Попробуй самучебная задача

Даны множества P = {1, 3, 5, 7, 9, 11} и Q = {3, 6, 9, 12}. Формула (x ∈ P → x ∉ Q) ∨ (x ∈ A) тождественно истинна при натуральных x от 1 до 99. Какова наименьшая сумма элементов множества A?

Раздел 8 из 9

Проверяем руками

Код даёт ответ, а руками удобно проверить, что формула записана верно. Порядок такой:

  1. С частью без A находим значения x и y.
  2. Часть без A делаем ложной.
  3. Делаем выводы и пишем ответ.

Для неравенств и ДЕЛ правило короткое: отрицаем условия и решаем.

Законы

ДЕЛ руками

Разберём формулу ДЕЛ(x, 128) → (¬ДЕЛ(x, A) → ¬ДЕЛ(x, 80)). Для краткости будем писать только числа.

  1. Записываем: 128 → (¬A → ¬80).
  2. Упрощаем: ¬128 ∨ A ∨ ¬80, то есть ¬128 ∨ ¬80 ∨ A.
  3. Сворачиваем обратно: (128 ∧ 80) → A.

Значит, если x делится на 128 и на 80, то он делится на A. Такие x это числа, кратные 640, поэтому A должно быть делителем 640. Наибольшее A равно 640, как и в коде.

Отрезки и множества руками

Формула P → ((Q ∧ ¬A) → ¬P) по тем же законам равна (P ∧ Q) → A. Значит, A должен накрыть общую часть P и Q, и наименьшая длина это длина пересечения.

С множествами так же. Формула (P → ¬Q) ∨ A требует, чтобы A содержало пересечение P и Q. Напомним: объединение это всё, что есть хотя бы в одном множестве, а пересечение это общая часть.

Раздел 9 из 9

Ловушки и домашка

ЛовушкаКак не попасться
min и max перепутаныСмотри, что просят: наименьшее или наибольшее
Импликация записана не такЭто <=, а не -> и не >=
Нет скобок вокруг <= и ==В Python сравнения выполняются раньше not, and, or. Ставь скобки
Слишком маленький диапазон xНеверное A покажется подходящим. Бери диапазон с запасом
Отрезки: не те точкиКонцы всех отрезков, точки x - 0.1 и x + 0.1, условие a2 >= a1, длину округляем через round
Формула должна быть ложнойПроверяй f(x) == 0
Множестваf(a) == 0 значит «ложно», тогда x добавляем

Как решать задачу

  1. Определи тип: ДЕЛ, &, неравенства, отрезки, множества.
  2. Перепиши формулу в Python по таблице и расставь скобки.
  3. Составь перебор: min или max, диапазоны A и x.
  4. Запусти. Проверь себя руками по разделу 8.

Домашка

Семь задач с настоящих экзаменов и из банка ФИПИ. Решай прямо здесь: кнопка «Решать здесь» открывает редактор, а код каждой задачи сохраняется.

Где теряют балл в этих задачах

В третьей задаче A начинается с нуля и нужно наибольшее значение. В четвёртой формула должна быть ложной, а длина наибольшей. В седьмой число 78125 слишком большое для двойного перебора: y выражается через x как 78125 - 4 * x, так что хватает одного цикла по x. Найди самое большое значение из x и y, и A будет на 1 больше.

Ещё задачи этого вида лежат в разделе «Задания», №15. Там же есть учебные задачи на & и множества.

Задачи «Попробуй сам» учебные, в домашке задачи с настоящих экзаменов и из банка ФИПИ. Код в блоках можно менять и запускать, он выполняется прямо в браузере.