# Enumerating Trinary Logic

Kurt Nalty
July 19, 2012

Trinary logic is an extension of binary logic to have three states, such as

<spin up>, <no particle>, and <spin down>.

As implied by this example, quantum computers are expected to utilize trinary logic.

This paper looks at the fundamentals of trinary logic without any attachment to linguistics or philosophy. The primary tool I use, is simple enumeration, accompanied with graphical interpretation of the meanings of the tables. As an assistance in the explanations, I begin with binary logic to develop the method in familiar territory, and then do the same process in trinary. We illustrate the 27 single input trinary gates, then provide the algorithim for the 19683 dual input trinary gates. We list and explain the commutative and associative subset of those gates, then close by presenting two of at least six approaches toward arbitrary logic using a mere handful of gates.

*********************************************************************

Binary logic has two logic states, 0 and 1. We can easily enumerate all binary logic for single input, single output gates.

`Input   GND  	WIRE  	NOT  	VCC0	 0	 0	 1	 11	 0	 1	 0	 1`
The GND gate has an output always low, like a ground connection in a logic circuit. The WIRE gate has input and output equal, similar to a wire. The NOT gate is an inverter. Notice that two NOT gates cascaded one into the other make a WIRE gate. This implies that we can treat the NOT gate as a square root of the WIRE. Finally, VCC is stuck high all the time, like a power supply connection in digital logic. There is no way to make GND or VCC from the WIRE and NOT gates. Any single input gates above do not generate the complete set. However, if you provide a NOT gate, and a single static level, such as GND, you can generate the WIRE signal and the VCC signal.

*********************************************************************

Now, let's enumerate the full set of two input binary logic gates.

`                    N       N                   X                   N       INPUTS      G   A   A   B   B   A   X       N   N   N   B   N   A   A   V                 N   N   I       I       O   O   O   O   A   I   B   I   N   C  A B         D   D   B       A       R   R   R   R       A       B   D   C 0 0         0   0   0   0   0   0   0   0   1   1   1   1   1   1   1   1  0 0         0   0   0   0   1   1   1   1   0   0   0   0   1   1   1   1  0 0         0   0   1   1   0   0   1   1   0   0   1   1   0   0   1   1  0 0         0   1   0   1   0   1   0   1   0   1   0   1   0   1   0   1              CA  CA  xx  xA  xx  xA  CA  CA  Cx  CA  xx  xx  xx  xx  Cx  CA `

The implication gates are not widely used in digital logic, usually showing as single bubble input AND, NAND, OR and NOR gates. (1BAND, 1BNAND, 1BOR, 1BNOR).

In formal logic, we have various material implication gates:
AIB = A implies B
BIA = B implies A
NAIB = negated A implies B
NBIA = negated B implies A

Under the truth tables are the letters C for commutative, A for associative and x for the absense of the afore properties.

C = 1 iff F(A,B) == F(B,A)
A = 1 iff F(F(A,B),C) == F(A,F(B,C))

Of the above gates, the NAND and NOR gates are capable of generating every logic element in the single and double input cases (including VCC and GND). These are the universal gates, or set generators for logic. All higher input count logic can also be generated by sum of products (or product of sums) formats, and implemented as NAND gates for sum of products, or NOR gates for product of sums expressions.

Technology wise, NAND gates are faster than NOR gates, and thus we find NAND gates as the preferred logic element.

*********************************************************************

Now, let's investigate trinary logic.

By analogy with the example above, let's begin with enumerating the full set of single input and single output gates.

The single input can have three states, which I will label 0,1 and 2. (Simple text editor substitution can change these tables to +, 0 and -.) The output columns will cover a three character counting sequence, for 27 (27=3^3) logic functions.

`                                                                                 I                                                                                N                  W     N           N                             N              P                  I     O           O                       C     O              U                  R     T           T           C           C     T              T   0              E     0           2     1     W           W     1              2                                                                                   0   0  0  0  0  0  0  0  0  0  1  1  1  1  1  1  1  1  1  2  2  2  2  2  2  2  2  21   0  0  0  1  1  1  2  2  2  0  0  0  1  1  1  2  2  2  0  0  0  1  1  1  2  2  22   0  1  2  0  1  2  0  1  2  0  1  2  0  1  2  0  1  2  0  1  2  0  1  2  0  1  2`

At first glance, 27 single input, single output functions may seem like a surplus, but due to the comprehensive nature of enumeration, this is *exactly* what is required to span this functional space.

*********************************************************************

I start by looking at the information preserving gates, where we have all three states possible on the output.

The WIRE gate, where input and outputs are equal, is immediately apparent.

In binary logic, we had a single NOT gate, which squared, gave us a wire. In trinary, we have three NOT gates which square to a WIRE, being NOT0, NOT1 and NOT2. The number after the NOT gives the invariant logic level, while the other two levels swap. When people are initially discussing trinary logic, they usually identify NOT1, and fail to notice the equally valid and necessary NOT0 and NOT2. Cascade two of the very same NOTx together, and you get a WIRE. Consequently, we have three distinct square roots of the wire in trinary.

NOT0->NOT0 = WIRE
NOT1->NOT1 = WIRE
NOT2->NOT2 = WIRE

The remaining two information preserving gates, I've labelled as CW for clockwise, and CCW for counter-clockwise. These rotate the three logic levels in different directions, and constitute two different cubed roots of the wire.

CW->CW->CW = WIRE             CCW->CCW->CCW = WIRE

Cascading different NOTx gates leads to CW and CCW gates.

`NOT0->NOT1 = CW     NOT1->NOT0 = CCWNOT1->NOT2 = CW     NOT2->NOT1 = CCWNOT2->NOT0 = CW     NOT0->NOT2 = CCW`
These information preserving gates, I collectively call "threefer" gates, as they transfer three levels.

*********************************************************************

Now, let's look at the static levels 0 (0 0 0), 1 (1, 1, 1) and 2 (2, 2, 2). These are like the VCC and GND levels from binary logic, and our new logic level. Since these ignore the inputs, they necessarily totally lose incoming, yet originate outgoing, information. These static level gates, I collectively call "onefer" gates.

*********************************************************************

