Universal Decision Elements in 4-valued Logic


How many first order Universal Decision Elements of four argument places are there in 4-valued logic?

It is certainly more than 430, over 1 quintillion (1 x 1018), and possibly considerably more than that. Due to a lack of computer power our project to discover the number, described below, did not run to completion. If anyone knows the number perhaps they'd get in touch.


Theory

In 2-valued logic Unary Functors are easy to understand. For example NOT(0) is 1 and NOT(1) is 0. "NOT" is a Unary Functor: a function that acts on one operand. If we choose P to represent the operand, when P is 0, NOT(P) is 1; when P is 1, NOT(P) is 0. If we write this as a "truth table" we get:

P NOT(P)
0 1
1 0

In 4-valued logic each operand can have 4 values, say 0,1,2,3. Unary Functor number 6, for example, which we will write as U6, has this truth table:

P U6(P)
0 0
1 0
2 1
3 1

In 4-valued logic there are 256 Unary Functors. The output of each Unary Functor is simply one of the 256 possible combinations of 0,1,2,3. The first few and the last of the 256 Unary Functors are:

P U1(P) U2(P) U3(P) U4(P) U5(P) ... U256(P)
0 0 0 0 0 0   3
1 0 0 0 0 0   3
2 0 0 0 0 1   3
3 0 1 2 3 0   3

A first order Universal Decision Element of 4 argument places is a formula containing 4 variables F(P1,P2,P3,P4) (where the Ps can have the values 0,1,2,3 or P, and there must be at least one P) which can simulate all 256 Unary Functors.

For example, say F(0,3,1,P) gives the result 0,0,0,2 when P takes the values 0,1,2,3 respectively. I.E:

F(0,3,1,0) is 0
F(0,3,1,1) is 0
F(0,3,1,2) is 0
F(0,3,1,3) is 2.

This is the same result as U3(P). And let's say that substituting F(P,P,3,1) in this same formula gives the result 0,0,2,1 as P takes the values 0,1,2,3, which is the same result as U10(P). If this formula F(P1,P2,P3,P4) can thus simulate all 256 Unary Functors it is called a Universal Decision Element (UDE).

The question is: how many of these Universal Decision Element formulae are there?

One way to find out would be to test all possible formulae and see if each can simulate all 256 Unary Functors. The trouble is there are rather a lot of such formulae:

Each formula F(P1,P2,P3,P4) has 256 lines (we will call the lines "entry points") in its truth table:

P1 P2 P3 P4   F(P1,P2,P3,P4)
0  0  0  0
0  0  0  1
0  0  0  2
0  0  0  3
0  0  1  0
0  0  1  1
0  0  1  2
0  0  1  3
0  0  2  0
0  0  2  1
0  0  2  2
0  0  2  3
etc until line 256 where P1,P2,P3,P4 all have the value 3.

Now, the result of line 1 could be 0, 1, 2 or 3, so the first line in the truth table could be:

P1 P2 P3 P4   F(P1,P2,P3,P4)
0  0  0  0           0
or
0  0  0  0           1
or
0  0  0  0           2
or
0  0  0  0           3

Since each of the 256 results in the truth table can take the value 0,1,2 or 3, the number of possible truth tables is 4x4x4... 256 times. I.E. there are 4256 F(P1,P2,P3,P4) possible truth tables. That is a huge number - more atoms than there are in the universe - and testing each one to see if it is a UDE would take for ever: the calculations would still be running long after the end of the universe. So a faster method is required.

Suppose, for a given F(P1,P2,P3,P4) formula we substitute 0,0,0,P in place of P1,P2,P3 and P4. This substitution uses entry points 1,2,3 and 4 in the truth table: as P takes the values 0,1,2,3, F(0,0,0,P) becomes F(0,0,0,0), F(0,0,0,1), F(0,0,0,2), F(0,0,0,3). Further, suppose that this substitution gives the result 1,3,2,0 for values 0,1,2,3 of P. (Which, by the way, is the same result as Unary Functor number 120.) The first 4 of the 256 lines in the truth table for this particular formula F(P1,P2,P3,P4) would be:

P1 P2 P3 P4   F(P1,P2,P3,P4)
0  0  0  0           1
0  0  0  1           3
0  0  0  2           2
0  0  0  3           0

Clearly, every substitution will give the same result as some Unary Functor or other, but for the formula to qualify as a Universal Decision Element (UDE) each of the 256 Unary Functors must be simulated by at least one of the substitutions.

However, there are 369 possible substitutions of 0,1,2,3,P in F(P1,P2,P3,P4) such that there is always at least one P, e.g. F(0,0,0,P), F(P,P,3,1), F(P,P,P,P). But there are only 256 Unary Functors. So a UDE will simulate some of the Unary Functors with more than one substitution. For illustration:

Unary Functor Substitutions that simulate it
1 27 3
2 72 91 151
3 1
4 156 207 319
.
256 7 14 298

