Skip to content

Instantly share code, notes, and snippets.

@assyrianic
Last active March 7, 2025 06:58
Show Gist options
  • Save assyrianic/43782a430b5567c248fad3da8bf16922 to your computer and use it in GitHub Desktop.
Save assyrianic/43782a430b5567c248fad3da8bf16922 to your computer and use it in GitHub Desktop.
truth table printer for binary logic functions
#include <stdio.h>
/// a*b = min(a,b)
int min(int const a, int const b) {
return a < b? a : b;
}
void print_and(size_t const n, int const set[const static n]) {
for( size_t a=0; a < n; a++ ) {
for( size_t b=0; b < n; b++ ) {
int const A = set[a];
int const B = set[b];
printf("a(%2i) & b(%2i) == %2i\n", A, B, min(A, B));
}
}
}
/// a+b = max(a,b)
int max(int const a, int const b) {
return a > b? a : b;
}
void print_or(size_t const n, int const set[const static n]) {
for( size_t a=0; a < n; a++ ) {
for( size_t b=0; b < n; b++ ) {
int const A = set[a];
int const B = set[b];
printf("a(%2i) + b(%2i) == %2i\n", A, B, max(A, B));
}
}
}
/// ~a = -a
/// (a + 1) mod (n)
int neg(int const a, int const n, int const is_unbalanced) {
return is_unbalanced? n - a : -a;
}
void print_neg(size_t const n, int const set[const static n]) {
for( size_t a=0; a < n; a++ ) {
int const A = set[a];
printf("!a(%2i) == %2i\n", A, neg(A, n, 0));
}
}
int main(void) {
int const tern_set[] = { -1, 0, 1 };
size_t const tern_len = sizeof tern_set / sizeof tern_set[0];
print_and(tern_len, tern_set);
puts("\n");
print_or(tern_len, tern_set);
puts("\n");
print_neg(tern_len, tern_set);
}
#include <stdio.h>
#include <inttypes.h>
#include <stdlib.h>
#include <math.h>
typedef int LogicFunc(int a, int b, int set_len, int balanced);
static inline int min(int const x, int const y) { return x < y? x : y; }
static inline int max(int const x, int const y) { return x < y? y : x; }
static inline int neg1(int const x) { return -x; }
static inline int neg2(int const x, int const n) { return (n-1) - x; }
static inline int neg3(int const x, int const n, int const balanced) {
return balanced? neg1(x) : neg2(x, n);
}
static inline int False(int a, int b, int set_len, int balanced) { return 0; }
static inline int AND(int a, int b, int set_len, int balanced) { return min(a,b); }
static inline int AND_NOTB(int a, int b, int set_len, int balanced) {
return min(a, neg3(b, set_len, balanced));
}
static inline int A(int a, int b, int set_len, int balanced) { return a; }
static inline int AND_NOTA(int a, int b, int set_len, int balanced) { return min(neg3(a, set_len, balanced), b); }
static inline int B(int a, int b, int set_len, int balanced) { return b; }
static inline int XOR(int a, int b, int set_len, int balanced) {
/// x ^ y = x*!y + !x*y
int const x_ny = min(a, neg3(b, set_len, balanced));
int const nx_y = min(neg3(a, set_len, balanced), b);
return max(x_ny, nx_y);
}
static inline int OR(int a, int b, int set_len, int balanced) { return max(a,b); }
static inline int NOR(int a, int b, int set_len, int balanced) {
/// !(a+b) = !a*!b
return neg3(max(a,b), set_len, balanced);
}
static inline int XNOR(int a, int b, int set_len, int balanced) {
/// x ~^ y = !x*!y + x*y
int const nx_ny = min(neg3(a, set_len, balanced), neg3(b, set_len, balanced));
int const x_y = min(a, b);
return max(nx_ny, x_y);
}
static inline int NB(int a, int b, int set_len, int balanced) { return neg3(b, set_len, balanced); }
static inline int IMPLIESB(int a, int b, int set_len, int balanced) { return max(neg3(a, set_len, balanced), b); }
static inline int NA(int a, int b, int set_len, int balanced) { return neg3(a, set_len, balanced); }
static inline int IMPLIESA(int a, int b, int set_len, int balanced) { return max(a, neg3(b, set_len, balanced)); }
static inline int NAND(int a, int b, int set_len, int balanced) { return neg3(min(a,b), set_len, balanced); }
static inline int Truth(int a, int b, int set_len, int balanced) { return 1; }
void idx_to_set(size_t const size, int8_t vars[const restrict static size], size_t const setlen, int const set[const static setlen], size_t idx) {
for( size_t i = size - 1; i < size; i-- ) {
vars[i] = set[idx % setlen];
idx /= setlen;
}
}
void print_truth_table(FILE *stream, size_t const num_vars, size_t const set_len, int const set[const static set_len], LogicFunc logic_func) {
/// for each variable, we need to print a power-of-2 set of operations.
/// 2 vars = truth table of 4 values. 3 vars = 8 values, etc.
int const is_balanced = set[0] < 0;
int8_t *vars = calloc(num_vars, sizeof *vars);
size_t const loops = ( size_t )( lround(pow(set_len, num_vars)) );
for( size_t i=0; i < loops; i++ ) {
idx_to_set(num_vars, vars, set_len, set, i);
int logic_result = logic_func(vars[0], vars[1], set_len, is_balanced);
for( size_t j=0; j < (num_vars - 2); j++ ) {
logic_result = logic_func(vars[j+2], logic_result, set_len, is_balanced);
}
fprintf(stream, "%3zu -- ", i);
for( size_t j=0; j < num_vars; j++ ) {
fprintf(stream, "var%zu(%2i) | ", j+1, vars[j]);
}
fprintf(stream, "result: %2i\n", logic_result);
}
free(vars);
}
int main() {
FILE *stream = stdout;
enum {
MIN_VARS = 2,
MAX_VARS = 1 << 3,
};
size_t num_vars = 0;
do {
printf("enter how many variables you'd like a truth table of (min: 2, max: %i):\n", MAX_VARS);
scanf(" %zu", &num_vars);
} while( num_vars < MIN_VARS );
if( num_vars > MAX_VARS ) {
num_vars = MAX_VARS;
}
char const *logic_names[] = {
"FALSE", "AND", "A AND NOT B", "A",
"NOT A AND B","B","XOR","OR","NOR","XNOR","NOT B","A IMPLIES B",
"NOT A","B IMPLIES A","NAND","TRUE",
};
LogicFunc *const logic_funcs[] = {
False, AND, AND_NOTB, A, AND_NOTA,
B, XOR, OR, NOR, XNOR, NB, IMPLIESB, NA,
IMPLIESA, NAND, Truth,
};
int const binary_set[] = { 0, 1 };
int const balanced_ternary_set[] = { -1, 0, 1 };
int const ternary_set[] = { 0, 1, 2 };
int const quaternary_set[] = { 0, 1, 2, 3 };
#define ARR_LEN(a) (sizeof (a) / sizeof (a)[0])
for( size_t i=0; i < ARR_LEN(logic_funcs); i++ ) {
fprintf(stream, "%s:::\n", logic_names[i]);
print_truth_table(stream, num_vars, ARR_LEN(quaternary_set), quaternary_set, logic_funcs[i]);
fputs("", stream);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment