Simplifying the boolean expression (A && B) || (A && !B && C) - math

I'm so confused currently while trying to simplify a boolean expression. I know the solution but not the correct way to achieve it.
What law makes (A && B) || (A && !B && C) the same as (A && B) || (A && C)
Why can i leave the !B?

Since (in simplified notation):
B+B'C = B+B+B'C = B(C+C')+B(C'+C)+B'C = BC+BC'+BC'+BC+B'C = BC+BC'+BC'+(B+B')C = BC+BC'+1C = B(C+C')+C = B+C
we have
AB + AB'C = A (B + B'C) = A(B+C) = AB + AC

I don't know of any law, but I will try to explain it.
For us to reach the check of !B we must acknowledge two things:
A must be TRUE
B must be FALSE
If A is false we can short-circuit out of both checks (A && B) and (A && !B && C) because A is evaluated first and we are only comparing with &&.
If A is true and B is true, the second condition is not evaluated.
Therefore, to reach !B, A must be true and B must be false as stated above. If that's the case then !B will always evaluate to TRUE in the second condition, and can be removed.

Related

Boolean Algebra help: duals

I consistently keep getting this question wrong, and I cant figure out why
(a+b)(b+c)=ac+b
I put this as the answer:
ab+bc=a+cb
I do not understand why that is wrong
(a || b) && (b || c) = (a && c) || b
It's written in c style (may be better for understanding). It means that if we have b = true the result is true, if b = false the result is depends of a and c in couple. Also we can find result for each tuple of (a, b, c) and for identical tuple we have identical results.

How to eliminate division inside code like "a/b>c/d"?

For example, if I don't want division in "a/b==c/d",I can rewrite it as "ad==bc".
But "a/b>c/d" is not always = "ad>bc", for example:
a=20, b=5, c=9,d=3 : a/b>c/d is true and ad>bc is true
but
a=-20, b=-5, c=9,d=3 : a/b>c/d is true but ad>bc is false
I started to found the patten, it seems (I am not sure if it is right):
if b and d has same sign, a/b>c/d = ad > bc
if b and d has different sign, a/b > c/d = ad < bc
if I rewrite "a/b>c/d" as
(( (b>0 && d>0 || b<0 && d<0) && a*d>b*c) || ( ((b>0 && d<0) || b<0 && d>0) && a*d<b*c)
,it needs type more characters, also I need to type each variable more than 1 time,and this form is very hard to maintain if I want to change to
a/b>=c/d
or
a/b<c/d
Is there any method to eliminate division in a/b>c/d in simpler way?
You can rewrite it as:
a*d*b*d > b*c*b*d
This way if b and d have different signs then b*d will be a negative number and the comparison will be flipped back the correct way. Be careful about overflows however. To make the code equivalent to a/b > c/d you will also need to check if b or d are zeros.
May be you can get the signs of b and d by bitwise operation, and then rewrite "a/b>c/d" as
(((b>>31)&1) ^ ((d>>31)&1)) ^ (ad > bc)
which is equivalent to
((b>0) ^ (d>0)) ^ (ad > bc)
say b and d are 32-bits integers
When you multiply both sides of an inequality by some non-zero number v, then if v is negative you must reverse the direction of the inequality.
So in your case you are multiplying by b*d so
if (a/b > c/d) {
...
}
is equivalent to
v = b * d;
if(v==0) {
error
}
if ( ( (v>0) && (a*d > c*b) ) ||
( (v<0) && (a*d < c*b) ) ) {
...
}
If you don't care whether you're using > or >=, or care about the handling of v==0 you can rewrite this as
if ( (v>0) ^ (a*d > c*b ) ) {
...
}
There's further considerations required if a, b, c and d are floating point numbers as you need to consider the behaviour of positive and negative infinity, signed zeros and "not a number" values.

What does "&&" do?

I can't seem to find the resource I need. What does && do in a code that is comparing variables to determine if they are true? If there is a link with a list of the symbol comparisons that would be greatly appreciated.
example: Expresssion 1: r = !z && (x % 2);
In most programming languages that use &&, it's the boolean "and" operator. For example, the pseudocode if (x && y) means "if x is true and y is true."
In the example you gave, it's not clear what language you're using, but
r = !z && (x % 2);
probably means this:
r = (not z) and (x mod 2)
= (z is not true) and (x mod 2 is true)
= (z is not true) and (x mod 2 is not zero)
= (z is not true) and (x is odd)
In most programming languages, the operator && is the logical AND operator. It connects to boolean expressions and returns true only when both sides are true.
Here is an example:
int var1 = 0;
int var2 = 1;
if (var1 == 0 && var2 == 0) {
// This won't get executed.
} else if (var1 == 0 && var2 == 1) {
// This piece will, however.
}
Although var1 == 0 evaluates to true, var2 is not equals to 0. Therefore, because we are using the && operator, the program won't go inside the first block.
Another operator you will see ofter is || representing the OR. It will evaluate true if at least one of the two statements are true. In the code example from above, using the OR operator would look like this:
int var1 = 0;
int var2 = 1;
if (var1 == 0 || var2 == 0) {
// This will get executed.
}
I hope you now understand what these do and how to use them!
PS: Some languages have the same functionality, but are using other keywords. Python, e.g. has the keyword and instead of &&.
It is the logical AND operator
(&&) returns the boolean value true if both operands are true and returns false otherwise.
boolean a=true;
boolean b=true;
if(a && b){
System.out.println("Both are true"); // Both condition are satisfied
}
Output
Both are true
The exact answer to your question depends on the which language your are coding in. In R, the & operator does the AND operation pairwise over two vectors, as in:
c(T,F,T,F) & c(T,T,F,F)
#> TRUE FALSE FALSE FALSE
whereas the && operator operated only on the first element of each vector, as in:
c(T,F,T,F) && c(T,T,F,F)
#> TRUE
The OR operators (| and ||) behave similarly. Different languages will have different meanings for these operators.
In C && works like a logical and, but it only operates on bool types which are true unless they are 0.
In contrast, & is a bitwise and, which returns the bits that are the same.
Ie. 1 && 2 and 1 && 3 are true.
But 1 & 2 is false and 1 & 3 is true.
Let's imagine the situation:
a = 1
b = 2
if a = 1 && b = 2
return "a is 1 and b is 2"
if a = 1 && b = 3
return "a is 1 and b is 3"
In this situation, because a equals 1 AND b = 2, the top if block would return true and "a is 1 and b is 2" would be printed. However, in the second if block, a = 1, but b does not equal 3, so because only one statement is true, the second result would not be printed. && Is the exact same as just saying and, "if a is 1 and b is 1".

Julia: Dictionary with Tuple keys containing Composite Types

I ran into an issue trying to using a dictionary whose keys are a tuple including a composite type.
Here is a minimal example to replicate my issue:
import Base: hash, isequal
type T
a :: Int
b :: Int
end
function isequal(A::(T,Int), B::(T,Int))
A[1].a == B[1].a && A[1].b == B[1].b && A[2] == B[2]
end
function hash(A::(T,Int))
hash(A[1].a + A[1].b + A[2])
end
d = Dict{(T,Int),Int}()
d[(T(1,1),1)] = 1
d[(T(2,2),2)] = 2
r = (T(2,2),2)
for k in keys(d)
println(isequal(r, k) && hash(r) == hash(k))
end
println(d[r])
Running this results in:
false
true
ERROR: key not found: (T(2,2),2)
So isequal and hash work, but for some reason the dict is not.
Does anyone know what is going on? Thank you.
There is something I don't quite understand in this case about the types of tuples and dispatching, but basically you need to implement the two argument form of hash for this case. The following very similar code works as expected, as a point of comparison, without the two argument form:
type T
a::Int
b::Int
end
function Base.isequal(A::T, B::T)
println("isequal", A, " ", B)
A.a == B.a && A.b == B.b
end
function Base.hash(A::T)
println("hash", A)
hash(A.a + A.b)
end
d = Dict{T,Int}()
d[T(1,1)] = 1
d[T(2,2)] = 2
println("test")
r = T(2,2)
println(d[r])
with output
isequalT(1,1) T(1,1)
hashT(1,1)
isequalT(2,2) T(2,2)
hashT(2,2)
test
hashT(2,2)
isequalT(2,2) T(2,2)
2
The problem can be solved by creating hash & isequal functions for each composite type rather than for the overall tuple.
If you key is (T,Int):
Instead of this:
function isequal(A::(T,Int), B::(T,Int))
A[1].a == B[1].a && A[1].b == B[1].b && A[2] == B[2]
end
function hash(A::(T,Int))
hash(A[1].a + A[1].b + A[2])
end
Do this:
function isequal(A::T, B::T)
A.a == B.a && A.b == B.b
end
function hash(A::T)
hash(A.a + A.b)
end
If you want the original formulation to work, you have to specify Base.hash with the optional second argument: h::Uint64:
function isequal(A::(T,Int), B::(T,Int))
A[1].a == B[1].a && A[1].b == B[1].b && A[2] == B[2]
end
function hash(A::(T,Int))
hash(A[1].a + A[1].b + A[2])
end
function hash(A::(T,Int), h::Uint64)
hash(A[1].a + A[1].b + A[2] + h)
end

Merge conditions in if statement

I have two conditions for if statement. I found that those are different, but I don't know the reason.
1: if ((local != -1) || (fall_back == 1))
2. if ((local != -1) || ((local != -1) && (fall_back == 1)))
Those two are different. But in Math, we have A V (B ^ C) = (A V B) ^ (A V C). If I use this equation and reorganize statement 2, it seems to be the same as 1. Is there anything fundamental I am missing?
How can I simplify statement 2? It doesn't look good.
Short circuit evaluation is done in order to optimize.
So in an expression like (A!=B) || (A!=C), if A!=B turns out to be true the second part A!=C is not evaluated at all, because independent of the second part, the expression will turn out to be true.
Consider
A -> local != -1
B -> fall_back == 1
Your first condition reduces to
A V B
And second statement reduces to
A V (A ^ B) => A ^ (1 V B) => A
So your first statement requires either condition A or B to be true
And second statement tests only if A is true
Consider test case where local = 0 and fall_back = 1
Statement 1 => True as fall_back == 1
Statement 2 => False as local != 0
Hence conditions are not the same
This is Simple, If you Take local != -1 = true and fall_back == 1 = false
Then in Both case result will be true because the value of local != -1 = true
but if take local != -1 = false and fall_back == 1 = true
then in first case result will be true and in second case result will be false.
In Logical OR if the first condition is true means it wont evaluate the second one! But in Logical AND first condition false means it wont evaluate the second one!
if ((local != -1) || (fall_back == 1))
In this if any one of the condition is true, local != -1 or fall_back == 1 it will evaluate the body of the if.
if ((local != -1) || ((local != -1) && (fall_back == 1)))
But here both should be true, Then only it will evaluate the expression. else local != -1 fails means, Both conditions will fails. Because Logical AND(&&) both should be true!
Consider- local != -1 is false and fall_back == 1 is true
if ( false || true ) -> if(0 || 1) -->true
if ( false || (false && true)) -> if(0 || (0 && 1)) -> if(0 || 0) --> false

Resources