Now, in the above illustration, Unary Functor 3 is simulated by substitution number 1 which is F(0,0,0,P). [* See Numbering.] This substitution uses entry points 1,2,3 and 4 in the truth table. I.E the first 4 lines in the truth table for this particular UDE are:

P1 P2 P3 P4   F(P1,P2,P3,P4)
0  0  0  0           0
0  0  0  1           0
0  0  0  2           0
0  0  0  3           2
etc to line 256

If we now mark off all the entry points that are used by Unary Functors that are simulated by only one substitution, and we strike these Unary Functors from the list of Unary Functors, we would be left with a list of Unary Functors which are simulated by more than one substitution, and the list of entry points showing which has been used by Unary Functors that are simulated by only one substitution.

The remaining Unary Functors are simulated by two or more substitutions. Suppose we now simulate these remaining Unary Functors by choosing, wherever possible, substitutions that only use entry points that have already been used by the Unary Functors that were simulated by only one substitution. When we have thus judiciously chosen a substitution for all of the 256 Unary Functors it could be that some entry points have not been used at all. And indeed this turns out to be the case.

So let us suppose that for a particular formula F(P1,P2,P3,P4) we can simulate all the Unary Functors without using entry point 1. We can therefore put any value we like in entry point 1 and the resulting 3 additional formulae will all still be UDEs:

P1 P2 P3 P4   F1(P1,P2,P3,P4)
0  0  0  0           0
0  0  0  1           2
0  0  0  2           3
0  0  0  3           3
etc to line 256

P1 P2 P3 P4   F2(P1,P2,P3,P4)
0  0  0  0           1
0  0  0  1           2
0  0  0  2           3
0  0  0  3           3
etc to line 256

P1 P2 P3 P4   F3(P1,P2,P3,P4)
0  0  0  0           2
0  0  0  1           2
0  0  0  2           3
0  0  0  3           3
etc to line 256

P1 P2 P3 P4   F4(P1,P2,P3,P4)
0  0  0  0           3
0  0  0  1           2
0  0  0  2           3
0  0  0  3           3
etc to line 256

However, we can now take each of the 3 new formulae and start the process again, calculating which Unary Functor each substitution simulates. We know that all 3 of these new formulae can simulate all 256 Unary Functors, but let's say that one of the new formulae can do so using entry point 1 but leaving entry points 8 and 174 unused. That means we can now change the values at those two entry points in the new formula which will yield a further 16 formulae (one of which is the one we started with). Clearly, by repeating the above process we can generate more and more new UDEs.

Though it's a little more complicated than the above would suggested. Suppose Unary Functor 1 can be defined either by substitution 254 or 39. Further, suppose using substitution 254 leaves entry points 4 and 163 unused, and using substitution 39 leaves entry point 80 unused. Choosing to use substitution 254 means we can generate 16 UDEs by varying the values at entry points 4 and 163, and choosing substitution 39 means we can assign any of the values 0,1,2,3 to entry point 80. So that's 20 new UDEs in all - though two of these will be the formula we started with.

And of course it could well be that there are several Unary Functors each of which can be simulated by several substitutions. This implies many permutations of substitutions are possible to simulate those Unary Functors, each permutation potentially delivering a set of unused entry points.


Program

To find all the UDEs in 4-valued logic one could take the following approach:

Generate as many UDEs as possible from the first UDE, generate all possible UDEs from those, compare to those already generated and store any that are new, and so on until every UDE has been examined. This approach, although simple, is very time consuming. Some UDEs generate over 200,000 new UDEs and comparing them to those already generated to eliminate duplicates takes a long time. If, say 10,000,000 UDEs each generated an average of 100,000 new UDEs, that's 10,000,000 x 100,000 x 5,000,000 (average number already stored) compares: 5 x 1018 compares of 256 digit numbers. A bit too much for a laptop.

The search for duplicates could be speeded by sorting the UDEs. However, since the above paragraph was initially written it has become clear that the number of UDEs is measured in quintillions, so even storing them would be impractical on a laptop.

Instead, our program analyses the starting UDE and determines the sets of unused entry points it yields. Each of these UDE/unused-entry-point sets is stored. Then each stored UDE/unused-entry-point set is analysed to produce more UDE/unused-entry-point sets, each time comparing new UDE/unused-entry-point sets to those already stored to avoid storing duplicates.

One further wrinkle: a given formula F(P1,P2,P3,P4) will usually produce several sets of unused entry points, eg:

  • 80, 215
  • 80, 172, 202
  • 80, 94, 215
  • 172

But the UDEs produced from set 4, which only contains entry point 172, will also be produced from set 2 (80, 172, 202). So the set consisting just of entry point 172 can be ignored. Similarly set 1 (80, 215) is a subset of set 3 (80, 94, 215). So only sets (80, 172, 202) and (80, 94, 215) need to be stored. I.E. for any given starting UDE we ignore subsets of unused entry points.

The Process