The last class of gates, I collectively call the twofer gates, as we have two of one logic level, and one of another. We necessarily lose information using these gates.

Before presenting the truth table for the cascade of single input gates, I want to present some graphical tiles, which I've made for the open-source DIA program. These tiles are inspired by similar tiles used in knots and braids. <!-- KN - find references and give credit.-->

The number on top of the tiles is the enumeration value in base 3 for that particular gate. The left side shows incoming logic levels, 0 at the top, 1 in the middle, and 2 at the bottom. The right side shows corresponding output logic levels, 0 at the top, 1 in the middle, and 2 at the bottom. The enumeration function and the tile are related as follows:
• The left digit gives the logic output when the input level is zero.
• The middle digit gives the logic output level when in the input level is one.
• The third digit gives the logic output level when the input level is two.
Looking at the top left tile, 000, we see that the output is always zero regardless of the input. This is one of the three onefer gates.

Looking at 001, we see that 0 and 1 on the input both results in a zero output, while a 2 on the input results in a 1 output. This is an example of a twofer gate.

Scrolling down and looking at 012, we see a threefer gate, the WIRE gate. A bit further down, we see another threefer gate, the NOT0 gate, ID 021.

These tiles allow me to quickly, graphically evaluate cascades of gates without having to access a lookup table. These have been very valuable for developing insight into the operations of trinary logic.   These symbols are available in a zip archive in a DIA shape format at

http://www.kurtnalty.com/TrinaryA.zip

Source code used for this work is included at the end of this file.

Multiplication Table

The traditional next step is to create a multiplication table the logic being studied. The first table is using the 000 style labels, as seen above. This table will be wide.

`						Outer Term (Ex: 121(...)  )          000 001 002 010 011 012 020 021 022 100 101 102 110 111 112 120 121 122 200 201 202 210 211 212 220 221 222    000    000 000 000 000 000 000 000 000 000 111 111 111 111 111 111 111 111 111 222 222 222 222 222 222 222 222 222    001    000 000 000 001 001 001 002 002 002 110 110 110 111 111 111 112 112 112 220 220 220 221 221 221 222 222 222    002    000 001 002 000 001 002 000 001 002 110 111 112 110 111 112 110 111 112 220 221 222 220 221 222 220 221 222    010    000 000 000 010 010 010 020 020 020 101 101 101 111 111 111 121 121 121 202 202 202 212 212 212 222 222 222 I  011    000 000 000 011 011 011 022 022 022 100 100 100 111 111 111 122 122 122 200 200 200 211 211 211 222 222 222 N  012    000 001 002 010 011 012 020 021 022 100 101 102 110 111 112 120 121 122 200 201 202 210 211 212 220 221 222 N  020    000 010 020 000 010 020 000 010 020 101 111 121 101 111 121 101 111 121 202 212 222 202 212 222 202 212 222 E  021    000 010 020 001 011 021 002 012 022 100 110 120 101 111 121 102 112 122 200 210 220 201 211 221 202 212 222 R  022    000 011 022 000 011 022 000 011 022 100 111 122 100 111 122 100 111 122 200 211 222 200 211 222 200 211 222    100    000 000 000 100 100 100 200 200 200 011 011 011 111 111 111 211 211 211 022 022 022 122 122 122 222 222 222 T  101    000 000 000 101 101 101 202 202 202 010 010 010 111 111 111 212 212 212 020 020 020 121 121 121 222 222 222 E  102    000 001 002 100 101 102 200 201 202 010 011 012 110 111 112 210 211 212 020 021 022 120 121 122 220 221 222 R  110    000 000 000 110 110 110 220 220 220 001 001 001 111 111 111 221 221 221 002 002 002 112 112 112 222 222 222 M  111    000 000 000 111 111 111 222 222 222 000 000 000 111 111 111 222 222 222 000 000 000 111 111 111 222 222 222    112    000 001 002 110 111 112 220 221 222 000 001 002 110 111 112 220 221 222 000 001 002 110 111 112 220 221 222    120    000 010 020 100 110 120 200 210 220 001 011 021 101 111 121 201 211 221 002 012 022 102 112 122 202 212 222    121    000 010 020 101 111 121 202 212 222 000 010 020 101 111 121 202 212 222 000 010 020 101 111 121 202 212 222    122    000 011 022 100 111 122 200 211 222 000 011 022 100 111 122 200 211 222 000 011 022 100 111 122 200 211 222    200    000 100 200 000 100 200 000 100 200 011 111 211 011 111 211 011 111 211 022 122 222 022 122 222 022 122 222    201    000 100 200 001 101 201 002 102 202 010 110 210 011 111 211 012 112 212 020 120 220 021 121 221 022 122 222    202    000 101 202 000 101 202 000 101 202 010 111 212 010 111 212 010 111 212 020 121 222 020 121 222 020 121 222    210    000 100 200 010 110 210 020 120 220 001 101 201 011 111 211 021 121 221 002 102 202 012 112 212 022 122 222    211    000 100 200 011 111 211 022 122 222 000 100 200 011 111 211 022 122 222 000 100 200 011 111 211 022 122 222    212    000 101 202 010 111 212 020 121 222 000 101 202 010 111 212 020 121 222 000 101 202 010 111 212 020 121 222    220    000 110 220 000 110 220 000 110 220 001 111 221 001 111 221 001 111 221 002 112 222 002 112 222 002 112 222    221    000 110 220 001 111 221 002 112 222 000 110 220 001 111 221 002 112 222 000 110 220 001 111 221 002 112 222    222    000 111 222 000 111 222 000 111 222 000 111 222 000 111 222 000 111 222 000 111 222 000 111 222 000 111 222 A much more compact, yet less informative, table uses A-Z and @ as substitution codes.000 = A   001 = B   002 = C   010 = D   011 = E   012 = F   020 = G   021 = H   022 = I   100 = J   101 = K   102 = L   110 = M   111 = N   112 = O   120 = P   121 = Q   122 = R   200 = S   201 = T   202 = U   210 = V   211 = W   212 = X   220 = Y   221 = Z   222 = @                     Outer Term (Ex: R(...)  )      A B C D E F G H I J K L M N O P Q R S T U V W X Y Z @ A     A A A A A A A A A N N N N N N N N N @ @ @ @ @ @ @ @ @ B     A A A B B B C C C M M M N N N O O O Y Y Y Z Z Z @ @ @ C     A B C A B C A B C M N O M N O M N O Y Z @ Y Z @ Y Z @ D     A A A D D D G G G K K K N N N Q Q Q U U U X X X @ @ @ E     A A A E E E I I I J J J N N N R R R S S S W W W @ @ @ F     A B C D E F G H I J K L M N O P Q R S T U V W X Y Z @ G     A D G A D G A D G K N Q K N Q K N Q U X @ U X @ U X @ H     A D G B E H C F I J M P K N Q L O R S V Y T W Z U X @ I     A E I A E I A E I J N R J N R J N R S W @ S W @ S W @ J     A A A J J J S S S E E E N N N W W W I I I R R R @ @ @ K     A A A K K K U U U D D D N N N X X X G G G Q Q Q @ @ @ L     A B C J K L S T U D E F M N O V W X G H I P Q R Y Z @ M     A A A M M M Y Y Y B B B N N N Z Z Z C C C O O O @ @ @ N     A A A N N N @ @ @ A A A N N N @ @ @ A A A N N N @ @ @ O     A B C M N O Y Z @ A B C M N O Y Z @ A B C M N O Y Z @ P     A D G J M P S V Y B E H K N Q T W Z C F I L O R U X @ Q     A D G K N Q U X @ A D G K N Q U X @ A D G K N Q U X @ R     A E I J N R S W @ A E I J N R S W @ A E I J N R S W @ S     A J S A J S A J S E N W E N W E N W I R @ I R @ I R @ T     A J S B K T C L U D M V E N W F O X G P Y H Q Z I R @ U     A K U A K U A K U D N X D N X D N X G Q @ G Q @ G Q @ V     A J S D M V G P Y B K T E N W H Q Z C L U F O X I R @ W     A J S E N W I R @ A J S E N W I R @ A J S E N W I R @ X     A K U D N X G Q @ A K U D N X G Q @ A K U D N X G Q @ Y     A M Y A M Y A M Y B N Z B N Z B N Z C O @ C O @ C O @ Z     A M Y B N Z C O @ A M Y B N Z C O @ A M Y B N Z C O @ @     A N @ A N @ A N @ A N @ A N @ A N @ A N @ A N @ A N @ `
When comparing the table to the graphical tiles, there are a few points to keep in mind. The time history of the tiles proceeds left to right, while the usual nesting of arguments in parenthesis goes from innermost parenthesis to outer most terms. As a self-calibration 000(xxx) == 000, and A(x) == A, so the vertical columns are the outer (last in time) arguement. For the example below, 202(100) = 022, and equivalently, U(J) = I. Here are the most common, useful gates.

