开发者

Besides AND/OR/NOT, what's the point of the other logical operators in programming?

I've been programming nearly all of my life (around 20+ years), and I don't think I can remember a single time when I was looking at a if-statement and think "Hmmm, this would be a good time to use XOR." The entire logical programming universe seems to revolve around just these three.

Granted, with AND/OR/NOT gates, you can make any other logical statement. However, there might be a time where it might save you some code to combine two or three statements into a single logical statement. Let's look at the 16 possible combinations of logical connectives:

  1. FALSE = Contradiction = 0, null, NOT TRUE
  2. TRUE = Tautology = 1, NOT FALSE
  3. X = Proposition X = X
  4. NOT X = Negation of X = !X
  5. Y = Proposition Y = Y
  6. NOT Y = Negation of Y = !Y
  7. X AND Y = Conjunction = NOT (X NAND Y)
  8. X NAND Y = Alternative Denial = NOT (X AND Y), !X OR !Y
  9. X OR Y = Disjunction = NOT (!X AND !Y)
  10. X NOR Y = Joint Denial = NOT (X OR Y), !X AND !Y
  11. X ⊅ Y = Material Nonimplication = X AND !Y, NOT(!X OR Y), (X XOR Y) AND X, ???
  12. X ⊃ Y = Material Implication = !X OR Y, NOT(X AND !Y), (X XNOR Y) OR X, ???
  13. X ⊄ Y = Converse Nonimplication = !X AND Y, NOT(X OR !Y), (X XOR Y) AND Y, ???
  14. X ⊂ Y = Converse Implication = X OR !Y, NOT(!X AND Y), (X XNOR Y) OR Y, ???
  15. X XOR Y = Exclusive disjunction = NOT (X IFF Y), NOT (X XNOR Y), X != Y
  16. X XNOR Y = Biconditional = X IFF Y, NOT (X XOR Y), !X AND !Y

So, items 1-2 involve zero variables, items 3-6 involve one, and items 7-10 are terms we are familiar with. (Though, we don't usually have a 开发者_如何学编程NAND operator, but at least Perl has "unless" for universal NOT.)

Items 11-14 seem like interesting ones, but I've never seen these in programming. Items 15-16 are the XOR/XNOR.

Can any of these be used for AND/OR/NOT simplification? If so, have you used them?

UPDATE: "Not equal" or != is really XOR, which is used constantly. So, XOR is being used after all.


Going to close this question after the Not Equals/XOR thing. Out of the 16 possible operators, programmers use 9 of them:

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

All of the other operators don't typically exist in programming languages:

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

Perhaps there's room for them later on, because NAND/NOR seems pretty handy, and cleaner than typing NOT (X xxx Y).


Consider this:

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

Using and/or/not, you might try

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

That's pretty ugly because you end up having to specify each of the 1-sets, 3-sets, 5-sets, ..., 2n+1 sets which are subsets of the set of your conditions. The XOR version is pretty elegant, though...

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

For a large or variable N, this is probably better handled with a loop and counter system anyway, but when N isn't too large (~10), and you aren't already storing the conditions as an array, this isn't so bad. Works the same way for checking an even number of conditions.

You can come up with similar examples for the others, too. An interesting exercise would be to try programming something like

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

And see whether the compiler emits assembly language for ANDs, ORs and NOTs or is smart enough to recognize this is XOR and, based on this, emits (a possibly cheaper) XOR instruction.


When programming in java, I tend to mostly use the following logic functions:

  • not !
  • and &&
  • or ||
  • xnor ==
  • xor !=,

extending this to other basic functions:

  • material implication A || !B
  • converse implication !A || B
  • material nonimplication !A && B
  • converse nonimplication A && !B

Knowing when to use the xor and xnor comes down to simplifying the logic. In general, when you have a complex function:

1) simplify to either CNF ("conjunctive normal form" aka "sum over product") or DNF ("disjunctive normal form" aka "product over sum").*

2) remove extra terms A && (A || B),A || (A && B) -> A

2) simplify (A || !B) && (!A || B),(!A && !B) || (A && B) -> A == B

3) simplify (A || B) && (!A || !B),(A && !B) || (!A && B) -> A != B

Using these 3 simplifications can lead to much cleaner code using both the xor and xnor functions.

*It should be noted that a logical function may be much simpler in DNF than CNF or vice versa.


"Items 11-14 seem like interesting ones, but I've never seen these in programming."
I disagree. item 12, Material Implication is basically a "IF" statement, it is everywhere in programming. I see Material Implication same as:

 if(A) {
    return B
 }


Material nonimplication/abjunction use case

Got an instance now where I'd like to do a material nonimplication/abjunction.

Truth Table

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

I'm dealing with a number of permissions (all luckily true/false) for a number of entities at once and have a roles and rights situation where I want to see if a system user can change another user's permissions. The same operation is being attempted on all the entities at once.

First I want the delta between the between an entity's old permission state and new commonly desired permission state for all entities.

Then I want to compare that delta to the current user's change rights for this specific entity.

  • I don't care about permissions where the delta requires no change.
  • I only want a true flag where an action should be blocked.

Example

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

Right now I'm just doing an XOR and then an AND, which is the same thing.

Which kinda code smells that there's an easier way to do the comparison, but at least in this incredibly stodgy, step-by-step logic, it would be nice to have that operator.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