UDE/unused-entry-point sets are read from file into an in-memory array. [** See Initialisation.] Each set is held as a set of 256 digits each having values 0,1,2 or 3, along with a list of its unused entry points.

The first as yet unprocessed UDE/unused-entry-point set in the array is found. From this starting UDE/unused-entry-point set, new UDEs are generated by assigning all possible combinations of values to its unused entry points. For example, if entry points 132 and 319 are unused, we will generate 16 UDEs.

(Point A)

Each generated UDE is analysed in turn using the following process:

Each of the 369 substitutions is examined to see which Unary Functor it makes the UDE being examined simulate. For example, let us look at substitution F(1,P,0,P). Assigning each value of P yields:
1 0 0 0
1 1 0 1
1 2 0 2
1 3 0 3

We look up what the value of the UDE is at each of these entry points. Let us suppose that for the UDE being examined the values at these four entry points are 0,0,0,3. That corresponds to Unary Functor number 4. I.E. for this UDE, this particular substitution simulates Unary Functor number 4.

By examining all 369 substitutions we build a table showing, for each Unary Functor, which substitution(s) simulate it.

(We then check that all 256 Unary Functors have at least one substitution, i.e. that this UDE is indeed a UDE. This MUST be the case if the program is working properly - this was a useful check during program development.)

The table of Unary Functors and substitutions is examined. For Unary Functors that have only one substitution, the entry points used by its substitution are marked as used, and those Unary Functors are marked as defined.

Next, each of the Unary Functors which have more than one substitution is checked to see if any of its substitutions use only entry points that have already been used. If so, those Unary Functors are also marked as defined.

For each Unary Functor that is still undefined, all of its substitutions are examined to see if they all use one of the as yet unused entry points. If they do, clearly that entry point will have to be used, so it is marked as used. The step described in the previous paragraph is then repeated to see if any of the as yet undefined Unary Functors can now be defined using the enlarged list of used entry points. If so, they are marked as defined. (Performing this paragraph's action before the action of the previous paragraph would avoid repeating the previous paragraph's step, but that way actually requires more calculations and runs slower: many more UFs would have to be examined in this step.)

We are now left with a number of as yet undefined Unary Functors and a list of as yet unused entry points.

For example. Let us suppose that the process above has defined all but three Unary Functors, 27, 34 and 217, and that they could be defined by the following substitutions:

UF   Substitutions
27     2 93 369
34   67 85 136 298
217  15 34

These 3 last Unary Functors could be defined using substitutions 2, 67 and 15; or 2, 67 and 34, for example. Clearly, there are 24 (3x4x2) ways these last Unary Functors can be defined.

Each permutation of substitutions is examined to see which of the as yet unused entry points it would use. If, after defining these last few Unary Functors with one of the permutations, there are still some entry points unused we have found a UDE/unused-entry-point set. So say, in our example, the first of the 24 permutations leaves entry points 57 and 255 unused. This UDE/unused-entry-point set is compared to sets previously found and added to the in-memory array if it is not already there and it is not a subset of one already there. The process is reapeated for each of the (in our example 24) permutations of substitutions.

We then return to Point A above to generate the next UDE from our starting UDE/unused-entry-point set. When all (16 in our example) UDEs generated from the starting UDE/unused-entry-point set has been examined, the next UDE/unused-entry-point set is read from the file.

We then return to Point A above to generate the next UDE from our starting UDE/unused-entry-point set.

When all (16 in our example) UDEs generated from the starting UDE/unused-entry-point set has been examined we return to the paragraph just above Point A where the next as yet unprocessed UDE/unused-entry-point set is read from the in-memory array.

After processing a certan number (set by a parameter) of UDE/unused-entry-point sets, the in-memory array is "subsetted": Each UDE/unused-entry-point set that has been added to the array since the last subsetting is checked against pre-existing entries to see if any pre-existing set is a subset of the new set. If so, it is deleted from the array.

The in-memory array is then written to file: UDE/unused-entry-point sets with the most unused EPs are written first. At the start of the next loop, the file is read into the in-memory array and the first as-yet-unprocessed UDE/unused-entry-point set from the array will be processed. In this way, UDE/unused-entry-point sets with the highest number of unused EPs will be processed first. Writing to the file every so often also provides a checkpoint restart capability.

Eventually, when all the UDE/unused-entry-point sets on the file have been processed, a calculation is made of how many UDEs these stored UDE/unused-entry-point sets would generate.

[*Numbering: The numbering of entry points, unary functors and substitutions is arbitrary. We have chosen entry point 0000 to be number 1, unary functor 0000 to be number 1 and substitution 000P to be number 1.]

[**Initialisation: The process was initialised by using an initial known UDE supplied by J.Loader. It was J.Loader who originally devised the method of discovering UDEs described in this paper.]


Outcome

This paragraph should be all about the results produced by the programs. However, at the moment it is looking as if the number of UDE/unused-entry-point sets (let alone the number of UDEs) is far too vast to be discoverable on a laptop.


Notes on results so far