We start our investigation of computer hardware with Boolean functions. For this part of the course we will use the hardware convention for Boolean values, 0 = false and 1 = true (instead of the Racket convention of #f and #t). A Boolean function maps n-tuples of Boolean values to Boolean values, where n is a non-negative integer. (An n-tuple of values is an ordered sequence of n values, generally represented with parentheses and commas: (13,7,44) is a 3-tuple (or triple) of values, with first element 13, second element 7, and third element 44.)
Note that the domain of a Boolean function is finite, so we can write down a table containing every possible input and the corresponding value of the function for that input. Four examples of Boolean functions when n = 1.
input | value input | value input | value input | value ------------- ------------- ------------- ------------- 0 | 0 0 | 1 0 | 0 0 | 1 1 | 1 1 | 0 1 | 0 1 | 1
The first function shown above is the identity: it takes input x and returns value x, for x = 0,1. The second function is negation, or NOT -- if the input is 0 (false), the value is 1 (true); if the input is 1 (true), the output is 0 (false). The last two functions "ignore" their inputs: the third one is the constant function 0, and the fourth one is the constant function 1. These are the only possible Boolean functions when n = 1. To see this, note that the table for any such function has 2 lines, one for input 0 and one for input 1.
input | value ------------- 0 | ? 1 | ?
Each of the two question marks can (independently) be replaced by 0 or 1 to get a Boolean function. Two choices for the first question mark times two choices for the second question mark gives four choices overall for Boolean functions when n = 1.
Here are some examples of Boolean functions when n = 2.
input | value input | value input | value input | value ------------- ------------- ------------- ------------- 0 0 | 0 0 0 | 0 0 0 | 0 0 0 | 1 0 1 | 0 0 1 | 1 0 1 | 1 0 1 | 1 1 0 | 0 1 0 | 1 1 0 | 1 1 0 | 0 1 1 | 1 1 1 | 1 1 1 | 0 1 1 | 1
(Note that I have written "0 1" instead of the 2-tuple (0,1).) The first function above is AND -- it is only 1 (true) when both of its inputs are 1 (true), and 0 (false) otherwise. The second function above is (inclusive) OR -- it is only 0 (false) when both of its inputs are 0, and 1 (true) otherwise. The third function is something called Exclusive OR, whose abbreviation is XOR -- it is 1 (true) if and only if exactly one of its arguments is 1 (true). Note that it differs from (inclusive) OR on the last line, when both arguments are 1 (true). In this case, inclusive OR is 1 but Exclusive OR is 0. We will use OR to mean (inclusive) OR, and use XOR when we mean Exclusive OR.
Milk or sugar? is an example of inclusive OR.
Coffee or tea? is an example of exclusive OR.
The fourth function is one that logicians like; it is IMPLICATION, where the intuitive meaning is "if the first argument is true then the second argument is true." After long debate mathematical logicians agreed on this Boolean function as a good meaning for implication, though the first two lines of the table are a bit counterintuitive. This table represents the meaning intended by a mathematician who says "If p then q."
Another useful Boolean function of two arguments is equivalence, given by the following table.
input | value ------------- 0 0 | 1 0 1 | 0 1 0 | 0 1 1 | 1
This function is 1 if and only if its two arguments are equal (both 0 or both 1).
How many total Boolean functions for n = 2? There are clearly four lines in the table, and on each line we can make a choice of 0 or 1 for the value of the Boolean function, so there are $2*2*2*2 = 2^4 = 16$ possible Boolean functions when n = 2. We've shown 5 of them above; there are 11 others, including the constant function 0 and the constant function 1, whose tables are:
input | value input | value ------------- ------------- 0 0 | 0 0 0 | 1 0 1 | 0 0 1 | 1 1 0 | 0 1 0 | 1 1 1 | 0 1 1 | 1
Note that these (technically) are different functions from the constant functions 0 and 1 for n = 1, because their domains are different (one has 4 elements, the other has 2 elements.)
An example of a Boolean function for n = 3.
input | value --------------- 0 0 0 | 0 0 0 1 | 0 0 1 0 | 0 0 1 1 | 1 1 0 0 | 0 1 0 1 | 1 1 1 0 | 1 1 1 1 | 1
Note that this function is 1 if and only if at least two of its arguments are 1. Thus, it computes a "majority vote" of its inputs. How many Boolean functions are there for n = 3? Clearly, there are $2*2*2 = 2^3 = 8$ lines in the table, and for each of these 8 lines we may independently choose a 0 or a 1 to enter for the value. Thus, there are $2*2*2*2*2*2*2*2 = 2^8 = 256$ Boolean functions when $n = 3$.
For a general non-negative integer n, how many Boolean functions are there? There are n arguments, each of which can be 0 or 1, so there are $2^n$ lines in the table for such a function. On each of those lines, we may (independently) enter a 0 or a 1 as the value, for a total of $2^{2^n}$ possible Boolean functions of n arguments. Check for $n = 3$: we get $2^n = 2^3 = 8$ lines, and $2^{2^3} = 2^8 = 256$ functions.
Here is a table of some values of this function
n | 22n ---------------- 0 | 2 1 | 4 2 | 16 3 | 256 4 | 65,536 (= 216)
Note that each line is the square of its predecessor, so that this sequence can be described by the recurrence:
A0 = 2 A(n+1) = (An)2 for n >= 0You may want to convince yourself of that algebraically. Note that by convention,exponentiation associates to the right, and in general $(a^b)^c$ is not equal to $a^{b^c}$. For example, $(2^2)^3 = 4^3 = 64$, whereas $2^{(2^3)} = 2^8 = 256$.
We first introduce the syntax of a notation for representing Boolean functions. The definition we give is inductive (or recursive). We assume a countable supply of variable symbols, for example, x, y, z, x1, y1, z1, x2, y2, z2, ... . The definition:
(Base cases) 0 is a Boolean expression 1 is a Boolean expression x is a Boolean expression, for any variable x (Inductive cases) If E1 and E2 are Boolean expressions, then so are: (E1)' ;[not E1] (E1 * E2) ;[E1 AND E2] (E1 + E2) ;[E1 OR E2]
(Note that in the above I've used the asterisk (*) instead of the centered dot that I've used on the blackboard.) As is customary with these inductive definitions, we agree that the only Boolean expressions are those that can be obtained in a finite number of steps using the rules above. As examples of Boolean expressions, we have:
0 is a Boolean expression (base case) 1 is a Boolean expression (base case) x is a Boolean expression (base case) y is a Boolean expression (base case) (0)' is a Boolean expression (from 0 and inductive case) (x * 1) is a Boolean expression (from x and 1 and inductive case) ((0)' + (x * 1)) is a Boolean expression (from (0)' and (x * 1) ...
There are a variety of other notations for the operations ', *, +, but these will be our conventions in this part of the course.
The syntactic definition just given requires a lot of parentheses,
which are not so congenial for humans.
We will use an order of operations convention for these
operations: parentheses, ', *, +.
This agrees with the
PEMDAS (or BEDMAS or BODMAS) mnemonic, if we note
that ' looks like exponentiation, * looks like multiplication,
and + looks like addition.
Hence we can interpret the expression (x' + y)'
as (fully parenthesized):
(((x)' + y))'
.
We have a syntax, recursively defined, but we'd like to know what these expressions mean or denote. We start from the truth tables that many of you have previously encountered. To construct a truth table for the expression $(x' + y)'$ we proceed as follows. There are two variables, x and y, so we have two columns labeled by x and y. We have a row in the table for each possible way to assign 0 or 1 to the variables x and y, thus:
x y | --------------- 0 0 | 0 1 | 1 0 | 1 1 |
Now we look at the most deeply-nested subexpressions of our expression (the ones we'd have to construct first using our inductive definition of the syntax.) In this case, we need $x'$ So we label a column of the table with $x'$ and proceed to fill in values for it by applying NOT to the value of $x$ on that line:
x y | x' --------------- 0 0 | 1 0 1 | 1 1 0 | 0 1 1 | 0
Now we take the next expression: $(x' + y)$, and label a column with this expression, and enter values for it on each line by combining the value of $x'$ for that line with the value of $y$ for that line using the OR operation:
x y | x' (x' + y) ---------------------- 0 0 | 1 1 0 1 | 1 1 1 0 | 0 0 1 1 | 0 1
Note that this shows that the value of $(x' + y)$ is 0 if and only if $x = 1$ and $y = 0$. Finally, to get the value of the top-level expression $(x' + y)'$, we label another column of the table with this expression and enter values for it on each line by applying NOT to the value of $(x' + y)$ on that line:
x y | x' (x' + y) (x' + y)' --------------------------------- 0 0 | 1 1 0 0 1 | 1 1 0 1 0 | 0 0 1 1 1 | 0 1 0
Note that the value of $(x' + y)'$ is 1 if and only if $x = 1$ and $y = 0$. Also, this expression is not symmetric in x and y. If our expression had involved the * symbol, then we would have used the AND function to combine the values of the two expressions on each line.
To relate this truth-table procedure to a slightly different formal treatment, we can view a Boolean expression as representing a map from environments to Boolean values. What is an environment? It is a map from variables to Boolean values, assigning a 0 or 1 to each variable. (In fact, we only need values for the variables that appear in the expression.) If we are only concerned with the values of the variables x and y, then there are four possibilities for environments: $x = 0$ and $y = 0$, or $x = 0$ and $y = 1$, or $x = 1$ and $y = 0$, or $x = 1$ and $y = 1$. Note that these correspond to the values in the columns labeled x and y in the four lines of the truth table above. What is shown in the other three columns, respectively, are the values taken by the expressions $x'$, $(x' + y)$ and $(x' + y)'$ in those four environments. We'll see a recursive view of the process of determining the value of a Boolean expression in an environment in the next lecture.
If you have $n$ variables, the number of possible environments is $2^n$.
It is similar to the power-set
calculation you did in hw1.
In hw4, you are asked to write a procedure all-combs
, which generates all possible Boolean environments for a given number of variables. Here are
some examples.
"hw4_rkt.zo"> (all-combs 0) '(()) "hw4_rkt.zo"> (all-combs 1) '((0) (1)) "hw4_rkt.zo"> (all-combs 2) '((0 0) (0 1) (1 0) (1 1)) "hw4_rkt.zo"> (all-combs 3) '((0 0 0) (0 0 1) (0 1 0) (0 1 1) (1 0 0) (1 0 1) (1 1 0) (1 1 1)) "hw4_rkt.zo"> (all-combs 4) '((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))
These environments will form the respective rows of a truth table.
See also: Sum-of-products algorithm.
Recall that an environment is an assignment of Boolean values (0 or 1) to the variables. For example, for the expression $(x' + y)'$ we might consider the environment $x = 0$ and $y = 1$. In the previous lecture we saw a construction of the truth table for the expression $(x' + y)'$ as follows.
x y | x' (x' + y) (x' + y)' --------------------------------- 0 0 | 1 1 0 0 1 | 1 1 0 1 0 | 0 0 1 1 1 | 0 1 0
The environment $x = 0$ and $y = 1$ corresponds to the second line of this truth table, where $x$ and $y$ have these values. The other columns of the second line show the values taken on by the expressions $x'$, $(x' + y)$, and $(x' + y)'$ in this environment. A recursive definition of the value of a Boolean expression in an environment follows the form of the recursive definition of the syntax of a Boolean expression, as follows.
If $E$ is a Boolean expression and $env$ is an environment, then the value of $E$ in $env$ is defined as follows:
Base cases
- If $E = 0$, then the value of $E$ is $0$ in any environment
- If $E = 1$, then the value of $E$ is $1$ in any environment
- If $E = x$ (a variable), then the value of $E$ is the value that $env$ assigns to $x$
Recursive cases
- If $E = (E1)'$, then the value of $E$ in $env$ is the NOT of the value of $E1$ in $env$
- If $E = (E1 * E2)$, then the value of $E$ in $env$ is the AND of the value of $E1$ in $env$ and the value of $E2$ in $env$
- If $E = (E1 + E2)$, then the value of $E$ in $env$ is the OR of the value of $E1$ in $env$ and the value of $E2$ in $env$
We can apply this definition to the expression $E = (x' + y)'$ and the environment $x = 0$ and $y = 1$, and we get a tree of recursive applications of the definition as follows.
value of (x' + y)' (=> 0) / | NOT value of (x' + y) (=> 1) / | \ OR value of x' value of y (=> 1) (=> 1) / | NOT value of x ( => 0)
Note that the leaves are the base cases $x$ and $y$, whose values are determined by the environment ($x = 0$ and $y = 1$), and as the values are returned back up the tree, the values for the sub-expressions $x'$ and $(x' + y)$ are also found, corresponding to the "auxiliary" columns in the truth table. You'll be asked to implement this definition as a recursive procedure in the homework.
How expressive are Boolean expressions? What class of Boolean functions can be expressed by Boolean expressions? The answer is: EVERY Boolean function can be expressed by a Boolean expression. We'll show this by means of the sum of products algorithm that can take an arbitrary truth table and produce a Boolean expression for that truth table.
We start with a truth table for an arbitrary Boolean function, for example the following one, where we've given the 3 arguments the names $x$, $y$ and $z$. (This is not so arbitrary -- we saw that it is the "majority vote" function, but the same procedure works on an arbitrary function.)
x y z | f(x,y,z) ----------------- 0 0 0 | 0 0 0 1 | 0 0 1 0 | 0 0 1 1 | 1 1 0 0 | 0 1 0 1 | 1 1 1 0 | 1 1 1 1 | 1
Can we write down a Boolean expression with this truth table? The answer is yes, and one method is the sum-of-products algorithm. If we look at the first 1 in the table above, we see that it corresponds to the environment where $x = 0$, $y = 1$, and $z = 1$. The expression $(x' * y * z)$ has the property that it is $1$ in this environment, and $0$ in all the other environments in the table. That is, it has the truth table:
x y z | (x' * y * z) --------------------------- 0 0 0 | 0 0 0 1 | 0 0 1 0 | 0 0 1 1 | 1 1 0 0 | 0 1 0 1 | 0 1 1 0 | 0 1 1 1 | 0
Note, for example that when $x = 1$, $y = 0$, and $z = 1$, $x' = 0$, so the AND of $x'$, $y$, and $z$ is $0$. For each of the other $1$'s in the truth table of $f$ we can find an expression that is $1$ on that line of the truth table and $0$ elsewhere. For example, for the environment $x = 1$, $y = 0$, $z = 1$, we get such an expression by conjoining $x$, $y'$, and $z$. (Note that we take the variable if its value is $1$, and the NOT of the variable if its value is $0$.)
x y z | (x * y' * z) --------------------------- 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 | 0 1 1 1 | 0
Similarly, for the other two $1$'s in the table, we get the expressions $(x * y * z')$ and $(x * y * z)$. Putting all four of these expressions in a truth table, together with the expression gotten by OR'ing all of them together, we get:
x y z | (x'*y*z) (x*y'*z) (x*y*z') (x*y*z) (x'*y*z)+(x*y'*z)+(x*y*z')+(x*y*z)
===================================================================================== 0 0 0 | 0 0 0 0 0 0 0 1 | 0 0 0 0 0 0 1 0 | 0 0 0 0 0 0 1 1 | 1 0 0 0 1 1 0 0 | 0 0 0 0 0 1 0 1 | 0 1 0 0 1 1 1 0 | 0 0 1 0 1 1 1 1 | 0 0 0 1 1
Note that the final expression, $(x'*y*z) + (x*y'*z) + (x*y*z') + (x*y*z)$, has the truth table of $f$ as specified above.
The sum of products algorithm takes any truth table for a Boolean function and returns a Boolean expression with that truth table. We may re-state the algorithm in general terms as follows.
The Sum of Products Algorithm
- Input: a truth table
- Output: a Boolean expression with that truth table
If all of the rows of the truth table have value $0$, output the Boolean expression: $0$.
Otherwise, for each row with the value $1$, construct a term (product) by AND'ing together all the variables that are 1 in that row and the negations of all the variables that are 0 in that row.
Output the Boolean expression gotten by OR'ing together all the terms (products) constructed for rows with value 1.
The term sum of products refers to the fact that the main connectors are ORs ("sums") and the minor connectors are ANDs ("products"). (There is a dual product-of-sums algorithm -- it might be interesting to derive it.)
Thus, all Boolean functions may be expressed by Boolean expressions. This also shows that the operations of NOT, AND, and OR are a "complete basis" for the Boolean functions -- every Boolean function can be represented by an expression using only NOT, AND, and OR.
The sum of products algorithm in general does not return the most concise possible expression for a given truth table. Consider the truth table for the expression $(x*y + x*z + y*z)$, as follows.
x y z | (x*y + x*z + y*z) ------------------------------ 0 0 0 | 0 0 0 1 | 0 0 1 0 | 0 0 1 1 | 1 1 0 0 | 0 1 0 1 | 1 1 1 0 | 1 1 1 1 | 1
This expression also has the desired truth table for $f(x,y,z)$, and is much more concise than the expression that the sum of products algorithm found.
In general, we may define a notion of (semantic) equivalence of two Boolean expressions as follows.
Two Boolean expressions $E1$ and $E2$ are equivalent if for every environment $env$ that assigns values to all of the variables that occur in either $E1$ or $E2$, the value of $E1$ in $env$ is equal to the value of $E2$ in $env$.
Note that we need to consider environments that give values to all of the variables that occur in either expression. (The notation for the equivalence of two Boolean expressions is an "equal sign" with 3 horizontal bars, which we'll render as ≡) Thus, we've seen the equivalence of the following two Boolean expressions.
$$(x*y*z' + x*y'*z + x'*y*z + x*y*z) \equiv (x*y + x*z + y*z)$$Question: is there an algorithm that inputs a Boolean expression $E1$ and outputs a most concise Boolean expression $E2$ equivalent to $E1$? (We can define the size of a Boolean expression as the number of occurrences of symbols needed to write it down; then a most concise expression is one that has the smallest possible size.)
See the notes Sum-of-products algorithm for the truth table for the alarm signal ($a$) as a function of sensors for key in ignition ($k$), door closed ($d$) and seat belt fastened ($b$), and two Boolean expressions for a in terms of $k$, $d$, and $b$, one derived informally and one derived using the sum-of-products algorithm.
Three useful Boolean functions of 2 variables are XOR, implication (⇒), and equivalence (⇔), whose truth tables are as follows.
x y | (x XOR y) x y | (x ⇒ y) x y | (x ⇔ y) ------------------ ----------------- ------------------ 0 0 | 0 0 0 | 1 0 0 | 1 0 1 | 1 0 1 | 1 0 1 | 0 1 0 | 1 1 0 | 0 1 0 | 0 1 1 | 0 1 1 | 1 1 1 | 1
Each of these can be expressed in terms of AND, OR and NOT, using the sum of products algorithm as follows.
(x XOR y) = x'*y + x*y' (x ⇒ y) = x'*y' + x'*y + x*y (x ⇔ y) = x'*y' + x*y
Note that equivalence is true when $x$ and $y$ are equal, and XOR is true when $x$ and $y$ are unequal, so that each is the negation of the other. Another expression for $(x \implies y)$ is $(x' + y)$, as verified by the following truth table.
x y | (x' + y) ----------------- 0 0 | 1 0 1 | 1 1 0 | 0 1 1 | 1
We say that two Boolean expressions $E1$ and $E2$ are equivalent, which we'll denote by $E1 \equiv E2$ in these notes, if for every environment $env$ that assigns values to all the variables in either $E1$ or $E2$, we have the value of $E1$ in $env$ is the same as the value of $E2$ in $env$. In terms of truth tables, if we make a combined truth table with all the variables in either expression, the column of values for $E1$ is the same as the column of values for $E2$.
A set of axioms for the equivalence of Boolean expressions is available here: Boolean axioms. Each axiom expresses an equivalence between two Boolean expressions. For example, axiom (A10) is the following.
$$a + (b * c) \equiv (a + b) * (a + c)$$
This is the property that in Boolean algebra, OR distributes over AND. To verify the equivalence of the two sides, we consider the following truth table.
a b c | a + (b * c) (a + b) * (a + c) -------------------------------------------- 0 0 0 | 0 0 0 0 1 | 0 0 0 1 0 | 0 0 0 1 1 | 1 1 1 0 0 | 1 1 1 0 1 | 1 1 1 1 0 | 1 1 1 1 1 | 1 1
Because the columns giving the values of the two expressions are equal, the expressions are equivalent.
These axioms have the property that consistently substituting an expression for each of the variables on both sides of the axiom gives another equivalent pair of expressions. So, if we take axiom (A7), which is
$$a * (a + b) \equiv a$$and substitute $(x' + y)$ for $a$ and $z'$ for $b$ on both sides, we get the equivalence
$$(x' + y) * ((x' + y) + z') \equiv (x' + y)$$Moreover, if we have an equivalence $E1 \equiv E2$ and another expression $E3$ that contains one or more sub-expressions equal to $E1$, then we can replace one or more of the sub-expressions $E1$ in $E3$ by $E2$ and get a new expression equivalent to $E3$. Thus, from axiom (A13) we have the equivalence
$$1 * a \equiv a$$and as a substitution instance of (A16) we have
$$x + x' \equiv 1$$and we may substitute (x + x') for 1 in the previous equivalence to get
$$(x + x') * a \equiv a$$These axioms and rules of inference give a system that is sound (every equivalence derivable using the rules is in fact true) and complete (every true equivalence between Boolean expressions is in fact derivable.) The axioms are in fact redundant; as an example, we'll derive (A8) from the other axioms using the rules of inference. The axiom (A8) is one of the absorption laws, namely,
$$a + (a * b) \equiv a$$One way to derive it is to start with $a + (a * b)$ and use (A10) to get
$$a + (a * b) \equiv (a + a) * (a + b)$$Using (A2), $(a + a) \equiv a$, so we have
$$a + (a * b) \equiv a * (a + b)$$Then using (A7) (the other absorption law), $a * (a + b) \equiv a$, so
$$a + (a * b) \equiv a$$Here are three very useful equivalences that are not among the axioms.
$$(a + b)' \equiv a' * b'$$$$(a * b)' \equiv a' + b'$$$$(a')' \equiv a$$The first two are called DeMorgan's laws, after the logician Augustus DeMorgan (who tutored Ada Lovelace in mathematics, after whom the Ada programming language was named.) The third is the law of double negation. These equivalences are easily verified using truth tables, but are somewhat challenging to derive using the given axioms and inference rules.
Note that the axioms on the list come in dual pairs. That is, if we replace $+$ by $*$, replace $*$ by $+$, replace $0$ by $1$ and replace $1$ by $0$, we will find a dual for every axiom on the list. For example, the dual of (A11), $0 * a \equiv 0$ is (A14), $a + 1 \equiv 1$. This means that if we take any equivalence $E1 \equiv E2$ and apply the dual operation to the two sides to get $D1$ and $D2$, then the equivalence $D1 \equiv D2$ is also true.
We considered the question: is there an algorithm that takes as input a Boolean expression $E1$ and outputs a Boolean expression $E2$ equivalent to $E1$ such that $E2$ has the smallest size among all Boolean expressions equivalent to E1? (Where we define size as the number of symbols to write down the expression, for example.)