F = WIRE = 012
H = NOT0 = 021
V = NOT1 = 210
L = NOT2 = 102

P = CW   = 120
T = CCW  = 201

Ten of these tiles square to simpler terms. These are great for logic simplification.

HH = VV = LL = F (disappears if not the only term)
BB = GG = AA = A = 000
MM = WW = NN = N = 111
RR = UU = @@ = @ = 222

In additions to WIRE and onefers squaring to themselves, we have the following six self-squares.
CC = C = 002
DD = D = 010
EE = E = 011
II = I = 022
OO = O = 112
XX = X = 212

Illustration of self-projection below for C, D, E, I, O and X. The minimum requirements to span this set of gates is quite small. Two distinct inverters and a single twofer, or one inverter, one rotator and one twofer are adequate to span the entire kit. For example, using inverter 102, inverter 021, and twofer 001, we can create or define all 27 elements in this kit.

A commutation map for this logic is shown below. As expected, the squares commute, as does the wire. The onefer gates commute with one third of the function space. The rest of commuters are listed below the table.

`       A B C D E F G H I J K L M N O P Q R S T U V W X Y Z @ A      C C C C C C C C C                                    B      C C       C                                          C      C   C C   C                                     C   CD      C   C C   C         C     C                          E      C       C C       C       C C                        F      C C C C C C C C C C C C C C C C C C C C C C C C C C CG      C         C C                                        H      C         C   C                                      I      C         C     C                   C         C     CJ              C C       C                                  K            C   C         C                                L                C           C                             CM                C             C C                          N            C C C             C C C             C C C      O              C C               C C                     C CP                C                   C       C              Q                C                     C             C      R                C                       C                 CS                C     C                   C                T                C                   C       C              U                C                             C           CV                C               C               C          W                C               C                 C        X                C     C         C     C             C     CY          C     C                                     C    Z                C                 C                     C  @          C     C     C     C     C     C     C     C     C`
Commuter pairs (outside the obvious)
C-D   C-Y   D-K   D-N   E-J   E-N   E-O  I-R   I-X    O-Z   P-T  Q-W

002-010   002-220   010-101   010-111   011-100   011-111
011-112   022-122   022-212   112-221   120-201   121-211

These commutators are potentially useful for simplifying logic by re-arranging product terms to then exploit  the squaring simplifications above.

Each of the gates above can be factored. The most degenerate gates (onefors) have 87 factorizations, while
the twofers each have 24. The threefors have merely six each.

Dual Input Gates

More fun than the 27 single input trinary gates are the 3^9 = 19683 dual input gates. My mental picture of this logic is to treat A as a multiplexer control, selecting one of the three candidate B functions to drive the output. Thinking HIGH, LOW, or TRUE, FALSE is not productive at all in the trinary arena. In my opinion, the three logic levels are equally important, perhaps best thought of as tips on a 120 degree Y shape, rather than as a linear strip.

In binary logic, we had GND, VCC, AND, OR, XOR and XNOR functions which were both associative and commutative. In the trinary world, we have 63 such functions. It is easy to identify three of these functions as our static levels: 0, 9841 and 19682.

This leaves sixty other functions to evaluate for algebraic usefulness. The two that jump out at me as of being of great value are 15665, which matches multiplication for - 0 + symbols, and 14001, which matches modulo 3 addition.

A nice way to group these functions is by permutation family. Treating the logic levels equally, we see that a logic function can be implemented (typically) six different ways. You have three choices for your first logic label, two choices for the second, and no choice at all for the third. As a bit of fine print, for the static levels, once the initial choice is made, as there are no other members, we have no choices, thus only three static levels. Likewise, for the match and rotator functions, the symmetries degenerate (repeat), leaving just three members in those families.

The remaining 54 commutating and associative functions fall neatly into nine permutation familes, and are listed below. What these functions *mean* is a current topic of investigation.

Source code for the tables generated below is at the end of this file.
`Both Associative and Commutative        0       9841      19682                 - static levels    83       3281       6479                 - inputs match  4069      14001      11453                 - rotator, mod 3 addition (aka XOR)     1        162       9840      13121      16402      19520          2         81       3280       6560       9842      19601         32        141       4018       4130       9104      14741        112        224       1538       2541      10610      17141        113        143       1619       2543       4019       4049        142        194       3968       4017       8180      15665     Multiplier Family      1536       2460       6673      10609      13346      17222       1617       2462       4048       4100       6674      13265       3168       6336       7381      12301      18146      18914           Static Outputs    0        9841      19682      A B | C    A B | C    A B | C    0 0 | 0    0 0 | 1    0 0 | 2   0 1 | 0    0 1 | 1    0 1 | 2    0 2 | 0    0 2 | 1    0 2 | 2    1 0 | 0    1 0 | 1    1 0 | 2    1 1 | 0    1 1 | 1    1 1 | 2    1 2 | 0    1 2 | 1    1 2 | 2    2 0 | 0    2 0 | 1    2 0 | 2    2 1 | 0    2 1 | 1    2 1 | 2    2 2 | 0    2 2 | 1    2 2 | 2     Both Inputs Match, and Level    83       3281       6479      A B | C    A B | C    A B | C    0 0 | 0    0 0 | 0    0 0 | 0    0 1 | 0    0 1 | 1    0 1 | 2    0 2 | 0    0 2 | 1    0 2 | 2    1 0 | 0    1 0 | 1    1 0 | 2    1 1 | 1    1 1 | 1    1 1 | 1    1 2 | 0    1 2 | 1    1 2 | 2    2 0 | 0    2 0 | 1    2 0 | 2    2 1 | 0    2 1 | 1    2 1 | 2    2 2 | 2    2 2 | 2    2 2 | 2     Rotator - CW, None, CCW  4069      14001      11453     4069 is also a mod 3 adder for 0, 1, 2 tokensA B | C    A B | C    A B | C   14001 is also a mod 3 adder for -, 0 , + tokens0 0 | 0    0 0 | 2    0 0 | 1    0 1 | 1    0 1 | 0    0 1 | 2    0 2 | 2    0 2 | 1    0 2 | 0    1 0 | 1    1 0 | 0    1 0 | 2    1 1 | 2    1 1 | 1    1 1 | 0    1 2 | 0    1 2 | 2    1 2 | 1    2 0 | 2    2 0 | 1    2 0 | 0    2 1 | 0    2 1 | 2    2 1 | 1    2 2 | 1    2 2 | 0    2 2 | 2    **************************************************************     1        162       9840      16402      19520      13121     A B | C    A B | C    A B | C    A B | C    A B | C    A B | C    0 0 | 0    0 0 | 0    0 0 | 1    0 0 | 2    0 0 | 2    0 0 | 1    0 1 | 0    0 1 | 0    0 1 | 1    0 1 | 1    0 1 | 2    0 1 | 2    0 2 | 0    0 2 | 0    0 2 | 1    0 2 | 1    0 2 | 2    0 2 | 2    1 0 | 0    1 0 | 0    1 0 | 1    1 0 | 1    1 0 | 2    1 0 | 2    1 1 | 0    1 1 | 2    1 1 | 1    1 1 | 1    1 1 | 0    1 1 | 2    1 2 | 0    1 2 | 0    1 2 | 1    1 2 | 1    1 2 | 2    1 2 | 2    2 0 | 0    2 0 | 0    2 0 | 1    2 0 | 1    2 0 | 2    2 0 | 2    2 1 | 0    2 1 | 0    2 1 | 1    2 1 | 1    2 1 | 2    2 1 | 2    2 2 | 1    2 2 | 0    2 2 | 0    2 2 | 1    2 2 | 2    2 2 | 2         2         81       9842       3280      19601       6560     A B | C    A B | C    A B | C    A B | C    A B | C    A B | C    0 0 | 0    0 0 | 0    0 0 | 1    0 0 | 0    0 0 | 2    0 0 | 0    0 1 | 0    0 1 | 0    0 1 | 1    0 1 | 1    0 1 | 2    0 1 | 2    0 2 | 0    0 2 | 0    0 2 | 1    0 2 | 1    0 2 | 2    0 2 | 2    1 0 | 0    1 0 | 0    1 0 | 1    1 0 | 1    1 0 | 2    1 0 | 2    1 1 | 0    1 1 | 1    1 1 | 1    1 1 | 1    1 1 | 1    1 1 | 2    1 2 | 0    1 2 | 0    1 2 | 1    1 2 | 1    1 2 | 2    1 2 | 2    2 0 | 0    2 0 | 0    2 0 | 1    2 0 | 1    2 0 | 2    2 0 | 2    2 1 | 0    2 1 | 0    2 1 | 1    2 1 | 1    2 1 | 2    2 1 | 2    2 2 | 2    2 2 | 0    2 2 | 2    2 2 | 1    2 2 | 2    2 2 | 2        32        141       9104       4018      14741       4130     A B | C    A B | C    A B | C    A B | C    A B | C    A B | C    0 0 | 0    0 0 | 0    0 0 | 1    0 0 | 0    0 0 | 2    0 0 | 0    0 1 | 0    0 1 | 0    0 1 | 1    0 1 | 1    0 1 | 0    0 1 | 1    0 2 | 0    0 2 | 0    0 2 | 0    0 2 | 2    0 2 | 2    0 2 | 2    1 0 | 0    1 0 | 0    1 0 | 1    1 0 | 1    1 0 | 0    1 0 | 1    1 1 | 0    1 1 | 1    1 1 | 1    1 1 | 1    1 1 | 1    1 1 | 2    1 2 | 1    1 2 | 2    1 2 | 1    1 2 | 1    1 2 | 2    1 2 | 2    2 0 | 0    2 0 | 0    2 0 | 0    2 0 | 2    2 0 | 2    2 0 | 2    2 1 | 1    2 1 | 2    2 1 | 1    2 1 | 1    2 1 | 2    2 1 | 2    2 2 | 2    2 2 | 0    2 2 | 2    2 2 | 1    2 2 | 2    2 2 | 2       112        224       2541      17141       1538      10610     A B | C    A B | C    A B | C    A B | C    A B | C    A B | C    0 0 | 0    0 0 | 0    0 0 | 0    0 0 | 2    0 0 | 0    0 0 | 1    0 1 | 0    0 1 | 0    0 1 | 1    0 1 | 1    0 1 | 0    0 1 | 1    0 2 | 0    0 2 | 0    0 2 | 0    0 2 | 2    0 2 | 2    0 2 | 2    1 0 | 0    1 0 | 0    1 0 | 1    1 0 | 1    1 0 | 0    1 0 | 1    1 1 | 1    1 1 | 2    1 1 | 1    1 1 | 1    1 1 | 0    1 1 | 1    1 2 | 1    1 2 | 2    1 2 | 1    1 2 | 1    1 2 | 2    1 2 | 2    2 0 | 0    2 0 | 0    2 0 | 0    2 0 | 2    2 0 | 2    2 0 | 2    2 1 | 1    2 1 | 2    2 1 | 1    2 1 | 1    2 1 | 2    2 1 | 2    2 2 | 1    2 2 | 2    2 2 | 0    2 2 | 2    2 2 | 2    2 2 | 2       113        143       2543       4019       1619       4049     A B | C    A B | C    A B | C    A B | C    A B | C    A B | C    0 0 | 0    0 0 | 0    0 0 | 0    0 0 | 0    0 0 | 0    0 0 | 0    0 1 | 0    0 1 | 0    0 1 | 1    0 1 | 1    0 1 | 0    0 1 | 1    0 2 | 0    0 2 | 0    0 2 | 0    0 2 | 2    0 2 | 2    0 2 | 2    1 0 | 0    1 0 | 0    1 0 | 1    1 0 | 1    1 0 | 0    1 0 | 1    1 1 | 1    1 1 | 1    1 1 | 1    1 1 | 1    1 1 | 1    1 1 | 1    1 2 | 1    1 2 | 2    1 2 | 1    1 2 | 1    1 2 | 2    1 2 | 2    2 0 | 0    2 0 | 0    2 0 | 0    2 0 | 2    2 0 | 2    2 0 | 2    2 1 | 1    2 1 | 2    2 1 | 1    2 1 | 1    2 1 | 2    2 1 | 2    2 2 | 2    2 2 | 2    2 2 | 2    2 2 | 2    2 2 | 2    2 2 | 2       142        194       4017      15665       3968       8180     A B | C    A B | C    A B | C    A B | C    A B | C    A B | C    0 0 | 0    0 0 | 0    0 0 | 0    0 0 | 2    0 0 | 0    0 0 | 1    0 1 | 0    0 1 | 0    0 1 | 1    0 1 | 1    0 1 | 1    0 1 | 0    0 2 | 0    0 2 | 0    0 2 | 2    0 2 | 0    0 2 | 2    0 2 | 2    1 0 | 0    1 0 | 0    1 0 | 1    1 0 | 1    1 0 | 1    1 0 | 0    1 1 | 1    1 1 | 2    1 1 | 1    1 1 | 1    1 1 | 0    1 1 | 1    1 2 | 2    1 2 | 1    1 2 | 1    1 2 | 1    1 2 | 2    1 2 | 2    2 0 | 0    2 0 | 0    2 0 | 2    2 0 | 0    2 0 | 2    2 0 | 2    2 1 | 2    2 1 | 1    2 1 | 1    2 1 | 1    2 1 | 2    2 1 | 2    2 2 | 1    2 2 | 2    2 2 | 0    2 2 | 2    2 2 | 2    2 2 | 2      1536       2460      10609       6673      17222      13346     A B | C    A B | C    A B | C    A B | C    A B | C    A B | C    0 0 | 0    0 0 | 0    0 0 | 1    0 0 | 1    0 0 | 2    0 0 | 2    0 1 | 0    0 1 | 1    0 1 | 1    0 1 | 0    0 1 | 1    0 1 | 0    0 2 | 2    0 2 | 0    0 2 | 2    0 2 | 0    0 2 | 2    0 2 | 0    1 0 | 0    1 0 | 1    1 0 | 1    1 0 | 0    1 0 | 1    1 0 | 0    1 1 | 0    1 1 | 0    1 1 | 1    1 1 | 1    1 1 | 2    1 1 | 2    1 2 | 2    1 2 | 1    1 2 | 2    1 2 | 1    1 2 | 1    1 2 | 2    2 0 | 2    2 0 | 0    2 0 | 2    2 0 | 0    2 0 | 2    2 0 | 0    2 1 | 2    2 1 | 1    2 1 | 2    2 1 | 1    2 1 | 1    2 1 | 2    2 2 | 0    2 2 | 0    2 2 | 1    2 2 | 1    2 2 | 2    2 2 | 2      1617       2462       4048       6674       4100      13265     A B | C    A B | C    A B | C    A B | C    A B | C    A B | C    0 0 | 0    0 0 | 0    0 0 | 0    0 0 | 1    0 0 | 0    0 0 | 2    0 1 | 0    0 1 | 1    0 1 | 1    0 1 | 0    0 1 | 1    0 1 | 0    0 2 | 2    0 2 | 0    0 2 | 2    0 2 | 0    0 2 | 2    0 2 | 0    1 0 | 0    1 0 | 1    1 0 | 1    1 0 | 0    1 0 | 1    1 0 | 0    1 1 | 1    1 1 | 0    1 1 | 1    1 1 | 1    1 1 | 2    1 1 | 1    1 2 | 2    1 2 | 1    1 2 | 2    1 2 | 1    1 2 | 1    1 2 | 2    2 0 | 2    2 0 | 0    2 0 | 2    2 0 | 0    2 0 | 2    2 0 | 0    2 1 | 2    2 1 | 1    2 1 | 2    2 1 | 1    2 1 | 1    2 1 | 2    2 2 | 0    2 2 | 2    2 2 | 1    2 2 | 2    2 2 | 2    2 2 | 2      3168       6336       7381      12301      18146      18914     A B | C    A B | C    A B | C    A B | C    A B | C    A B | C    0 0 | 0    0 0 | 0    0 0 | 1    0 0 | 1    0 0 | 2    0 0 | 2    0 1 | 1    0 1 | 2    0 1 | 0    0 1 | 2    0 1 | 2    0 1 | 2    0 2 | 1    0 2 | 2    0 2 | 1    0 2 | 1    0 2 | 0    0 2 | 1    1 0 | 1    1 0 | 2    1 0 | 0    1 0 | 2    1 0 | 2    1 0 | 2    1 1 | 0    1 1 | 0    1 1 | 1    1 1 | 1    1 1 | 2    1 1 | 2    1 2 | 0    1 2 | 0    1 2 | 0    1 2 | 2    1 2 | 0    1 2 | 1    2 0 | 1    2 0 | 2    2 0 | 1    2 0 | 1    2 0 | 0    2 0 | 1    2 1 | 0    2 1 | 0    2 1 | 0    2 1 | 2    2 1 | 0    2 1 | 1    2 2 | 0    2 2 | 0    2 2 | 1    2 2 | 1    2 2 | 2    2 2 | 2    `

