Помимо AND/OR/NOT, какой смысл в других логических операторах в программировании?

Я программировал почти всю свою жизнь (около 20+ лет), и я не думаю, что могу вспомнить хоть один раз, когда я смотрел на выражение if и думал: "Хм, это было бы хорошим временем для используйте XOR." Вся вселенная логического программирования, кажется, вращается вокруг этих трех.

Конечно, с помощью логических элементов И / ИЛИ / НЕ вы можете сделать любое другое логическое утверждение. Однако может быть время, когда вам удастся сэкономить некоторый код для объединения двух или трех операторов в один логический оператор. Давайте посмотрим на 16 возможных комбинаций логических связок:

  1. ЛОЖЬ = Противоречие = 0, ноль, НЕ ИСТИНА
  2. ИСТИНА = Тавтология = 1, НЕ ЛОЖЬ
  3. X = предложение X = X
  4. НЕ Х = Отрицание Х =! Х
  5. Y = предложение Y = Y
  6. НЕ Y = отрицание Y =! Y
  7. X И Y = Соединение = НЕ (X И НЕ Y)
  8. X NAND Y = Альтернативный отказ = НЕ (X И Y),! X ИЛИ! Y
  9. X ИЛИ Y = дизъюнкция = НЕ (! X И! Y)
  10. X NOR Y = Объединенный отказ = НЕ (X ИЛИ Y),! X И! Y
  11. X ⊅ Y = Материальная неявность = X И! Y, НЕ (! X ИЛИ Y), (X XOR Y) И X,???
  12. X ⊃ Y = Материальное значение =! X ИЛИ Y, НЕ (X И! Y), (X XNOR Y) ИЛИ X,???
  13. X ⊄ Y = обратное неявное выражение =! X И Y, НЕ (X ИЛИ! Y), (X XOR Y) И Y,???
  14. X ⊂ Y = обратное значение = X ИЛИ! Y, НЕ (! X И Y), (X XNOR Y) ИЛИ Y,???
  15. X XOR Y = Исключительная дизъюнкция = НЕ (X IFF Y), НЕ (X XNOR Y), X! = Y
  16. X XNOR Y = Biconditional = X IFF Y, НЕ (X XOR Y),! X AND! Y

Таким образом, пункты 1-2 содержат нулевые переменные, пункты 3-6 включают одну, а пункты 7-10 - термины, с которыми мы знакомы. (Хотя у нас обычно нет оператора NAND, но, по крайней мере, в Perl есть "разве что" для универсального NOT.)

Пункты 11-14 кажутся интересными, но я никогда не видел их в программировании. Пункты 15-16 являются XOR/XNOR.

Может ли что-либо из этого быть использовано для упрощения И / ИЛИ / НЕ? Если да, то использовали ли вы их?

ОБНОВЛЕНИЕ: "Не равно" или! = Действительно XOR, который используется постоянно. Итак, XOR используется в конце концов.

6 ответов

Решение

Собираюсь закрыть этот вопрос после вещи Не равно /XOR. Из 16 возможных операторов программисты используют 9 из них:

FALSE, TRUE, X, Y, !X, !Y, AND (or ==), OR, XOR (or !=)

Все остальные операторы обычно не существуют в языках программирования:

X NAND Y = Alternative Denial = NOT (X AND Y), !X OR !Y
X NOR Y = Joint Denial = NOT (X OR Y), !X AND !Y
X ⊅ Y = Material Nonimplication = X AND !Y, NOT(!X OR Y), (X XOR Y) AND X, ???
X ⊃ Y = Material Implication = !X OR Y, NOT(X AND !Y), (X XNOR Y) OR X, ???
X ⊄ Y = Converse Nonimplication = !X AND Y, NOT(X OR !Y), (X XOR Y) AND Y, ???
X ⊂ Y = Converse Implication = X OR !Y, NOT(!X AND Y), (X XNOR Y) OR Y, ???
X XNOR Y = Biconditional = X IFF Y, NOT (X XOR Y), !X AND !Y

Возможно, им есть место позже, потому что NAND/NOR кажется довольно удобным и более чистым, чем ввод NOT (X xxx Y).

