How to convert logical statements into their opposites? - logic

I have a scenario where I am checking whether to hide something depending on multiple variables values. For some these statements, if they evaluate to true, then I will skip over showing something (showing by default). However, I need to re-write my statements so that if they evaluate to true, then I will show something (hiding by default).
For Example:
If X !== 1 && Y !==1
For Example:
If X === 3 or Y === 3
If either example were true, then I would skip (hide) something.
I need to flip conditions the conditions written in the code so that the expressions are their opposites. I cannot just evaluate the original expression and then swap the end true/false result.
Would
X === 1 or Y === 1
And
X !== 3 && Y !== 3
Be the logical opposites respectively? How can I approach re-writing these expressions so that they would evaluate to their opposite result every time?
I cannot simply do !(If X !== 1 && Y !==1) in this situation. Would De Morgan's law be applicable to what I am trying to do? I'm considering just flipping all "===" to "!===" (and vice versa) and flipping all "ands/ors" so that I can get the results I want. This seems to work in cases I've tried, however I am not sure whether it would be working in "all" cases. Thank you!

if I follow what you're asking the inverse of
If X !== 1 && Y !==1
is:
if (X == 1 || Y == 1)
which is the same as:
if !(X !== 1 && Y !==1)
Here's how to think about it: In your example, both X and Y must not equal 1 to be true; therefore if either X or Y equal 1 the statement is false. Now convert that last sentence to boolean.
When inverting a logical statement, invert the arguments and the logical condition: "and" becomes an "or" and vise-versa.

If the goal is to negate the whole condition, the simplest way to do it is to just wrap the entire expression in !.
For example the following conditional clause:
If X !== 1 && Y !== 1
can be flipped by replacing it with:
If !(X !== 1 && Y !== 1)
Now, this is perfectly correct, but it may seem rather ugly to you. This is where DeMorgan's laws can be applied, to rewrite the expression in an equivalent, but possibly syntactically simpler form.
DeMorgan's laws state that:
!(x && y) === !x || !y, and that
!(x || y) === !x && !y.
So we can for example take our ugly (but correctly flipped) conditional clause above:
If !(X !== 1 && Y !== 1)
and use the first of DeMorgan's laws listed above to rewrite it (without changing the meaning at all):
If !(X !== 1) || !(Y !== 1)
and then by simple reasoning (!(a !== b) is equivalent to !(!(a === b)) is equivalent to a === b):
If X === 1 || Y === 1
and this is (also) a flipped version of the original clause If X !== 1 && Y !== 1.

Related

One and only one zero comparison with the least operations

This might be a silly question, but in some function I have two int s, and need to compare them to find if exactly one of them is ==0... Both of the ways I came up with require 5 logical operations, and I can't think of anything shorter... Is there a shorter way?
What I came up with is:
int x, y;
if (((x==0) || (y==0)) && (x != y)){} // most obvious option, or:
if (((x^y) == x) ^ ((x^y) == y)){} // looks better, but still 5 ops
The expression ((x^y) == x) ^ ((x^y) == y) can be simplified in a straightforward way.
(x^y) == x if and only if y == 0, and likewise (x^y) == y if and only if y == 0. So the following uses three operations to compute the condition:
if((x == 0) ^ (y == 0)) {
// ...
}
This makes sense because using XOR as a logical operator, the result is true if and only if one but not both of the operands is true. So this directly tests whether one but not both of x == 0 and y == 0 are true.

How to write a conditional lambda in Ruby?

