/* * implicants.c * Implicant functions for quine.c. * * Copyleft 2002 Chris Williams. */ #include #include #include "implicants.h" #include "types.h" #include "lists.h" #include "error.h" literals_t MSb; /******************************************************************************* * one_count: returns number of one literals in implicant A *******************************************************************************/ int one_count (implicant_t *A) { int count = 0; literals_t bit = MSb; for (; bit; bit >>= 1) if ((A->expr & bit) && (A->care & bit)) ++count; return count; } /******************************************************************************* * zero_count: returns number of zero literals in implicant A *******************************************************************************/ int zero_count (implicant_t *A) { int count = 0; literals_t bit = MSb; for (; bit; bit >>= 1) if ((A->expr & bit) == 0 && (A->care & bit)) ++count; return count; } /******************************************************************************* * x_count: returns number of don't-cares in implicant A *******************************************************************************/ int x_count (implicant_t *A) { int count = 0; literals_t bit = MSb; for (; bit; bit >>= 1) if ((A->care & bit) == 0) ++count; return count; } /******************************************************************************* * covers: returns true if implicant A covers implicant B *******************************************************************************/ boolean_t covers (implicant_t *A, implicant_t *B) { /* A's don't-cares cover all of B's don't-cares * and A's cares are equal to B's cares less A's don't-cares */ return (A->care & ~B->care) == 0 && (A->expr & A->care) == (B->expr & A->care); } /******************************************************************************* * can_group: returns true if implicant A can be grouped with implicant B *******************************************************************************/ boolean_t can_group (implicant_t *A, implicant_t *B) { implicant_t C; C.node.next = NULL; C.expr = A->expr ^ B->expr; C.care = A->care; /* A and B are same size and are adjacent */ return A->care == B->care && one_count (&C) == 1; } /******************************************************************************* * is_essential: true if implicant A is an essential implicant in list m *******************************************************************************/ boolean_t is_essential (implicant_t *A, list_t list) { /* determine if A is an EPI of list m. * If A covers any minterm that no other * prime implicant covers, return true. * Otherwise, return false. */ return false; } /******************************************************************************* * get_minterm_list: gets a minterm list from stdin *******************************************************************************/ int get_minterm_list (list_t *list) { /* Get list of minterms from stdin. * To support boolean expressions, pipe * the output of a boolean evaluator * to the input. * Allocate an IMPLICANT for each minterm * obtained from the input. * return -1 on error */ char *bad_format = "Bad File Format\n"; char in[101]; int num_literals, m; literals_t num_minterms = 0; scanf ("%s %d", in, &num_literals); if (toupper (in[0]) == 'L') { if (num_literals > MAXLITERALS) return ERROR ("Cannot handle that many literals - maximum is %d\n", MAXLITERALS); } else return ERROR (bad_format); MSb = 1ULL << (num_literals-1); scanf ("%s %lld", in, &num_minterms); if (toupper (in[0]) != 'M') return ERROR (bad_format); /* loop here to obtain all minterms */ for (m = 0; m < num_minterms; ++m) { implicant_t *implic; int i; scanf("%s", in); /* the file lied about the number of minterms */ if (feof(stdin)) { error ("Too few minterms"); return -1; } implic = (implicant_t *)malloc(sizeof(implicant_t)); /* parse the implicant in 'in' into 'implic' */ for (i = 0; i < num_literals; ++i) { if (in[i] == '\0') return ERROR ("Too few literals in minterm\n"); switch (toupper(in[i])) { case '0': implic->expr &= ~(MSb >> i); implic->care |= MSb >> i; break; case '1': implic->expr |= MSb >> i; implic->care |= MSb >> i; break; case 'X': implic->care &= ~(MSb >> i); break; default: return ERROR ("Invalid symbol in minterm"); } } add_node(&(implic->node), list); } return num_literals; } /******************************************************************************* * implicanttoa: converts implicant A to a string representing the literals *******************************************************************************/ char *implicanttoa (implicant_t * A, char *s) { literals_t mask = MSb; int i = 0; char *str = s; for (; mask; mask >>= 1, ++i) { #if 0 if (A->care & mask) { *(s++) = i + ((i < 26) ? 'A' : 'a' - 26); if (!(A->expr & mask)) *(s++) = '\''; } #else if (A->care & mask) putchar(!!(A->expr & mask) + '0'); else putchar('X'); #endif } *s = '\0'; return str; }