Universal Trinary Logic Generation

In binary logic, we can implement any logic function using a handful of standard gates, such as the AND, OR and NOT gates with sum-of-products notation. (Even more simply, we just use NAND gates.) One method of visualizing the process for the two input binary gates is to use the A input as a data selector, gating one of the two single input primitives required for B to the output.

For binary, the second gate is traditionally shown as an OR gate, indicating saturating addition. However, since the process is effectively adding gate B to zeroes, we could implement the addition using an XOR gate, which represents mod 2 addition.

For trinary, we have a similar type of strategy which works. We have three single input triary gates (from our group of 27 earlier) which defined the output pattern for the top, middle and lower output of the truth table. The output of theses three gates feed into three selector functions, S0, S1 and S2, gated by A, which pass data through in their selected state,  but otherwise provide a constant, such as zero. The three selector gates feed into a summer, the output of which is the desired logic. In my illustrations, I will use a mod 3 summer, simply due to personal preference. A traditional summer will work as well, for the selectors which return 0 as the unselected constant. First Implementation - Uses Zero Constant Selectors, Mod 3 Adders

S0         S1         S2              Mod 3 Summer (4069)
A B | C    A B | C    A B | C               A B | C

0 0 | 0    0 0 | 0    0 0 | 0               0 0 | 0
0 1
| 1    0 1 | 0    0 1 | 0               0 1 | 1
0 2 | 2    0 2 | 0    0 2 | 0               0 2 | 2