I'd like to write a conditional lambda in Ruby. The Python equivalent of what I'd like to write is:
even = (lambda x: x if x % 2 == 0 else 0)
My attempt to write this in Ruby looks like:
even = -> (x) {x if x % 2 == 0 else 0}
Unfortunately, that does not work. Is there any way to fix this?
You have several options here to express this. The long-form is this:
if (x % 2 == 0)
x
else
0
end
Note that a trailing if or unless cannot have a secondary condition like else. You need to use the full form.
If you want a short version, you use the ternary operator:
(x % 2 == 0) ? x : 0
What you could also do is this:
(x % 2 == 0) and x or 0
As others have observed there's a method called even? which does the modulo for you, so that can collapse this further:
x.even? ? x : 0
Ruby's ternary operator has this syntax
x % 2 == 0 ? x : 0
You don't even need a conditional.
p = ->(x) { x*(1-x%2) }
p.call(4) #=> 4
p.call(5) #=> 0
Note procs can be called in multiple ways:
p[4] #=> 4
p.(4) #=> 4
p.yield(4) #=> 4
p === 4 #=> 4
p(4) #=> 4
The last of these may be archaic.
Wrong syntax. You can write it like this:
even = -> (x) {if x % 2 == 0; x; else; 0; end}
However, for such one-liners, it is more common to use the ternary ?: operator, as other have suggested in this thread.
Your syntax is wrong:
The then-block comes after the condition, not before it.
The then-block is separated from the condition by the then keyword, a semicolon, or a newline.
The conditional expression is terminated with an end keyword.
So, any of the following is valid:
# idiomatic:
if x % 2 == 0 then x else 0 end
# idiomatic:
if x % 2 == 0
x
else
0
end
# non-idiomatic:
if x % 2 == 0; x else 0 end
# non-idiomatic:
if x % 2 == 0 then
x
else
0
end
# non-idiomatic:
if x % 2 == 0
x else 0 end
# … and many other non-idiomatic variations
Ruby also has a conditional operator:
x % 2 ? x : 0
But I personally find it ugly and unreadable. It also has different precedence than the conditional expression, which may be surprising to some. (Witness the myriad of variations of the same question about the conditional operator here on StackOverflow.) And it is completely unnecessary: in C, where if is a conditional statement, the conditional operator is required because it is an expression. In Ruby, everything is an expression anyway, there are no statements, so of course if is an expression, too.

Understanding precedence of assignment and logical operator in Ruby

I can't understand precedence of Ruby operators in a following example:
x = 1 && y = 2
Since && has higher precedence than =, my understanding is that similarly to + and * operators:
1 + 2 * 3 + 4
which is resolved as
1 + (2 * 3) + 4
it should be equal to:
x = (1 && y) = 2
However, all Ruby sources (including internal syntax parser Ripper) parse this as
x = (1 && (y = 2))
Why?
EDIT [08.01.2016]
Let's focus on a subexpression: 1 && y = 2
According to precedence rules, we should try to parse it as:
(1 && y) = 2
which doesn't make sense because = requires a specific LHS (variable, constant, [] array item etc). But since (1 && y) is a correct expression, how should the parser deal with it?
I've tried consulting with Ruby's parse.y, but it's so spaghetti-like that I can't understand specific rules for assignment.
Simple. Ruby only interprets it in a way that makes sense. = is assignment. In your expectation:
x = (1 && y) = 2
it does not make sense to assign something to 1 && y. You can only assign something to a variable or a constant.
And note that the purpose of the precedence rule is to disambiguate an otherwise ambiguous expression. If one way to interpret it does not make sense, then there is no need for disambiguation, and hence the precedence rule would not be in effect.
My understanding is that in the case of
x = 1 && y = 2
The logical AND is parsed first. The AND then is forced to evaluate its left side and its right side. In the evaluation the left side the first assignment occurs, and then in the evaluation of the right side the second does the same. It is for this reason that in the case of:
x = false && y = 2
"y" will never be assigned. The AND is hit, forcing the x assignment to evaluate, but never bothering to run the y assignment, as it is unnecessary for the AND to fulfill its purpose.
In other words, the parser is, again, simply to my understanding, smart enough to recognize that in running the AND the equation is split into a left and right side (equations), which are in turn evaluated according to the order of operation.

Difference between negation and inequality in Ruby?

What is the difference between if !variable == 10 {...} and if variable != 10 {...} in Ruby programming language? Of course this can be applied to all other languages. In first case are we just negating condition, and in second testing if variable is actually unequal to 10?
if variable != 10 is equivalent to unless variable == 10
while !variable is negating the variable, so first it's evaluated as an expression, then negated.
Example
variable = 5
variable != 10 # => true
!variable # => false (5 is evaluated to true, then negated)
!variable = 10 # => warning: found = in conditional, should be ==
To a large degree all programming languages, including Ruby, follow boolean algebra rules that state there's a number of ways to express the same condition.
x != y
!(x == y)
!!(x != y)
This also plays out in other domains, such as:
!x && !y
!(x || y)
As others have pointed out, be very careful when using the == comparator instead of the = assignment operator.

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:
FALSE = Contradiction = 0, null, NOT TRUE
TRUE = Tautology = 1, NOT FALSE
X = Proposition X = X
NOT X = Negation of X = !X
Y = Proposition Y = Y
NOT Y = Negation of Y = !Y
X AND Y = Conjunction = NOT (X NAND Y)
X NAND Y = Alternative Denial = NOT (X AND Y), !X OR !Y
X OR Y = Disjunction = NOT (!X AND !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 XOR Y = Exclusive disjunction = NOT (X IFF Y), NOT (X XNOR Y), X != Y
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.

Resources