Basic identities of logical expressions and deriving logical expressions from truth table? - boolean

I was wondering what a basic identity of a logical expression is and how to get it. I looked on google but couldn't find anything about it.
Say, for example I have a logical expression ~(~(P ^ ~(P ^ Q)) ^ ~(Q ^ ~(P ^ Q)))
Below is the result I got from a truth table and I don't know what to do with it to get a basic identity.
0
1
1
0
As well, as that I have a truth table and I have no idea how to derive a logical expression from it.
P Q R F
0 0 0 0
0 0 1 0
0 1 0 0
0 1 1 0
1 0 0 0
1 0 1 1
1 1 0 1
1 1 1 1

When you have the truth table, creating a DNF formula is trivial. Take a look at where the assignment is true. Then you end you end up with (exclamation mark means negation)
(P & !Q & R) OR (P & Q & !R) OR (P & Q & R).

Related

Combinations of zeros and ones of vector size n [duplicate]

I have an algorith that the number of possibles combinations of 0 and 1, can reach the number 2^39. Let's say i have n=2 situations, or n1=2^2=4 combinations of 0 and 1: 00,01,10,11.From that i can create an array a=zeros(n,n1) and fill the columns with the possible combinations? That means first column has 00,second 01,third 10,last 11.I want this to be dynamic that means that n can be 1,2,3...,39, show the array will be a=zeros(n,2^n).Thanks for any response!
Just for general understanding: why do you think you need an array of all combinations of all integers from 0 to 2³⁹? That array would consume 39×2³⁹/1000⁴ ≈ 21TB of RAM...last time I checked, only the world's most advanced supercomputers have such resources, and most people working with those machines consider generating arrays like this quite wasteful...
Anyway, for completeness, for any N, this is the simplest solution:
P = dec2bin(0:(2^N)-1)-'0'
But, a little piece of advice: dec2bin outputs character arrays. If you want numerical arrays, you can subtract the character '0', however, that gives you an array of doubles according to the rules of MATLAB:
>> P = dec2bin(0:(2^3)-1)-'0';
>> whos P
Name Size Bytes Class Attributes
P 8x3 192 double
If you want to minimize your memory consumption, generate a logical array instead:
>> P = dec2bin(0:(2^3)-1)=='1';
>> whos P
Name Size Bytes Class Attributes
P 8x3 24 logical
If you want to also speed up the execution, use the standard algorithm directly:
%// if you like cryptic one-liners
B1 = rem(floor((0:pow2(N)-1).' * pow2(1-N:0)), 2) == 1;
%// If you like readability
B = false(N,pow2(N));
V = 0:pow2(N)-1;
for ii = 1:N
B(ii,:) = rem(V,2)==1;
V = (V-B(ii,:))/2;
end
That last one (the loop) is fastest of all solutions for any N (at least on R2010b and R2013a), and it has the smallest peak memory (only 1/Nth of the cryptic one-liner).
So I'd go for that one :)
But, that's just me.
Using ndgrid with a comma-separated list as output (see also here):
[c{1:N}] = ndgrid(logical([0 1]));
c = cat(N+1,c{N:-1:1});
c = reshape(c,[],N);
Example: N=4 gives
c =
0 0 0 0
0 0 0 1
0 0 1 0
0 0 1 1
0 1 0 0
0 1 0 1
0 1 1 0
0 1 1 1
1 0 0 0
1 0 0 1
1 0 1 0
1 0 1 1
1 1 0 0
1 1 0 1
1 1 1 0
1 1 1 1

How to convert a matrix from int to bool in Julia like MATLAB's logical()?

If you have an array a of ints in MATLAB you can do logical(a) to get a Boolean array where every nonzero entry is 1 and every 0 entry is 0. How do you do this in Julia?
Another option is to use the iszero function, which gives you a clearer syntax:
julia> a = rand(0:3,2,2)
2×2 Array{Int64,2}:
0 3
0 1
julia> b = iszero.(a)
2×2 BitArray{2}:
1 0
1 0
You can find information about iszero in here or by typing ?iszero at the REPL.
The use of broadcasting is needed because that makes the function compare every element to zero. If you don't use it, it will return only true if all the matrix is zero or false if one element is different than zero.
You can construct this behavior by broadcasting the inequality operator.
julia> x
5×5 Array{Int64,2}:
0 -4107730642120626124 6654664427866713002 7518855061140735034 8818106399735122346
8091546149111269981 4315717857697687985 0 -5798218902015720994 1300970799075893685
-7301322994135835673 -2297242472677021645 -4021288767260950802 7892625078388936975 -1629449791447953082
1060255079487701867 -5212584518144622345 7329251290490888722 1375278257655605061 -4361465961064184585
-469090114465458856 6912712453842322323 -1577327221996471827 -5606008086331742040 1641289265656709209
julia> !=(0).(x)
5×5 BitArray{2}:
0 1 1 1 1
1 1 0 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
The result is a BitArray, the canonical representation of a matrix with boolean values.

Count the first x integers of a group of values

I want to get the count starting from 1, of the number of occurrences of Y until its subsequent value is N. A simple example table can be found below, I've added an additional column called expected output to highlight what I'm trying to achieve.
tab:([]x:`N`N`Y`N`N`Y`Y`Y`N`N`Y`Y`Y;expected_output:0 0 1 0 0 1 2 3 0 0 1 2 3)
I have been playing around with the idea of trying to use cut (granted that I can find the correct indexes) I could split the table up, get the count of each list, then piece it all back together somehow e.g.
0 2 3 5 8 10 cut tab
Approach without scan, not as neat as terry's but should be faster on larger tab.
q)update o:{a+r-maxs differ[x]*r:sums a:`Y=x}x from tab
x expected_output o
-------------------
N 0 0
N 0 0
Y 1 1
N 0 0
N 0 0
Y 1 1
Y 2 2
Y 3 3
N 0 0
N 0 0
Y 1 1
Y 2 2
Y 3 3
One approach using scan
q)update c:0{y*x+y}\x=`Y from tab
x expected_output c
-------------------
N 0 0
N 0 0
Y 1 1
N 0 0
N 0 0
Y 1 1
Y 2 2
Y 3 3
N 0 0
N 0 0
Y 1 1
Y 2 2
Y 3 3
Essentially a modified version of sums which resets the counter back to zero (using zero/false multiplication) whenever the next boolean is zero

Boolean Simplification - Q=A.B.(~B+C)+B.C+B

I've been struggling with boolean simplification in class, and took it to practice some more at home. I found a list of questions, but they don't have any answers or workings. This one I'm stuck on, if you could answer clearly showing each step I'd much appreciate:
Q=A.B.(~B+C)+B.C+B
I tried looking for a calculator to give me the answer and then to work out how to get to that, but I'm lost
(I'm new to this)
Edit: ~B = NOT B
I've never done this, so I'm using this site to help me.
A.B.(B' + C) = A.(B.B' + B.C) = A.(0 + B.C) = A.(B.C)
So the expression is now A.(B.C) + B.C + B.
Not sure about this, but I'm guessing A.(B.C) + (B.C) = (A + 1).(B.C).
This equals A.(B.C).
So the expression is now A.(B.C) + B.
As A.(B + C) = B.(A.C), the expression is now B.(A.C) + B, which equals (B + 1).(A.C) = B.(A.C).
NOTE: This isn't complete yet, so please avoid downvoting as I'm not finished yet (posted this to help the OP understand the first part).
Let's be lazy and use sympy, a Python library for symbolic computation.
>>> from sympy import *
>>> from sympy.logic import simplify_logic
>>> a, b, c = symbols('a, b, c')
>>> expr = a & b & (~b | c) | b & c | b # A.B.(~B+C)+B.C+B
>>> simplify_logic(expr)
b
There are two ways to go about such a formula:
Applying simplifications,
Brute force
Let's look at brute force first. The following is a dense truth table (for a better looking table, look at Wα), enumerating all possible value for a, b and c, alongside the values of the expression.
a b c -- a & b & (~b | c) | b & c | b = Q
0 0 0 0 0 10 1 0 0 0 0 0 = 0
0 0 1 0 0 10 1 1 0 0 1 0 = 0
0 1 0 0 1 01 0 0 1 0 0 1 = 1
0 1 1 0 1 01 1 1 1 1 1 1 = 1
1 0 0 1 0 10 1 0 0 0 0 0 = 0
1 0 1 1 0 10 1 1 0 0 1 0 = 0
1 1 0 1 1 01 1 0 1 0 0 1 = 1
1 1 1 1 1 01 1 1 1 1 1 1 = 1
You can also think of the expression as a tree, which will depend on the precedence rules (e.g. usually AND binds stronger than OR, see also this question on math.se).
So the expression:
a & b & (~b | c) | b & c | b
is a disjunction of three terms:
a & b & (~b | c)
b & c
b
You can try to reason about the individual terms, knowing that only one has to be true (as this is a disjunction).
The last two will be true, if and only if b is true. For the first, this a bit harder to see, but if you look closely: you have now a conjunction (terms concatenated by AND): All of them must be true, for the whole expression to be true, so a and b must be true. Especially b must be true.
In summary: For the whole expression to be true, in all three top-level cases, b must be true (and it will be false, if b is false). So it simplifies to just b.
Explore more on Wolfram Alpha:
https://www.wolframalpha.com/input/?i=a+%26+b+%26+(~b+%7C+c)+%7C+b+%26+c+%7C+b
A.B.(~B+C) + B.C + B = A.B.~B + A.B.C + B.C + B ; Distribution
= A.B.C + B.C + B ; Because B.~B = 0
= B.C + B ; Because A.B.C <= B.C
= B ; Because B.C <= B

Combine two boolean equations to separate a boolean variables from others

I have 2 programs: X and Y.
X has two bitmaps A and C.
X calls Y.
Y has a bitMap B.
The code I need to execute in Y is
if AB == B && BC == C
//do some action Z
I want to combine on A and C using boolean operations such that I can pass a single bitMap to Y. This single bitmap can then do any boolean operation with B to return true / false and accordingly I can decide to do action Z.
There is no way to simplify by combining A and C.
Here is our truth table:
B A C Z
0 0 0 1
0 0 1 0
0 1 0 1
0 1 1 0
1 0 0 0
1 0 1 0
1 1 0 1
1 1 1 1
We can see from the truth table that when B = 0, we have Z = not C; when B = 1, we have Z = A.
Suppose for the sake of contradiction that we have a one-bit function Y = f(A, C) that "summarizes" A and C. We use B to choose whether the summary equals 'not C' versus 'A'. But this is clearly impossible, because a single bit cannot preserve enough information to be able to extract the value 'not C' and also the value 'A'.