#include "truth_table.h" int intpow(int b, int e) { int acc = 1; for (int i = 0; i < e; i++) { acc *= b; } return acc; } struct expr_input_iter expr_input_iter_init(struct truth_table *tt) { return (struct expr_input_iter){ .src = tt, .acc = 0, .count = 0, }; } int32_t expr_input_iter_next(struct expr_input_iter *self) { uint32_t bak = self->acc; if (self->count > self->src->lines_count-1) return -1; for (int i = self->src->letters_count - 1; i >= 0; i--) { uint8_t idx = self->src->letters[i] - 'a'; self->acc ^= 1 << idx; if (self->acc & (1 << idx)) break; } self->count++; return bak; } struct truth_table *truth_table_create(node *root, uint32_t letters_bitfield) { struct truth_table *tt = calloc(1, sizeof(struct truth_table)); char letters[27] = {0}; char letters_needle = 0; for (char i = 0; i <= ('z'-'a'); i++) { if (letters_bitfield & (1 << i)) { letters[letters_needle] = 'a'+i; letters_needle++; } } tt->letters = malloc(letters_needle * sizeof(char)); strncpy(tt->letters, letters, letters_needle); tt->letters_count = letters_needle; tt->lines_count = intpow(2,tt->letters_count); tt->lines = malloc(tt->lines_count * sizeof(uint32_t)); struct expr_input_iter inp_iter = expr_input_iter_init(tt); for (int i = 0; i < tt->lines_count; i++) { int32_t input = expr_input_iter_next(&inp_iter); uint8_t output = eval_tree(root, input); tt->lines[i] = input | (output << 26); } return tt; } void truth_table_destroy(struct truth_table *tt) { free(tt->lines); free(tt->letters); free(tt); } void truth_table_fprint(FILE *stream, struct truth_table *tt) { fprintf(stream, "\t%s | S\n\t", tt->letters); for (int i = 0; i < (tt->letters_count + 4); i++) putc('-', stream); putc('\n', stream); for (int i = 0; i < tt->lines_count; i++) { putc('\t', stream); uint32_t line = tt->lines[i]; for (int j = 0; j < tt->letters_count; j++) { int actual_idx = tt->letters[j] - 'a'; putc((line & (1 << actual_idx))? '1' : '0', stream); } fprintf(stream, " | %c\n", (line & (1 << 26))? '1' : '0'); } }