The 9th Dedekind number was recently computed. What is a Dedekind number and why was it a big deal to compute just the 9th one of them?
We need to define a couple terms before we can define Dedekind numbers.
A Boolean function is a function whose inputs are 0’s and 1’s and whose output is 0 or 1.
A function f is monotone if increasing the input cannot decrease the output:
x ≤ y ⇒ f(x) ≤ f(y).
Obviously a monotone Boolean function is a Boolean function that is monotone, but monotone with respect to what order? How are we to define when x ≤ y when x and y are sequences of bits?
There are numerous ways one might order the inputs, but the conventional order [1] in this context is to say x ≤ y if every bit in x is less than or equal to the corresponding bit in y. So if the ith bit of x is a 1, then the ith bit of y must be a 1.
A Boolean function is monotone if and only if flipping an input bit from 0 to 1 cannot change the output from 1 to 0.
Enumerating monotone Boolean functions
The nth Dedekind number M(n) is the number of monotone Boolean functions of n variables. We’ll enumerate a few of these. Let a, b, c and d be Boolean variables and denote AND by ∧ and OR by ∨. As usual, we assume ∧ is higher precedence than ∨ so that, for example,
x ∨ y ∧ z
means
x ∨ (y ∧ z).
One variable
There are three monotone functions of one variable a: always return 0, always return a, and always return 1.
- 0
- a
- 1
The only Boolean function of one variable that isn’t monotone is the function that flips a, i.e. f(a) = ¬a.
Two variables
There are six monotone Boolean functions with two variables:
- 0
- a
- b
- a ∧ b
- a ∨ b
- 1
and so M(2) = 6.
We can verify that the six functions above are monotone with the following Python code.
from itertools import product f = [None]*6 f[0] = lambda a, b: 0 f[1] = lambda a, b: a f[2] = lambda a, b: b f[3] = lambda a, b: a | b f[4] = lambda a, b: a & b f[5] = lambda a, b: 1 for i in range(6): for (a, b) in product((0,1), repeat=2): for (x, y) in product((0,1), repeat=2): if a <= x and b <= y: assert(f[i](a, b) <= f[i](x, y))
Three variables
There are 20 monotone Boolean functions of three variables:
- 0
- a
- b
- c
- a ∧ b
- b ∧ c
- a ∧ c
- a ∨ b
- b ∨ c
- a ∨ c
- a ∧ b ∨ c
- b ∧ c ∨ a
- a ∧ c ∨ b
- a ∧ b ∨ b ∧ c
- a ∧ c ∨ b ∧ c
- a ∧ b ∨ a ∧ c
- a ∧ b ∨ b ∧ c ∨ a ∧ c
- a ∧ b ∧ c
- a ∨ b ∨ c
and so M(3) = 20.
As before, we can verify that the functions above are monotone with a script.
g = [None]*20 g[ 0] = lambda a, b, c: 0 g[ 1] = lambda a, b, c: a g[ 2] = lambda a, b, c: b g[ 3] = lambda a, b, c: c g[ 4] = lambda a, b, c: a & b g[ 5] = lambda a, b, c: b & c g[ 6] = lambda a, b, c: a & c g[ 7] = lambda a, b, c: a | b g[ 8] = lambda a, b, c: b | c g[ 9] = lambda a, b, c: a | c g[10] = lambda a, b, c: a & b | c g[11] = lambda a, b, c: b & c | a g[12] = lambda a, b, c: a & c | b g[13] = lambda a, b, c: a & b | b & c g[14] = lambda a, b, c: a & c | b & c g[15] = lambda a, b, c: a & b | a & c g[16] = lambda a, b, c: a & b | b & c | a & c g[17] = lambda a, b, c: a & b & c g[18] = lambda a, b, c: a | b | c g[19] = lambda a, b, c: 1 for i in range(20): for (a, b, c) in product((0,1), repeat=3): for (x, y, z) in product((0,1), repeat=3): if a <= x and b <= y and c <= z: assert(g[i](a, b, c) <= g[i](x, y, z))
More variables
The concrete approach to enumerating monotone Boolean functions does not scale. There are 168 monotone functions of four variables, 7581 of five variables, and 7,828,354 functions of six variables. The Dedekind numbers M(n) grow very quickly. The next post will quantify just how quickly.
[1] This “order” is technically a partial order. If x = (0, 1) and y = (1, 0) then x and y are not comparable; neither is less than or equal to the other.
It would be helpful if you enumerated the Boolean functions for 2 and 3 arguments that are *not* monotone.