1 0
| 0    1 0 | 0    1 0 | 0               1 0 | 1
1 1 | 0    1 1 | 1    1 1 | 0               1 1 | 2
1 2 | 0    1 2 | 2    1 2 | 0               1 2 | 0

2 0
| 0    2 0 | 0    2 0 | 0               2 0 | 2
2 1 | 0    2 1 | 0    2 1 | 1               2 1 | 0
2 2 | 0    2 2 | 0    2 2 | 2               2 2 | 1

Second Implementation - Uses 1, 2 Constant Selectors, Mod 3 Adders (1+2 constants sum to zero)

S0         S1         S2              Mod 3 Summer (4069)
A B | C    A B | C    A B | C               A B | C

0 0 | 0    0 0 | 1    0 0 | 2               0 0 | 0
0 1
| 1    0 1 | 1    0 1 | 2               0 1 | 1
0 2 | 2    0 2 | 1    0 2 | 2               0 2 | 2

1 0
| 1    1 0 | 0    1 0 | 2               1 0 | 1
1 1 | 1    1 1 | 1    1 1 | 2               1 1 | 2
1 2 | 1    1 2 | 2    1 2 | 2               1 2 | 0

2 0
| 1    2 0 | 2    2 0 | 0               2 0 | 2
2 1 | 1    2 1 | 2    2 1 | 1               2 1 | 0
2 2 | 1    2 2 | 2    2 2 | 2               2 2 | 1

Third Implementation - Uses Zero Constant Selectors, Don't Care OR summer

S0         S1         S2              Mod 3 Summer (4069)
A B | C    A B | C    A B | C               A B | C

0 0 | 0    0 0 | 0    0 0 | 0               0 0 | 0
0 1
| 1    0 1 | 0    0 1 | 0               0 1 | 1
0 2 | 2    0 2 | 0    0 2 | 0               0 2 | 2

1 0
| 0    1 0 | 0    1 0 | 0               1 0 | 1
1 1 | 0    1 1 | 1    1 1 | 0               1 1 | x
1 2 | 0    1 2 | 2    1 2 | 0               1 2 | x

2 0
| 0    2 0 | 0    2 0 | 0               2 0 | 2
2 1 | 0    2 1 | 0    2 1 | 1               2 1 | x
2 2 | 0    2 2 | 0    2 2 | 2               2 2 | x

