How to understand De Morgan Laws Boolean Expression - boolean-logic

I got screwed when trying to understand this expression. I've thought several times but I cant get the meaning.
! (p || q) is equivalent to !p && !q
For this one, somehow I can comprehend a little bit.
My understanding is " Not (p q) = not p and not q" which is understandable
! (p && q) is equivalent to !p || !q
For the second, I'm totally got screwed. How come
My understanding is " Not (p q) = Not p or Not q " . How come and and or can be equivalent each other? as for the rule in the truth table between && and || is different.
That's how I comprehend each expression, perhaps I have the wrong method in understand the expression. Could you tell me how to understand those expressions?

You can use a Truth table to see how the two expressions are equal. Like This:
!(P || Q) = !P && !Q
_________________________________________________
P Q P || Q !(P||Q) !P !Q !P && !Q
_________________________________________________
1 1 1 0 0 0 0
1 0 1 0 0 1 0
0 1 1 0 1 0 0
0 0 0 1 1 1 1
_________________________________________________
Note that the column labeled !(P||Q) is the same as the column labeled !P && !Q. You can work this from the left most column where we set the initial values for P and Q. Then work out each column towards the right.
!(P && Q) = !P || !Q
_________________________________________________
P Q P && Q !(P&&Q) !P !Q !P && !Q
_________________________________________________
1 1 1 0 0 0 0
1 0 0 1 0 1 1
0 1 0 1 1 0 1
0 0 0 1 1 1 1
_________________________________________________

Think of it in terms of the Red Toyota.
Let p = "The car is red"
Let q = "The car is a Toyota"
! ( p && q ) means "The car is not a red Toyota"
Which is the same as saying:
!p || !q "it's not red, or (inclusive) it's not a Toyota" , right?

Related

Create a dvar boolean Constraint

