bool

simple boolean algebra solver
Log | Files | Refs

expr.c (2007B)


      1 #include <stdio.h>
      2 #include <stdbool.h>
      3 #include <stdlib.h>
      4 #include <ctype.h>
      5 #include <string.h>
      6 
      7 #include "expr.h"
      8 
      9 #define SAME(s1, s2) (strcmp(s1, s2) == 0)
     10 
     11 extern FILE *yyin;
     12 extern void yyparse();
     13 extern btree *program;
     14 extern char vars[26];
     15 bool vals[26];
     16 
     17 bool
     18 eval(btree *p) {
     19 	bool l, r;
     20 	switch (p->op) {
     21 	case '.': 
     22 		l = eval(p->left);
     23 		r = eval(p->right);
     24 		return l && r;	
     25 	case '+': 
     26 		l = eval(p->left);
     27 		r = eval(p->right);
     28 		return l || r;	
     29 	case '!': 
     30 		l = eval(p->left);
     31 		return !l;	
     32 	default:
     33 		return vals[p->op - 65];
     34 	}
     35 }
     36 
     37 bool
     38 read_bool(char *s) {
     39 	if (s[1] != '\n') goto err;
     40 
     41 	switch (*s) {
     42 	case '0': return false;
     43 	case '1': return true;
     44 	}
     45 err:
     46 	fprintf(stderr, "expected 1 or 0\n");
     47 	return false;
     48 }
     49 
     50 void
     51 incvars() {
     52 	int carry = 1;
     53 	for (int i = 0; i < 26 && carry; i++) {
     54 		if (vars[i]) {
     55 			if (!vals[i]) carry = 0;
     56 			vals[i] = !vals[i];
     57 		}
     58 	}
     59 }
     60 
     61 void
     62 mktable() {
     63 	bool start[26] = {false};
     64 	memcpy(start, vals, 26);
     65 
     66 	for (int i = 0; i < 26; i++) 
     67 		if (vars[i])
     68 			printf("%c | ", vars[i]);
     69 	printf("RES\n");
     70 
     71 	do {
     72 		for (int i = 0; i < 26; i++) 
     73 			if (vars[i])
     74 				printf("%b | ", vals[i]);
     75 		printf("%b\n", eval(program));
     76 		incvars();
     77 	} while (memcmp(start, vals, 26) != 0);
     78 }
     79 
     80 int 
     81 main(int argc, char **argv) {
     82 	yyin = stdin;
     83 	if (argc > 1)
     84 		yyin = fopen(argv[1], "r");
     85 	if (!yyin) {
     86 		fprintf(stderr, "failed to open file, using stdin\n");
     87 		yyin = stdin;
     88 	}
     89 
     90 	yyparse();
     91 
     92 	char line[128];
     93 	bool res = eval(program);
     94 
     95 	for (;;) {
     96 		printf("> ");
     97 		fgets(line, 128, stdin);
     98 		if (isupper(line[0])) {
     99 			vals[(int)line[0] - 65] = read_bool(line + 2);
    100 		}
    101 		else if (SAME(line, "s\n")) 
    102 			printf("res = %s\n", (res) ? "true" : "false");
    103 		else if (SAME(line, "q\n")) 
    104 			break;
    105 		else if (SAME(line, "p\n")) {
    106 			for (int i = 0; i < 26; i++) {
    107 				if (vars[i])
    108 					printf("%c = %s\n", vars[i], (vals[i]) ? "true" : "false");
    109 			}
    110 		}
    111 		else if (SAME(line, "t\n")) {
    112 			mktable();
    113 		}	
    114 		else
    115 			fprintf(stderr, "?\n");
    116 	}
    117 	
    118 	fclose(yyin);
    119 	return 0;
    120 }