Trinary Single Gate source code.
Multiplication Tables, Commutators, Factorizations.
`#include <stdio.h>void print(int i){	printf("%d",((i/9)%3));	printf("%d",((i/3)%3));	printf("%d",((i)%3));}int main(void){	int f;	// single input logic families	int commute;		// commutative flag	int i,j,k;	int count;	int a,b,c,A,B,C;	int index;	char letters={"ABCDEFGHIJKLMNOPQRSTUVWXYZ@"};	int onefers = {0, 13, 26};	int twofers = {1, 2, 3, 4, 6, 8, 9, 10, 12, 14, 16, 17, 18, 20, 22, 23, 24, 25};	int threefers = {5, 7, 11, 15, 19, 21};			for (i=0;i<27;i++) {		f[i] = i%3;		//least significant digit at highest address		f[i] = (i/3)%3;	// middle		f[i] = (i/9)%3;	// most significant digit at lowest address		}		// print values for check		for (j=0;j<3;j++) {		printf("%d  ",j);		for (i=0;i<27;i++) {			printf("%d ",f[i][j]);		}		printf("\n");	}// ********************************************************************		// check composite operations	printf("\n\n          ");	for (i=0;i<27;i++) {		print(i);	printf(" ");   //print banner	}	printf("\n\n");		for (i=0;i<27;i++) {		printf("   ");		print(i);		printf("    ");		a = f[i];	// inner term		b = f[i];		c = f[i];		for (j=0;j<27;j++) {			A = f[j][a];			B = f[j][b];			C = f[j][c];			index = C + 3*B + 9*A;			print(index);			printf(" ");		}		printf("\n");	}	printf("\n\n");// ********************************************************************	//	print 000 A, etc as a convenience	printf("\n\n");	for (i=0;i<27;i++) {		if (i%9 == 0) printf("\n");		print(i); 		printf(" = %c   ",letters[i]);	}	printf("\n");		// check composite operations, print alpha codes	printf("\n\n      ");	for (i=0;i<27;i++) {		printf("%c ",letters[i]);   //print banner	}	printf("\n\n");		for (i=0;i<27;i++) {		printf("%c ",letters[i]);		printf("    ");		a = f[i];	// inner term		b = f[i];		c = f[i];		for (j=0;j<27;j++) {			A = f[j][a];			B = f[j][b];			C = f[j][c];			index = C + 3*B + 9*A;			printf("%c ",letters[index]);		}		printf("\n");	}	printf("\n\n");//	look at commutator type of relationship	printf("\n\n      ");	for (i=0;i<27;i++) {		printf("%c ",letters[i]);   //print banner	}	printf("\n\n");		for (i=0;i<27;i++) {		printf("%c ",letters[i]);		printf("    ");		a = f[i];	// inner term		b = f[i];		c = f[i];		for (j=0;j<27;j++) {			A = f[j][f[i]] -  f[i][f[j]];			B = f[j][f[i]] -  f[i][f[j]];			C = f[j][f[i]] -  f[i][f[j]];			if ((A==0) && (B==0) && (C==0)) printf(" C");			else printf("  ");		}		printf("\n");	}	printf("\n\n");//************************* loop through building factor tables for onefers *****************************	for(k=0;k<3;k++) {		printf("**********************************************\n\nFactors for ");		print(onefers[k]); 		printf("\n\n");		count = 0;		for (i=0;i<27;i++) {			a = f[i];	// inner term			b = f[i];			c = f[i];			for (j=0;j<27;j++) {				A = f[j][a];				B = f[j][b];				C = f[j][c];				index = C + 3*B + 9*A;				if (index ==onefers[k]) {					count++;					print(j); printf("("); print(i); printf(")  ");				}			}			printf("\n");		}		printf("Count = %d\n\n", count);	}//************************* loop through building factor tables for twofers *****************************	for(k=0;k<18;k++) {		printf("**********************************************\n\nFactors for ");		print(twofers[k]); 		printf("\n\n");		count = 0;		for (i=0;i<27;i++) {			a = f[i];	// inner term			b = f[i];			c = f[i];			for (j=0;j<27;j++) {				A = f[j][a];				B = f[j][b];				C = f[j][c];				index = C + 3*B + 9*A;				if (index ==twofers[k]) {					count++;					print(j); printf("("); print(i); printf(")  ");				}			}			printf("\n");		}		printf("Count = %d\n\n", count);	}//************************* loop through building factor tables for threefers *****************************	for(k=0;k<6;k++) {		printf("**********************************************\n\nFactors for ");		print(threefers[k]); 		printf("\n\n");		count = 0;		for (i=0;i<27;i++) {			a = f[i];	// inner term			b = f[i];			c = f[i];			for (j=0;j<27;j++) {				A = f[j][a];				B = f[j][b];				C = f[j][c];				index = C + 3*B + 9*A;				if (index ==threefers[k]) {					count++;					print(j); printf("("); print(i); printf(")  ");				}			}			printf("\n");		}		printf("Count = %d\n\n", count);	}}`

