I am trying to finish a piece of Matlab 16 code which I have posted at the end. The objective is to evaluate each of the five properties for each Boolean operator specified by Emil Post in his thesis (some background can be found here https://sites.ualberta.ca/~francisp/Phil428/Phil428.11/UrquhartPost.pdf). The five conditions are listed at:
1) Easy to understand yet must log into Scribd unfortunately. https://www.scribd.com/document/255983069/Posts-Criterion
2) A little more difficult to follow but more rigorous. Pdf is readily available: https://sites.ualberta.ca/~francisp/Phil428/Phil428.11/PostPellMartin.pdf
The five properties are that a Boolean function $f$ may have are:
- $f$ preserves zero $(T_0)$,
- $f$ preserves one $(T_1)$,
- $f$ is linear $(L)$,
- $f$ is monotone $(M)$,
- $f$ is self-dual $(S)$.
Post's Completeness Theorem may be stated as follows (This is straight from the first reference):
Theorem. A system of Boolean functions is functionally complete if and only if this system does not entirely belong to any of $T_0$, $T_1$, $L$, $M$, $S$.
This means that
- at least one function that does not preserve zero (i.e. it is not in $T_0$), and
- at least one function that does not preserve one (i.e. it is not in $T_1$), and
- at least one function that is not linear (i.e. it is not in L), and
- at least one function that is not monotone (i.e. it is not in M), and
- at least one function that is not self-dual (i.e. it is not in S).
The aforementioned documents spell these out in great detail so I will not belabor the point here. Post's Completeness Theorem, however, states that a functionally complete operator set is a set of operators which at least one function $f$ of the set does not entirely below to all of these sets 1 through 5.
As a way to attempt to validate my code the number of Sheffer functions, that is those functions which are complete by themselves (as NAND and NOR gates are) for arity $n$ is \begin{equation} 2^{2^n-2}-2^{2^{n-1}} \end{equation} and for for $n=3$, or Boolean functions of three variables, there should be 48 Sheffer functions. The code I am providing calculates on 43 Sheffer functions and therefore something is amiss.
A remark on the code. It is my first attempt at coding each of the five criteria and therefore it is not as clean as I typically prefer. My objective is to first get it working and then to make changes according to preferred programming conventions. For properties 1, 2, 3, and 5 the main loop runs through the functions one-by-one. For Property 4 this is unnecessary and so I wait to evaluate Property 4 until the very end.
If a Boolean function meets a property then it receives a $1$ for TRUE and a $0$ for FALSE in the Conditions matrix. The Conditions matrix is a $2^{2^n}$-by-5 Boolean matrix which keeps track of how the functions behaved for the 5 conditions. According to Post's conditions then, a Sheffer function should have a row of zeros since it fulfills none of the conditions and it does not entirely below to any set. The final loop at the end of the code is supposed to determine how many Sheffer functions there are. For the arity (AtomNum) within the code this should be 48.
I suspect the error is within Property 3 - linearity. I have rewritten each of the 5 and I am fairly confident that the other four are working as necessary. However, I have been wrong many times and this one could just be yet another one of those times.
Please let me know if something is not clear or is confusing. I will respond swiftly. Thank you for your help!
clear all
clc
AtomNum = 3; % Arity
Conditions(1:2^(2^AtomNum),1:5) = 0;
Q = '';
for j = 0:2^(2^AtomNum)-1
BString = dec2bin(j);
for n=1:length(dec2bin(2^(2^AtomNum)-1))-length(dec2bin(j))
BString = strcat('0',BString);
end
L = length(BString);
% Test Properties according to Post's Completeness Theorem
% Property 1: f preserves 0
% 0: No
% 1: Yes
if BString(1) == '0'
Conditions(j+1,1) = 1;
end
% Property 2: f preserves 1
% 0: No
% 1: Yes
if BString(length(BString)) == '1'
Conditions(j+1,2) = 1;
end
% Property 5: Self-Dual?
% 0: No
% 1: Yes
flag = 0;
for k = 1:L/2
if str2num(BString(k)) ~= 1-(str2num(BString(L-k+1)))
flag = 1;
end
end
if flag == 0
Conditions(j+1,5) = 1;
end
%--------------------------------
% Property 3: Alternating Functions or Linearity
% 0: No
% 1: Yes
% Initialize the A matrix
A(1:2^AtomNum,1:AtomNum+1) = 0;
F = dec2bin(j);
L = length(F);
for n = L:2^AtomNum-1
F = strcat('0',F);
end
for jj = 1:2^AtomNum
A(jj,AtomNum+1) = str2num(F(jj));
end
% This code produces the atom matrix, or A matrix
% The B matrix is the A matrix augmented with the
% function's results
for jj = 0:2^AtomNum-1
BString1 = dec2bin(jj);
L = length(BString1);
for n = L:AtomNum-1
BString1 = strcat('0',BString1);
end
for kk = 1:AtomNum
A(1+jj,kk) = str2num(BString1(kk));
end
end
% is any column has a 1,3 or a 0,2 then that
% column has dummy variables and needs to
% be addressed
for jj=1:AtomNum
B(:,jj) = 2* A(:,jj) + A(:,AtomNum+1);
end
% We need to ignore all dummy variables.
% Those coded with a -1 are dummy variables
for jj=1:AtomNum
if any(B(:,jj)==0) * any(B(:,jj)==2) == 1
B(B(:,jj) == 0,jj) = -1;
B(B(:,jj) == 2,jj) = -1;
end
if any(B(:,jj)==1) * any(B(:,jj)==3) == 1
B(B(:,jj) == 1,jj) = -1;
B(B(:,jj) == 3,jj) = -1;
end
end
% set dummy variables values to -1
for jj=1:2^AtomNum
for k=1:AtomNum
if B(jj,k) == -1
A(jj,k) = -1;
end
end
end
% Set conditions as true. If an instance arises
% where it is false then set value as zero
cond1 = 1;
cond2 = 1;
cond3 = 1;
cond4 = 1;
for jj=1:2^AtomNum
if A(jj,1+AtomNum) == 1
if mod(sum(A(A(jj,1:AtomNum)==1)),2) == 1
cond1 = 0;
end
end
if A(jj,1+AtomNum) == 0
if mod(sum(A(A(jj,1:AtomNum)==1)),2) == 0
cond2 = 0;
end
end
if A(jj,1+AtomNum) == 1
if mod(sum(A(A(jj,1:AtomNum)==1)),2) == 0
cond3 = 0;
end
end
if A(jj,1+AtomNum) == 0
if mod(sum(A(A(jj,1:AtomNum)==1)),2) == 1
cond4 = 0;
end
end
end
% Either cond1 AND cond2 must be true OR cond3 AND cond4
% must be true to Property 3 to be true for this Boolean
% function.
Conditions(j+1,3) = cond1*cond2+cond3*cond4;
end
%Principle 4: Monotonic Functions
% 0: No
% 1: Yes
S = {'0', '1'};
for n = 1:AtomNum
cnt = 0;
J = {};
for m = 1:numel(S)
for k = m:numel(S)
if bitor(bin2dec(S{m}), bin2dec(S{k})) == bin2dec(S{k})
cnt = cnt + 1;
J{cnt} = strcat(S{m},S{k});
end
end
end
S = J;
end
S = bin2dec(S);
Conditions(S+1,4) = 1;
% If all rows are zero then the function is a Sheffer function.
% Count the number of Sheffer functions. For AtomNum=3 it should
% be 48.
cnt = 0;
for j=1:2^(2^AtomNum)
if sum(Conditions(j,:)) == 0
cnt = cnt + 1;
end
end