/*
* cobop.c - composition of boolean operators. 2 jun 2003
*
* For each trinary operator, find out how
* may compositions of binary operators of the form
*
* ( a bop1 b ) bop2 c
*
* are equivalent to it. Then, in an initial exercise,
* we will print out a "frequency of sums" histogram.
* This will guide us in constructing a pretty format
* for printing out a "matrix of sums."
*
* THE KEY TRICK in this program is: you can use the number formed
* by Boolean operand bits as an index into a "bit string"
* representing the operator in order to get the result of
* an arbitrary operation with arbitrary operands. I presume
* readers of this code are familiar with my essay "Binary,
* Trinary and Quaternary Boolean Operators" (m3peeps.org/btqbo.htm)
*
* NOTE: You are free to use, modify, re-distribute, etc., this
* code however you wish. If you use more than a few snips,
* I would appreciate it if you include this text along with
* the advertisement for my essay. Thanks. - rc@m3peeps.org
*
* AD: Read "Manifesto for the Peoples of the Third Millennium"
* m3peeps.org/manif.htm
*
* ALSO NOTE: I wrote a "four dimensional" variation on this program that
* uses the ncurses library:
* m3peeps.org/coqo.c
*
*/
#include
static unsigned char tops[ 256 ];
//static unsigned char sums[ 256 ];
int main ( int argc, char * argv[] ) {
unsigned char bop1, bop2, top; // operators.
unsigned char ndx1, ndx2, res1, res2;
unsigned char operands;
int i;
for ( bop1 = 0; bop1 < 16; bop1++ ) {
for ( bop2 = 0; bop2 < 16; bop2++ ) {
top = 0;
for ( operands = 0; operands < 8; operands++ ) {
/* We have two operator bytes of the form 0000wxyz,
* where:
* w = 0 op 0,
* x = 0 op 1,
* y = 1 op 0 and
* z = 1 op 1.
* We have an operands byte of the form 00000abc,
* where a is the first operand, b is the second
* operand and c is the third operand.
* We are constructing a trinary operator byte
* so that the bit corresponding to the operand set
* a, b and c is 1 or 0 according to the result
* ( a bop1 b ) bop2 c.
*/
// prepare index into bop1 based on operands
// a and b:
ndx1 = operands >> 1;
// get result of a bop1 b:
res1 = ( 0x08 >> ndx1 ) & bop1;
// prepare index into bop2 based on result of
// "a bop1 b" and operand c:
ndx2 = ( res1 ? 0x02 : 0x00 )
| ( operands & 0x01 );
// get final result:
res2 = ( 0x08 >> ndx2 ) & bop2;
// if result is non-zero, OR a 1 bit into
// appropriate position of trinary operator
// byte:
if ( res2 ) {
top |= ( 0x80 >> operands );
}
}
tops[ top ]++;
}
}
/*
// build the sums table:
for ( i = 0; i < 256; i++ ) {
sums[ tops[ i ] ]++;
}
// print out non-zero entries:
for ( i = 0; i < 256; i++ ) {
if ( sums[ i ] ) {
printf( "\t%6d\t%6d\n", i, sums[ i ] );
}
}
The output of the above code was:
0 168
2 84
22 4
*/
for ( i = 0; i < 256; i++ ) {
char num[ 4 ] = "xx ";
sprintf( num, "%02d ", tops[ i ] );
printf( "%s", tops[ i ] ? num : ".. " );
if ( ( i & 0x03 ) == 0x03 )
printf( " " );
if ( ( i & 0x0f ) == 0x0f )
printf( "\n" );
if ( ( i & 0x3f ) == 0x3f )
printf( "\n" );
}
}