I am using OPL CPLEX 12.9
I have problems with the formulation of the following constraint:
K[i][t] is a dvar boolean and t is the Index for time.
If K[i][t] == 0 it should be zero for two hours, before it goes 1 again.
I would like to achieve for example the following result
K[i][t] = [0 0 1 0 0 1 1 1 0 0 0 ]
I already tried:
range T = t_min..t_max;
range T1 = t_min-1 ..t_max+1;
dvar boolean K[I][T1];
forall ( i in I, t in T){
ct:
(K[i][t-1]==0) => (K[i][t]== 0) => (K[i][t+1]==1 || K[i][t+1]==0) &&
(K[i][t-1]==1) => (K[i][t]==1 || K[i][t]==0);
But in the results, these side conditions are ignored. I get the result like
K[i][t] = [0 0 1 0 1 1 0 0 1 1 0 ]
I think your condition reads "if K[i][t] is 0 then either K[i][t-1] or K[i][t+1] must be zero as well". So you need
forall (i in ...) {
(K[i][t_min] == 0) => (K[i][t_min+1] == 0);
(K[i][t_max] == 0) => (K[i][t_max-1] == 0);
forall(t in t_min+1..t_max-1)
(K[i][t] == 0) => ((K[i][t-1] == 0) || (K[i][t+1] == 0));
}

Julia (Julia-lang) conditional in function chaining

I'm trying to sum all numbers from 1 to 1000 that are either divisible by 3 or 5.
The first attempt is straight forward:
ans1 = 0
for x in 3:999
ans1 += x % 3 == 0 || x % 5 == 0 ? x : 0
end
When I try the same approach using function chaining, it fails to return the answer I expect, it instead returns 0.
ans2 = [3:999] |> x -> x % 3 == 0 || x % 5 == 0 ? x : 0 |> sum
I believe the problem is the center function, since the code below prints all values within the range of 3 to 999. So i know there is no problem with iteration.
[3:999] |> x -> println(x)
Could anyone please help me.
I discovered the reason was because I did not understand the type being parsed. Here is an example:
[3:999] |> println(typeof(x)) # Array{Int64,1}
Meaning the value being parsed is an array of integer64. So evaluating the following:
[1:999] % 3 == 0 # false
So my answer was to instead use the filter function, here is an example:
ans3 = sum(filter(x -> x % 3 == 0 || x % 5 == 0,[1:999]))
The final answer using function chaining is:
ans4 = [1:999] |> x -> filter(y -> y % 3 == 0 || y % 5 == 0,x) |> sum
Which evaluates to the expected answer.

Why exactly the output of this expression return true

I have this expression:
!(1 && !(0 || 1))
The output returns 1 true. And that's ok. When I read the expression I came to the same conclusion before checking the output. But I would really appreciate if someone can explain to me why the returning value is true, that way, I will have a better understanding of boolean logic and how to implement better evaluators in my code.
Key observation here: ! is not, && is the "And" operator, and || is the "Inclusive Or" Operator.
What are you really asking when you say "why it's true?".
0 = false
1 = true
AND && table
0 0 -> 0
0 1 -> 0
1 0 -> 0
1 1 -> 1
OR || table
0 0 -> 0
0 1 -> 1
1 0 -> 1
1 1 -> 1
NOT ! table
0 -> 1
1 -> 0
With parentheses implying "do this first", the statement reduces using the tables above:
!(1 && !(0 || 1))
!(1 && !1)
!(1 && 0)
!0
1
But I don't know "why" it's true. Because that's what an AND operation is, what an OR operation is, and what a NOT operation is, and how reducing a statement works. With those definitions, it can't be another answer, so it's that answer. But you already know that, because you did it yourself and got the same answer ... so what does the question mean?
The innermost expression (0 || 1) is always true.
So !(0 || 1) is always false.
That leaves 1 && 0, which is always false.
So !(false) is always true.
Please forgive my freely intermixing 0/false and 1/true.
The human evaluator (:-).
Working through the expression, following order of operation:
!(1 && !(0 || 1))
= !(1 && !(1))
= !(1 && 0)
= !(0)
= 1
Step by step explanation:
1 = true
0 = false
Starting point: !(1 && !(0 || 1))
Lets start with the inner most expression: !(0 || 1)
Var1 || Var2 =
Var1 or Var2 =
If Var1 or Var2 is 1 or both are 1, the result is 1.
(0 || 1) = 0 or 1 -> the second variable is 1 so the expression is 1.
Insert the result (0 || 1) = 1 into Startingpoint: !(1 && !(1))
! = not (inverts the value of what is behinde)
!1 = 0
!0 = 1
!(0 || 1) = !(1) = 0
Insert the result !(1) = 0 into Startingpoint: !(1 && 0)
So we have !(1 && 0)
Var1 && Var2 = And =
the opossite of or =
If Var1 AND Var2 are both 1, the result is 1. Else it is 0 =
If Var1 or Var2 is 0, the result is zero
1 && 1 = 1
1 && 0 = 0
everything else: 0
So this is left: !(0)
Reminder: ! = not = inverts the expression behind it. So !0 = 1 (and !1 = 0)
This is 1. Or in your case: true
A good book for Beginner C programmers and people who want to learn about programming and logic in an easy, understandable way:
C for Dummies by Dan Godkins
!(1 && !(0 || 1))
Since, you have used parenthesis, evaluation takes place according to them.
First, evaluate innermost parenthesis.
0 || 1 => always true.
!(0 || 1) => !(true) => always false.
1 && !(0 || 1) => 1 && false => always false.
!(1 && !(0 || 1)) => !false => always true.

How to convert a 3 input AND gate into a NOR gate?

I know that I can say convert a 2-input AND gate into a NOR gate by simply inverting the two inputs because of DeMorgan's Theorem.
But how would you do the equivalent on a 3-input AND gate?
Say...
____
A___| \
B___| )___
C___|____ /
I'm trying to understand this because my homework asks me to take a circuit and convert it using NOR synthesis to only use nor gates, and I know how to do it with 2 input gates, but the gate with 3 inputs is throwing me for a spin.
DeMorgan's theorem for 2-input AND would produce:
AB
(AB)''
(A' + B')'
So, yes, the inputs are inverted and fed into a NOR gate.
DeMorgan's theorem for 3-input AND would similarly produce:
ABC
(ABC)''
(A' + B' + C')'
Which is, again, inputs inverted and fed into a (3-input) NOR gate:
___
A--O\ \
B--O ) )O---
C--O/___ /
#SailorChibi has truth tables that show equivalence.
If i haven't made any mistakes it is pretty much the same, invert all 3 of the inputs and you get a NOR
Table:
AND with inverted in is exact the same as
1 1 1 = 1
1 1 1 = 0
1 0 1 = 0
0 1 0 = 0
0 1 1 = 0
0 1 0 = 0
0 0 1 = 0
0 0 0 = 0
NOR with original input
0 0 0 = 1
0 0 1 = 0
0 1 0 = 0
1 0 1 = 0
1 0 0 = 0
1 0 1 = 0
1 1 0 = 0
1 1 1 = 0

boolean logic Are both boolean logic equal

A && B || C && D
(A && B) || (C && D)
Are both boolean logic equal in C++? I am confused.
Whether or not they're equal depends entirely on how you define your operator precedence. If && takes precedence over ||, then yes. Otherwise, no.
In the most programming languages you'll find that operator && is of higher priority than ||.
So for example in Java, C#, C, C++, Python, Ruby, etc.
A && B || C && D
is equivalent to
(A && B) || (C && D)
You can even copy-paste the code:
#include <iostream>
using namespace std;
int main() {
bool A = false;
bool B = false;
bool C = true;
bool D = true;
for(int i = 0; i < 2; ++i) {
A = (i == 0);
for(int j = 0; j < 2; ++j) {
B = (j == 0);
for(int k = 0; k < 2; ++k) {
C = (k == 0);
for(int l = 0; l < 2; ++l) {
D = (l == 0);
cout << A << " " << B << " " << C << " " << D << " -> ";
cout << ((A && B || C && D) == ((A && B) || (C && D))) << endl;
}
}
}
}
return 0;
}
to Ideone to find out for yourself. In C++ for example the output is:
1 1 1 1 -> 1
1 1 1 0 -> 1
1 1 0 1 -> 1
1 1 0 0 -> 1
1 0 1 1 -> 1
1 0 1 0 -> 1
1 0 0 1 -> 1
1 0 0 0 -> 1
0 1 1 1 -> 1
0 1 1 0 -> 1
0 1 0 1 -> 1
0 1 0 0 -> 1
0 0 1 1 -> 1
0 0 1 0 -> 1
0 0 0 1 -> 1
0 0 0 0 -> 1
So the ((A && B || C && D) == ((A && B) || (C && D))) is a tautology.
While the final answer goes to the specifics of the C++ language you're asking about, here's some food for thought on why (and possibly how) to remember:
Conjunction (AND, &&) is often associated with multiplication, while disjunction (OR, ||) is often associated with addition (and we generally know the precedence of multiplication over addition).
Here's a quote from http://www.ocf.berkeley.edu/~fricke/projects/quinto/dnf.html:
... As a practical matter, we usually associate conjunction with
multiplication and disjunction with addition. Indeed, if we identify
true with 1 and false with 0, then {0,1} coupled with the usual
definitions of addition and multiplication over the Galois field of
size 2 (eg, arithmetic modulo 2), then addition (+) and disjunction
(or) really are the same, as are multiplication and conjunction (and).
...
Speaking in rather general terms, the computer languages tend to honor the precedence of multiplicative operators over additive operators.
(Further, these associations, e.g. between operators in logic and in algebra reoccur in other areas, such as type systems. For an interesting exposition of that, see http://blog.lab49.com/archives/3011 on the notion of Algebraic Type Systems.)