I have a java program where I want to validate if any of 3 booleans is false. I want to figure out the smallest expression I can write to check against the permutations.
if(!(needsWork && (needsApproval || isAdmin) ))
I think this is enough to make sure that if any of the 3 booleans is false I want to stop processing. However, I have the sneaking suspicion I am missing something.
Would if (!needsWork || !needsApproval || !isAdmin) not work? Java supports short-circuit evaluation.
Since
`any 3 booleans are false` (i.e. `!a || !b || !c`)
and
`(! (needsWork && (needsApproval || isAdmin))` (i.e. (! (a && ( b || c))`
have different truth tables, are you sure that the cases that are different don't matter?
a b c (!a || !b || !c) (! (a && (b || c)))
T T T F F
T T F T F
T F T T F
T F F T T
F T T T T
F T F T T
F F T T T
F F F T T
Transformations
I will often play around with boolean expressions to try to clarify or simplify them and I use these logic transformations to help me:
// You can push (distribute) `!` into parenthesis if you reverse the `||` or `&&` operator inside:
! (a || b) <=> (! a && ! b)
! (a || b || c || ...) <=> (! a && ! b && ! c && ...)
! (a && b) <=> (! a || ! b)
! (a && b && c && ...) <=> (! a || ! b || ! c || ...)
// You can drop parens when the boolean operator outside the parens is the same as inside:
(a || (b || c || ...)) <=> (a || b || c)
(a && (b && c && ...)) <=> (a && b && c)
// You can push (distribute) a boolean op into parenthesis by applying it to each term inside:
(a || (b && c) <=> ((a || b) && (a || c)
(a || (b && c && ...) <=> ((a || b) && (a || c) && (a || ...) ...
(a && (b || c) <=> ((a && b) || (a && c))
(a && (b || c || ...) <=> ((a && b) || (a && c) || (a || ...) ...
// XOR means the term values have to be different:
(a ^ b) <=> ((a && !b) || (!a && b))
// XOR means the same as OR unless both terms are true:
(a ^ b) <=> ((a || b) && ! (a && b))
There are of course many others, but these are ones I use most often. It may look complicated, but they are easy to get to know by heart once you start by practicing them.
In your case, if you wanted to see what some possible equivalent statements for:
(! (needsWork && (needsApproval || isAdmin) ))
here are some transformations:
(! (needsWork && (needsApproval || isAdmin) )) => [push the '!' through the `()`]
(! needsWork || ! (needsApproval || isAdmin) ) => [push the 2nd '!' through the `()`]
(! needsWork || (! needsApproval && ! isAdmin))
but I don't see any real simplification of what you have.
Of course, if checking that any of 3 booleans are false is fine, then your choices are simple
(! needsWork || ! needsApproval || ! isAdmin) => [or pull the `!` outside the `()`]
(! (needsWork && needsApproval && isAdmin))
if(!(needsWork & needsApproval & isAdmin))
Related
For this expression :
((a == b && b == c) && (a == b || b == c || a == c))
Is it legal to write it like below :
(a == b && b == c && a == b || b == c || a == c)
I want to compare the first set with the second set.
a, b and c are integers :
private int a;
private int b;
private int c;
No, it is not. && is associative: A && B && C is the same as A && (B && C) and (A && B) && C, and || is as well: A || B || C is the same as A || (B || C) and (A || B) || C.
However, it does not work when two different operations are involved: (A && B) || C is very different from A && (B || C). Furthermore, since && binds more tightly than ||, A && B || C is the same as the former, and different from the latter.
Thus, your first example
((a == b && b == c) && (a == b || b == c || a == c))
is equivalent to
(a == b && b == c && (a == b || b == c || a == c))
but your second example
(a == b && b == c && a == b || b == c || a == c)
is equivalent to a something completely different:
((a == b && b == c && a == b) || b == c || a == c)
(As Kayaman notes in the comments, it is irrelevant in this particular example, since all of them can be reduced to just (a == b && b == c), by the virtue of specific predicates used in your example; thus, while they are identical in this particular example, you should still understand the concepts of associativity and precedence to be used in general.)
It is legal, but it has a different meaning.
Since && has higher priority than || and operators associate from left to right your second example is parsed as
((a == b && b == c) && a == b) || b == c || a == c
AND (&&) operator has a higher precedence than OR (||) operator. This means that last comparison expressions:
b == c
a == c
will be computed after first half of your expression. After that OR operators will be calculated. So, yes it is legal in your case, but will return different answer.
Your condition will be computed as follows:
((a == b && b == c) && a == b) || b == c || a == c
I have an order of operations problem from a quiz and the explanation is not exactly helpful. Here is the code:
package com.udayan.oca;
public class Test {
public static void main(String [] args) {
int a = 2;
boolean res = false;
res = a++ == 2 || --a == 2 && --a == 2;
System.out.println(a);
}
}
It says it prints 3 which it does because I tested that but I do not understand how. Here is their explanation:
a++ == 2 || --a == 2 && --a == 2;
[Given expression]. (a++) == 2 || --a == 2 && --a == 2;
[Postfix has got higher precedence than other operators].
(a++) == 2 || (--a) == 2 && (--a) == 2;
[After postfix, precedence is given to prefix].
((a++) == 2) || ((--a) == 2) && ((--a) == 2);
[== has higher precedence over && and ||].
((a++) == 2) || (((--a) == 2) && ((--a) == 2));
[&& has higher precedence over ||].
Let's start solving it: ((a++) == 2) || (((--a) == 2) && ((--a) == 2));
[a=2, res=false].
(2 == 2) || (((--a) == 2) && ((--a) == 2));
[a=3, res=false]. true || (((--a) == 2) && ((--a) == 2));
[a=3, res=false].
|| is a short-circuit operator, hence no need to evaluate expression on the right.
res is true and a is 3.
Yes, I understand short circuiting by the way so no need to explain that.
So here is my thinking however:
res = a++ == 2 || --a == 2 && --a == 2 ->
(((a++) == 2) || (((--a) == 2) && ((--a) == 2))) [a = 2]
(((a++) == 2) || ((**1** == 2) && ((--a) == 2))) [a = 1]
(((a++) == 2) || (**false** && (**0** == 2))) [a = 1] //short-circuits
(((a++) == 2) || **false**) [a = 1] //short circuits
(**false**) [a = 1]
????
Another point is that the answer key says to do a++ first then || next. a++ yah that makes sense. But I thought && is before ||.
From the Java Language Specification,
The conditional-or operator || operator is like | (§15.22.2), but evaluates its right-hand operand only if the value of its left-hand operand is false.
So, this is simpler than you think. res = a++ == 2 || --a == 2 && --a == 2; is evaluated like so:
res = ((a++ == 2) || ((--a == 2) && (--a == 2)));
a++ == 2? Post-increment means that a is read as 2. Then that expression is evaluated. 2 == 2, which is true. Short circuit means that the rest of the expression is never evaluated.
So, essentially all the above code does is res = a++ == 2;
I made a simple program to test this:
public class TestSOCode {
public static void main(String [] args) {
test1();
}
private static void test1(){
int a = 2;
boolean res = false;
//res = a++ == 2 || --a == 2 && --a == 2;
res = expression(a++, "One") || expression(--a, "Two") && expression(--a, "Three");
System.out.println(res +" "+ a);
}
private static boolean expression(int i, String s){
System.out.println(s+ " called with "+ i);
return i == 2;
}
}
This gives the result
One called with 2
true 3
UPDATE: After some discussion and research, I think there's been a misunderstanding of the difference between precedence and execution order when it comes to logical operators.
res = a++ == 2 || --a == 2 && --a == 2;
The above statement's precedence is worked out before it's evaluated. I won't go over the other precedence rules since it would complicate this answer, so I'll simplify it:
res = x || y && z;
&& takes precedence, so the expressions are grouped together like so:
res = x || (y && z);
As we can see, && takes priority, so the expressions to it's left and right are grouped together, then || is evalutated. The expression to it's left is x and the expression on it's right is (y && z) (I think we were both thinking that if && took priority, it would be like (a || b) && c so it would be evaluated first, but that's not how it works). If we want to see that this is in fact the case, we can modify the above code like so:
res = expression(a = 8, "One") || expression(a = 16, "Two") && expression(a = 32, "Three");
This is equivalent to false || (false && false), but without any compiler interference with compile-time constants. The result of this is:
One called with 8
Two called with 16
false 16
First, the || is evaluated, then the left side of the &&. This returns false, and false && ? will always be false, so the third expression is not evaluated. But no precedence rules have been violated. I hope this has cleared up any confusion. If not, I'm happy to continue discussion in chat and update my answer. Because we know from the original code that if the first expression is true, the || returns true and short-circuits, we can say that a || b && c is not grouped together into (a || b) && c.
res = a++ == 2 || --a == 2 && --a == 2 (res is true)
1. a++ (post-increment, no) -> a = a + 1 -> it's still 2 -> when true -> it becomes 3
2. --a (pre-increment, right to left) -> a - 1 = a -> 1
3. --a (pre-increment, right to left) -> a - 1 = a -> 0 (its because of logical and, it never execute this part)
4. == (equality, left to right) -> 2 == 2 || 1 == 2 && 0 == 2 -> true || false && false
5. && (logical and, left to right) -> false -> no more steps
6. || (logical or, left to right) -> true -> go to 1.
// so take 3
// moral of the story is always use paranthesis
// op is correct for short-circuit
In the end when(((a++) == 2) || false) [a = 1]
Is done then as the || operator having less precedence than ++ so here a will become 3 .. then it will print a=3
Though it's a short circuit operator still it have to do the ++ operator 1st.
I have a conditional if statement like this
if ((a && (b || c)) ||
(b && (a || c))) {
}
basically what I'm trying to achieve is that I can only have one option true, but two is not ok!
Can it be more simplified, looks redundant to me!
Or should I extract it to a function?
edit
if (a && !b && !c) // process a
if (b && !a && !c) // process b
if (c && !a && !b) // process c
if (!a && !b && c!) // none present exception
else {} // more than one case exception
Yes it can be simpler, this would be more than enough since a && b will give the same result as b && a:
if (a && b || c) {
}
Note: the original question was completely different, and asked to simplify the following expression:
if ((a && b || c) ||
(b && a || c)) {
}
Following the comment and the edit, each line is the development of the previous one:
(a && (b || c)) || (b && (a || c))
((a && b) || (a && c)) || ((a && b) || (b && c))
(a && b) || (a && c) || (a && b) || (b && c)
You have a duplicate, so you can turn it to: (those lines are equals)
(a && b) || (a && c) || (b && c)
(a && (b ||c)) || (b&&c)
&& operator is Commutative so a && b or b && a results in same output.
Now your condition becomes like this
if ((a && b || c) ||
(a && b || c)) {
}
|| operator is Idempotent so x || x results x
your expression becomes (a && b) || c
But in java && and || operators exhibit "short-circuiting" behavior
First operand will be evaluated first and then second operand will be evaluated only if need so you can choose which operand to keep first based on operand complexity.
if (c || (a && b) {
...
}
The 2 large conditions are the same... ´&&` is commutative
I have this expression:
y[i] = ( z[i] == a && b || c )
Which of these elements (&&, ||, ==) have the priority?
Can you please show the order of operations with brackets?
First ==, then &&, then ||.
Your expression will be evaluated as y[i] = (((z[i] == a) && b) || c).
https://docs.oracle.com/javase/tutorial/java/nutsandbolts/operators.html
The priority list:
==
&&
||
The actual expression is evaluated as
y[i] = ( ((z[i] == a) && b) || c )
You probably want to look here for more info on operator precedence. https://docs.oracle.com/javase/tutorial/java/nutsandbolts/operators.html
This would be :
y[i] = ((( (z[i]) == a )&& b) || c)
ref: http://introcs.cs.princeton.edu/java/11precedence/
Here's the full list of ALL OPERATORS:
Full list of operators in Java
Got it from "Java ist auch eine Insel" = "Java is also an island"
boolean a = true
boolean b = true
<random code in here, booleans may or may not change>
if ((!a || !b) || (!a && !b)){
doSomethingElse();
}
This code is not working for me, what is a simple solution to this problem?
To be clear:
The if statement should work:
if at least one of the booleans is false
3 cases:
a = False b = True
a = True b = False
a = False b = False
I could do this in one long if statement, but I was just wondering if there was a simple way to implement this.
This should work for you:
if( !a || !b ) {
doSomething();
}
if(!(a && b)) {
....Then do something
}
(Way too much time, breakdown of logic)
Start by applying De Morgan's to get the ! outside: (Although other boolean algebra could be applied at this stage to skip a few steps, I like to show this.)
That is, given:
(!a || !b) (by DM) -> !(a && b) and
(!a && !b) (by DM) -> !(a || b).
Then (!a || !b) || (!a && !b) (by substituion) -> !(a && b) || !(a || b).
Applying DM again:
!( (a && b) && (a || b) )
Now using "distributivity of ^ over v" (x = a && b; y = a; z = b):
!( ((a && b) && a) || ((a && b) && b) )
And by "associativity" and "communicativity":
!( (a && a && b) || (a && b && b) )
And by "idempotence":
!( (a && b) || (a && b) )
!( (a && b) )
Simplified:
!(a && b)
Back by DM:
!a || !b
Of course, a simple Truth Table may have been easier to show this ..
Your if statement will work just change your if Statement to this:
if (!a || !b) {
}
As you can see above it will work when any one of the boolean is false .
All the Best.
Your proposed solution can be simplified to...
if (!a || !b) { .... }
By checking whether one is false or both are false, you're making sure that both are true, or a && b. The opposite of a && b is !a || !b:
if (!a || !b) {
doSomethingElse();
}
if (!(a && b)) {
doSomethingElse();
}