Trinary Dual Input Gate source code
`#include <stdio.h>// This program enumerates the 3^9 trinary dual input logic elements	int h;	// global array of truth tables	int commutators;	// indices for the 729 commutators	int associators;	// indices for the 113 associators	int both;		// indices for the 63 joint commutators and associatorsint print_9(int i){	int A, B, C, index, k;	// print this table	printf("\n");	for (k=0;k<9;k++) printf("A B | C    ");	printf("\n\n");	for (A=0; A<3; A++) {		for (B=0; B<3; B++) {			index = 3*A + B;			for (k=0;k<9;k++) printf("%d %d | %d    ", A, B, h[k+i][index]);			printf("\n");		}		printf("\n");	}	printf("\n");}int print9ofboth(int i){	int A, B, C, index, k;	// print this table	printf("\n");	for (k=0;k<9;k++) printf(" %5d     ",both[k+i]);	printf("\n");	for (k=0;k<9;k++) printf("A B | C    ");	printf("\n\n");	for (A=0; A<3; A++) {		for (B=0; B<3; B++) {			index = 3*A + B;			for (k=0;k<9;k++) printf("%d %d | %d    ", A, B, h[both[k+i]][index]);			printf("\n");		}		printf("\n");	}	printf("\n");}int print_specific_truthtable(int i){	int A, B, C, index;	// print this table	printf("\nA B | C\n\n");	for (A=0; A<3; A++) {		for (B=0; B<3; B++) {			index = 3*A + B;			printf("%d %d | %d \n", A, B, h[i][index]);		}	}	printf("\n");}int Associative(int i) {	int table;	int a,b,c,d;	int A,B,C,D;	int j, k, count;	// transcribe the linear 9 long h table into a 3x3 array for clarity	for (A=0;A<3;A++) {		for (B=0;B<3;B++) {			table[A][B] = h[i][3*A + B];		}	}	// generate 27 test cases for (table(A,B),C) =? (table(A,f(B,C))	count = 0;	for (A=0;A<3;A++) {		for (B=0;B<3;B++) {			for (C=0;C<3;C++) {				a = table[A][B];				b = table[a][C];				c = table[B][C];				d = table[A][c];				if (b==d) count++;			}		}	}	return (count == 27);}void permute(int i) {	int table;	int permuted_table;	int p;	// permutations. 0 1 2, 0 2 1, 1 0 2, 1 2 0, 2 1 0, 2 0 1	int a,b,c,d;	int A,B,C,D;	int j, k, count;	int local;	// save local results for printing	int id;	int index;	// transcribe the linear 9 long h table into a 3x3 array for clarity	for (A=0;A<3;A++) {		for (B=0;B<3;B++) {			table[A][B] = h[i][3*A + B];		}	}// *************************	p = 0; p = 1; p = 2;		// straight order initially	for (A=0;A<3;A++) {		for (B=0;B<3;B++) {			permuted_table[p[A]][p[B]] = p[table[A][B]];		}	}	for (A=0;A<3;A++) {		for (B=0;B<3;B++) {			local[3*A + B] = permuted_table[A][B];		}	}	p = 0; p = 2; p = 1;		// 021	for (A=0;A<3;A++) {		for (B=0;B<3;B++) {			permuted_table[p[A]][p[B]] = p[table[A][B]];		}	}	for (A=0;A<3;A++) {		for (B=0;B<3;B++) {			local[3*A + B] = permuted_table[A][B];		}	}	p = 1; p = 0; p = 2;		// 102	for (A=0;A<3;A++) {		for (B=0;B<3;B++) {			permuted_table[p[A]][p[B]] = p[table[A][B]];		}	}	for (A=0;A<3;A++) {		for (B=0;B<3;B++) {			local[3*A + B] = permuted_table[A][B];		}	}	p = 1; p = 2; p = 0;		// 120	for (A=0;A<3;A++) {		for (B=0;B<3;B++) {			permuted_table[p[A]][p[B]] = p[table[A][B]];		}	}	for (A=0;A<3;A++) {		for (B=0;B<3;B++) {			local[3*A + B] = permuted_table[A][B];		}	}	p = 2; p = 0; p = 1;		// 201	for (A=0;A<3;A++) {		for (B=0;B<3;B++) {			permuted_table[p[A]][p[B]] = p[table[A][B]];		}	}	for (A=0;A<3;A++) {		for (B=0;B<3;B++) {			local[3*A + B] = permuted_table[A][B];		}	}	p = 2; p = 1; p = 0;		// 210	for (A=0;A<3;A++) {		for (B=0;B<3;B++) {			permuted_table[p[A]][p[B]] = p[table[A][B]];		}	}	for (A=0;A<3;A++) {		for (B=0;B<3;B++) {			local[3*A + B] = permuted_table[A][B];		}	}// ************************	// print and calculate index	for (i=0;i<6;i++) {		id[i] = 0;		for (j=0;j<9;j++) {			id[i] *= 3;			id[i] += local[i][j];		}	}// ****************************		// print this table	printf("\n");	for (k=0;k<6;k++) printf(" %5d     ",id[k]);	printf("\n");	for (k=0;k<6;k++) printf("A B | C    ");	printf("\n\n");	for (A=0; A<3; A++) {		for (B=0; B<3; B++) {			index = 3*A + B;			for (k=0;k<6;k++) printf("%d %d | %d    ", A, B, local[k][index]);			printf("\n");		}		printf("\n");	}	printf("\n");}int main(void){	int i,j,k;	int left, right;	int f, g;	// local function tables	int a, b, c;	int A, B, C;	int scratch, index, count, linebreaker;	int nassoc, ncommut;		int max_count = 19683;	// 3^9 = 19683	for (i=0;i<19683;i++) {	//test our array-stuffing algorithm		scratch = i;	// do the modulo 3 decomposition on a local copy of the loop variable.		for (j=0;j<9;j++) {			k = 8-j;	// make the end of the truth table change the fastest			h[i][k] = scratch % 3;	// get least significant trinary digit			scratch /= 3;		// divide by three to expose next digit					}			// at this point, h[i,x] should have digits corresponding to truth table column. 	}	// print out first fifteen entries//	for (i=0;i<15;i++)//	{//		print_specific_truthtable(i);//	}//	print_9(0);//	print_9(9);//	print_9(18);//	check for commutating logic		printf("\n\nCommutators\n");	linebreaker = 0;	for (i=0;i<19683;i++) {		count = 0;		for (j=0;j<9;j++) {			A = j%3;			B = j/3;			k = 3*A + B;	// other index			if (h[i][j] == h[i][k]) count++;		}		if (count == 9) {			if ((linebreaker % 18) == 0) printf("\n");			printf("%5d ",i);			commutators[linebreaker] = i;			linebreaker++;		}			}	printf("\n\nNumber of commutative functions = %d of 19683\n\n",linebreaker);		printf("\n\nAssociators\n");	linebreaker = 0;	for (i=0;i<19683;i++) {		if (Associative(i)) {			if ((linebreaker % 18) == 0) printf("\n");			printf("%5d ",i);			associators[linebreaker] = i;			linebreaker++;		}			}	printf("\n\nNumber of associative functions = %d of 19683\n\n",linebreaker);	// now, report the combined commutator and associator functions.	nassoc =  113;	ncommut = 729;	linebreaker = 0;	printf("\n\nBoth Associative and Commutative\n");	for (i=0;i<nassoc;i++) {		for (j=0;j<ncommut;j++){			if (associators[i] == commutators[j]) {				if ((linebreaker % 18) == 0) printf("\n");				printf("%5d ",associators[i]);				both[linebreaker] = associators[i];				linebreaker++;			}		}	}	printf("\n\nNumber of both associative and commutative functions = %d of 19683\n\n",linebreaker);	// print these out	print9ofboth( 0);	print9ofboth( 9);	print9ofboth(18);	print9ofboth(27);	print9ofboth(36);	print9ofboth(45);	print9ofboth(54);	permute(1);	permute(2);	permute(32);	permute(83);	permute(112);	permute(113);	permute(142);	permute(1536);	permute(1617);	permute(3168);	permute(4069);}`