"Пункты 11-14 кажутся интересными, но я никогда не видел их в программировании".
Я не согласен. Пункт 12, "Материальный эффект", по сути, является утверждением "ЕСЛИ", он везде в программировании. Я вижу Материальные последствия такие же как:

 if(A) {
    return B
 }

Учти это:

  if(an odd number of conditions are true) then return 1 else return 0

Используя и / или / нет, вы можете попробовать

  if(one is true || three are true || ... 2n+1 are true) then return 1 else return 0

Это довольно уродливо, потому что вам приходится указывать каждый из 1-наборов, 3-наборов, 5-наборов, ..., 2n+1 наборов, которые являются подмножествами набора ваших условий. Версия XOR довольно элегантна, хотя...

  if(C1 XOR C2 XOR ... XOR CN) then return 1 else return 0

Для больших или переменных N это, вероятно, лучше обрабатывать с помощью системы циклов и счетчиков, но когда N не слишком велико (~10), и вы еще не сохраняете условия в виде массива, это не так так плохо. Работает так же для проверки четного числа условий.

Вы можете придумать похожие примеры и для других. Интересным упражнением было бы попробовать программировать что-то вроде

  if((A && !B) || (!A && B)) then return 1 else return 0

И посмотрите, генерирует ли компилятор язык ассемблера для AND, OR и NOT или достаточно умен, чтобы признать, что это XOR, и, основываясь на этом, испускает (возможно, более дешевую) инструкцию XOR.

При программировании на Java я обычно использую следующие логические функции:

  • не !
  • а также &&
  • или же ||
  • XNOR ==
  • исключающее !=,

распространяя это на другие основные функции:

  • материальное значение A || !B
  • обратное значение !A || B
  • материальная неявность !A && B
  • обратное неявное A && !B

Знание того, когда использовать xor и xnor, сводится к упрощению логики. В общем, когда у вас сложная функция:

1) упростить до CNF ("конъюнктивная нормальная форма" или "сумма над произведением") или DNF ("дизъюнктивная нормальная форма" или "произведение над суммой").*

2) удалить дополнительные условия A && (A || B),A || (A && B) -> A

2) упростить (A || !B) && (!A || B),(!A && !B) || (A && B) -> A == B

3) упростить (A || B) && (!A || !B),(A && !B) || (!A && B) -> A != B

Использование этих трех упрощений может привести к получению более чистого кода с использованием функций xor и xnor.

* Следует отметить, что логическая функция может быть намного проще в DNF, чем в CNF или наоборот.

Существенный вариант использования без импликации / абстракции

Теперь у меня есть пример, в котором я хотел бы сделать материальное непересечение / аббревиатуру .

Таблица правды

      ╔═══╦═══╦══════════╗
║ P ║ Q ║ P -/-> Q ║
╠═══╬═══╬══════════╣
║ T ║ T ║ F        ║
║ T ║ F ║ T        ║ <-- all I care about. True followed by false.
║ F ║ T ║ F        ║
║ F ║ F ║ F        ║
╚═══╩═══╩══════════╝

Я имею дело с несколькими разрешениями (все к счастью / false) для нескольких сущностей одновременно и имею ситуацию с ролями и правами, в которой я хочу увидеть, может ли системный пользователь изменить права другого пользователя. Та же операция выполняется сразу для всех сущностей.

Во-первых, мне нужна разница между старым состоянием разрешений объекта и новым обычно желаемым состоянием разрешений для всех объектов.

Затем я хочу сравнить эту дельту с правами на изменение текущего пользователя для этой конкретной сущности.

  • Меня не волнуют разрешения, когда дельта не требует изменения.
  • Я хочу только true флаг, где действие должно быть заблокировано.

Пример

      before:          10001
proposed after:  11001
delta:           01000 <<< I want a material nonimplication...
user rights      10101 <<< ... between these two...
blocked actions: 01000 <<< ... to produce this flag set

Прямо сейчас я просто делаю XOR а затем AND, что одно и то же.

Какой-то код пахнет тем, что есть более простой способ провести сравнение, но, по крайней мере, в этой невероятно громоздкой, пошаговой логике было бы неплохо иметь этот оператор.

Я считаю, что материальное непонимание на самом деле представлено A && !B (ответ Бретту Ярберри)

Другие вопросы по тегам