From 5a2f6687f681fa0ceff19a42ec9ddce479e67c48 Mon Sep 17 00:00:00 2001 From: Pedro Souza Date: Thu, 4 Apr 2024 01:52:22 -0300 Subject: added truth table and expression evaluator --- truth_table.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 truth_table.c (limited to 'truth_table.c') diff --git a/truth_table.c b/truth_table.c new file mode 100644 index 0000000..9ae9463 --- /dev/null +++ b/truth_table.c @@ -0,0 +1,77 @@ +#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'); + } +} + -- cgit v1.2.3