【问题标题】:Besides AND/OR/NOT, what's the point of the other logical operators in programming?除了 AND/OR/NOT,其他逻辑运算符在编程中的意义何在?
【发布时间】:2011-11-26 13:02:35
【问题描述】:

我几乎一生都在编程(大约 20 多年),我想我不记得有一次当我看到一个 if 语句并想“嗯,这将是一个使用 XOR 的好时机。”整个逻辑编程领域似乎都围绕着这三个。

当然,使用 AND/OR/NOT 门,您可以做出任何其他逻辑语句。但是,有时可能会节省一些代码来将两个或三个语句组合成一个逻辑语句。让我们看看logical connectives的16种可能组合:

  1. FALSE = 矛盾 = 0,null,NOT TRUE
  2. 真 = 重言式 = 1,不假
  3. X = 命题 X = X
  4. NOT X = X 的否定 = !X
  5. Y = 命题 Y = Y
  6. NOT Y = Y 的否定 = !Y
  7. X AND Y = 合取 = NOT (X NAND Y)
  8. X NAND Y = 替代拒绝 = NOT (X AND Y), !X OR !Y
  9. X OR Y = 析取 = NOT (!X AND !Y)
  10. X NOR Y = 联合拒绝 = NOT (X OR Y), !X AND !Y
  11. X ⊅ Y = 材料非暗示 = X AND !Y, NOT(!X OR Y), (X XOR Y) AND X, ???
  12. X ⊃ Y = 实质含义 = !X OR Y, NOT(X AND !Y), (X XNOR Y) OR X, ???
  13. X ⊄ Y = 逆非蕴涵 = !X AND Y, NOT(X OR !Y), (X XOR Y) AND Y, ???
  14. X ⊂ Y = 逆蕴涵 = X OR !Y, NOT(!X AND Y), (X XNOR Y) OR Y, ???
  15. X XOR Y = 异或分离 = NOT (X IFF Y), NOT (X XNOR Y), X != Y
  16. X XNOR Y = 双条件 = X IFF Y、NOT (X XOR Y)、!X AND !Y

所以,第 1-2 项涉及零变量,第 3-6 项涉及 1,第 7-10 项是我们熟悉的术语。 (虽然,我们通常没有 NAND 运算符,但至少 Perl 有通用 NOT 的“除非”。)

第 11-14 项看起来很有趣,但我在编程中从未见过这些。第 15-16 项是 XOR/XNOR。

这些中的任何一个都可以用于 AND/OR/NOT 简化吗?如果有,你用过吗?

更新:“不等于”或 != 实际上是 XOR,经常使用。所以,毕竟是在使用 XOR。

【问题讨论】:

  • "这些中的任何一个都可以用于 AND/OR/NOT 简化吗?"你在开玩笑吗?查看列表的右侧。现在看左边。完成。
  • 不管怎样,这些运算符最常用于位掩码功能,而不是逻辑/条件简化。
  • 你在开玩笑吗?查看列表的右侧。现在看左边。完成。 是的,但我实际上是在说。 XOR 是编程中唯一可用的其他功能,而且我从未真正见过使用它的地方。我的大多数复杂逻辑语句都涉及几个不同的变量,这里不适用。
  • “你在开玩笑吗?看看你列表的右边。现在看看左边。完成了。” - 这也是我最初的反应。我想知道我们是否不理解他所说的“实用”是什么意思。
  • 与现实世界的例子一样实用。我们拥有所有这些不同的逻辑门,而我们实际上只使用了三个,这似乎很奇怪。

标签: coding-style logic boolean-logic xor nor


【解决方案1】:

在 Not Equals/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) 更简洁。

【讨论】:

    【解决方案2】:

    考虑一下:

      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-sets、3-sets、5-sets、...、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 指令。

    【讨论】:

      【解决方案3】:

      在java中编程时,我倾向于主要使用以下逻辑函数:

      • 不是!
      • &&
      • ||
      • xnor ==
      • 异或!=

      将此扩展到其他基本功能:

      • 实质含义A || !B
      • 逆向蕴涵!A || B
      • 实质性非暗示!A && B
      • converse 非暗示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

      使用这 3 种简化可以使代码更简洁,同时使用 xor 和 xnor 函数。

      *需要注意的是,DNF 中的逻辑函数可能比 CNF 简单得多,反之亦然。

      【讨论】:

        【解决方案4】:

        “第 11-14 项看起来很有趣,但我在编程中从未见过这些。”
        我不同意。 item 12, Material Implication 基本上是一个“IF”语句,在编程中无处不在。 我认为实质性含义与以下内容相同:

         if(A) {
            return B
         }
        

        【讨论】:

          【解决方案5】:

          材料非暗示/放弃用例

          现在有一个实例,我想做一个material nonimplication/abjunction

          真值表

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

          我正在同时处理多个实体的多个权限(幸运的是 true/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,这是同一件事。

          哪种代码闻起来有一种更简单的方法可以进行比较,但至少在这种令人难以置信的枯燥、循序渐进的逻辑中,拥有该运算符会很好。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-01-09
            • 2023-01-31
            相关资源
            最近更新 更多