/* * 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" ); } }