home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************************
- *
- * Program name : LOGMIN_A.C
- *
- * Written By : Eng-Huat Ong and Kian-Mong Low.
- *
- * This is where the original LOGMIN algorithmn is implemented.
- *
- * --------------------------------------------------------------------------
- * Copyright (c) 1992. All Rights Reserved. Nanyang Technological
- * University.
- *
- * You are free to use, copy and distribute this software and its
- * documentation providing that:
- *
- * NO FEE IS CHARGED FOR USE, COPYING OR DISTRIBUTION.
- *
- * IT IS NOT MODIFIED IN ANY WAY.
- *
- * THE COPYRIGHT NOTICE APPEAR IN ALL COPIES.
- *
- * This program is provided "AS IS" without any warranty, expressed or
- * implied, including but not limited to fitness for any particular
- * purpose.
- *
- * If you find NTUMIN fast, easy, and useful, a note or comment would be
- * appreciated. Please send to:
- *
- * Boon-Tiong Tan or Othman Bin Ahmad
- * School of EEE
- * Nanyang Technological University
- * Nanyang Avenue
- * Singapore 2263
- * Republic of Singapore
- *
- ***************************************************************************/
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #define mask8 255
-
- unsigned char *logmin_a(a, b) /* pointer to a & b array passed */
- unsigned char *a, *b;
-
- {
- unsigned short pterm, ma, mb, pos;
- unsigned short *ca, *mp, m_cnt;
- unsigned long m, j, size, addr, count, count1, topow();
- register long i, wo, wi;
- char test;
- unsigned char *c, *d, *e, *s, *temp, *cp, *mt, *at, *ad;
- unsigned char n, adj, adj0, adji, adjacency(), nspm, cover;
- unsigned char *adjacent(), *reduce(), *cpt(), *ssm(), adj_of_mi();
-
-
- mb = *(b+2)<<8 | *(b+1); /* no. of minterms in b-array */
-
- n = *a; /* no. of variables */
- nspm = *(a+3); /* no. of bytes/minterm */
- ma = *(a+2)<<8 | *(a+1); /* no. of minterms in a-array */
-
- temp = (unsigned char *) malloc(nspm+1); /* temporary storage */
- if (temp == 0)
- {
- printf("Out of memory -- LOGMIN_A, *temp\n");
- printf("Program terminated - 1\n");
- exit(0);
- }
-
- s = (unsigned char *) malloc(4); /* header of s-array */
- if (s == 0)
- {
- printf("Out of memory -- LOGMIN_A, *s\n");
- printf("Program terminated - 2\n");
- exit(0);
- }
-
-
- /***********\
- * PHASE I *
- \***********/
-
- pterm = 0; /* no. of product term */
- count = 0; /* no. of terms stored for phase II */
-
- /***
- *** DETERMINE ADJACENCY OF ALL MINTERMS AND GENERATE THEIR CPT
- ***/
-
- for (i=0; i<mb; i++) /* for all minterms in b-array */
- {
- *b = n; /* assign back to n */
-
- memcpy(temp, (b+4+nspm*i), nspm); /* pick a minterm from b-array */
- c = adjacent(temp, a, 255); /* obtain the adjacent terms */
- adj = *(c+1); /* adjacency of minterm */
- d = cpt(c); /* generate CPT */
-
- /***
- *** MINIMIZE ALL MINTERMS WITH ADJACENCY OF 0 & 1 FIRST
- ***/
-
- if (adj <= 1) /* adjacency 0 or 1 */
- {
- s = (unsigned char *) realloc(s,4+n*(pterm+1)); /* more space */
- if (s == 0)
- {
- printf("Out of memory -- LOGMIN_A, *s\n");
- printf("Program terminated - 3\n");
- exit(0);
- }
- memcpy ((s+4+n*pterm),d,n); /* add CPT to soln array */
- pterm++; /* product term count */
-
- b = reduce(c,b,i); /* remove minterms covered from b-array */
- i = (char) *b; /* index pointer of b-array */
- mb = *(b+2)<<8 | *(b+1); /* value of mb altered in b-array */
- }
- else /* adj > 1 */
- {
-
- /***
- *** MINTERMS WITH ADJACENCY GREATER THAN 1, GENERATE SSM AND TEST FOR COVERAGE
- ***/
-
- e = ssm(d); /* generate SSM */
- m = topow(*(e+1)); /* no. of SSM terms */
-
- for (j=0; j<m; j++) /* check for SSM coverage */
- {
- memcpy (temp, (e+4+nspm*j), nspm); /* pick SSM term */
- test = exist (temp, a, ma);
- if (test == -1) /* minterm not in a-array */
- break;
- }
-
- /***
- *** ALL SSM COVERED BY THE FUNCTION, SELECT CPT AS PRODUCT TERM
- ***/
-
- if (test == 0) /* all SSM's covered by fn */
- {
- if (m > 65536) /* too many SSM terms */
- {
- printf("Product Term Too Huge \n");
- printf("Program terminated \n");
- exit(0);
- }
- *e = n; /* no. of variables */
- *(e+1) = (m-1) & mask8; /* no. of SSM terms minus 1 */
- *(e+2) = (m-1)>>8 & mask8;
- b = reduce(e,b,i); /* remove minterms covered from b-array */
- i = (char) *b; /* index pointer of b-array */
- mb = *(b+2)<<8 | *(b+1); /* no. of minterms in b-array */
-
- s = (unsigned char *) realloc(s, 4+n*(pterm+1)); /* more space */
- if (s == 0)
- {
- printf("Out of memory -- LOGMIN_A, *s\n");
- printf("Program terminated - 4\n");
- exit(0);
- }
- memcpy((s+4+n*pterm),d,n); /* add CPT to soln array */
- pterm++; /* no. of product terms */
- }
- else
- {
- /***
- *** NOT COVERED, STORE UNCOVERED MINTERMS, ITS CORRESPONDING
- *** ADJACENCY, ADJACENT TERMS AND CPT FOR PHASE II
- ***/
-
- count++; /* no. of terms for phase II */
- if (count==1) /* 1st uncovered term */
- {
- ad = (unsigned char *) malloc(1); /* array of adjacency */
- if (ad==0)
- {
- printf("Out of memory -- LOGMIN_A, *ad\n");
- printf("Program terminated - 5\n");
- exit(0);
- }
- cp = (unsigned char *) malloc(n); /* array of CPT's */
- if (cp==0)
- {
- printf("Out of memory -- LOGMIN_A, *cp\n");
- printf("Program terminated - 6\n");
- exit(0);
- }
- mt = (unsigned char *) malloc(4+nspm*count); /* array of minterms */
- if (mt==0)
- {
- printf("Out of memory -- LOGMIN_A, *mt\n");
- printf("Program terminated - 7\n");
- exit(0);
- }
- size = 4 + nspm*(1+adj); /* addr counter of at-array */
- at = (unsigned char *) malloc (4+nspm*(1+adj)); /* all adj terms from c-arrays */
- if (at==0)
- {
- printf("Out of memory -- LOGMIN_A, *at\n");
- printf("Program terminated - 8\n");
- exit(0);
- }
- ca = (unsigned short *) malloc(2); /* array of addr of at-array */
- if (ca==0)
- {
- printf("Out of memory -- LOGMIN_A, *ca\n");
- printf("Program terminated - 9\n");
- exit(0);
- }
- addr = 0; /* starting address of at-array */
- }
- else /* subsequent uncovered terms */
- {
- ad = (unsigned char *) realloc(ad, count); /* adjacency */
- if (ad==0)
- {
- printf("Out of memory -- LOGMIN_A, *ad\n");
- printf("Program terminated - 10\n");
- exit(0);
- }
- cp = (unsigned char *) realloc(cp,n*count); /* CPT's */
- if (cp==0)
- {
- printf("Out of memory -- LOGMIN_A, *cp\n");
- printf("Program terminated - 11\n");
- printf("n = %d, count = %d\n", n, count);
- exit(0);
- }
- mt = (unsigned char *) realloc(mt,4+nspm*count); /* minterms */
- if (mt==0)
- {
- printf("Out of memory -- LOGMIN_A, *mt\n");
- printf("Program terminated - 12\n");
- exit(0);
- }
- size+=4+nspm*(1+adj); /* addr counter of at-array */
- at = (unsigned char *) realloc (at,size); /* all adj terms from c-arrays */
- if (mt==0)
- {
- printf("Out of memory -- LOGMIN_A, *mt\n");
- printf("Program terminated - 13\n");
- exit(0);
- }
- ca = (unsigned short *) realloc(ca,2*count); /* addr of at-array */
- if (ca==0)
- {
- printf("Out of memory -- LOGMIN_A, *ca\n");
- printf("Program terminated - 14\n");
- exit(0);
- }
- }
-
- /***
- *** STORE IN ARRAYS FOR PHASE II
- ***/
-
- *(ad+(count-1)) = adj; /* adjacency */
- memcpy((cp+n*(count-1)),d,n); /* CPT's */
- memcpy((mt+4+nspm*(count-1)),(b+4+nspm*i),nspm); /* minterms */
- memcpy((at+addr),c,4+nspm*(1+adj)); /* adj terms */
- *(ca+(count-1)) = addr; /* addr of at-array */
- addr = size; /* update addr */
- }
- free(e); /* free pointer */
- }
- free(c); /* free pointers */
- free(d);
- }
- count1 = count; /* no. of terms for phase II */
-
-
- /************\
- * PHASE II *
- \************/
-
- while (count > 0) /* some terms stored for phase II */
- {
- /***
- *** SELECT NEXT MINTERM WITH THE LOWEST ADJACENCY AND AT LEAST ONE OF
- *** ITS ADJACENT TERMS PREVIOUSLY COVERED
- ***/
-
- adj0 = 255; /* set to max of 8-bit */
-
- for (i=0; i<count1; i++) /* do for all adj terms in phase II */
- {
- if (*(ad+i)<adj0 && *(ad+i)!=0) /* choose minterms with lowest adj */
- {
- if (adj0 != 255) /* not the first lowest */
- free(mp);
- adj0 = *(ad+i); /* new lowest value */
- m_cnt = 1; /* reset count to 1 */
-
- mp = (unsigned short *) malloc(2); /* space for pos of lowest adj */
- if (mp==0)
- {
- printf("Out of memory -- LOGMIN_A, *mp\n");
- printf("Program terminated - 15\n");
- exit(0);
- }
- *mp = i; /* first element */
- }
- else if (*(ad+i) == adj0) /* adj as large */
- {
- m_cnt++; /* no. of element in mp-array */
- mp = (unsigned short *) realloc(mp, 2*m_cnt); /* more space */
- if (mp==0)
- {
- printf("Out of memory -- LOGMIN_A, *mp\n");
- printf("Program terminated - 16\n");
- exit(0);
- }
- *(mp+m_cnt-1) = i; /* elements in mp-array */
- }
- }
-
- /***
- *** SELECT FROM MP-ARRAY, A MINTERM WITH AT LEAST ONE ADJACENT TERM PREVIOSLY
- *** COVERED
- ***/
-
- for (i=0; i<m_cnt; i++) /* do for all in mp-array */
- {
- adj = *(ad+ *(mp+i)); /* adjacency from ad-array */
-
- c = (unsigned char *) malloc(4+nspm*(1+adj)); /* space for adj terms */
- if (c == 0)
- {
- printf("Out of memory -- LOGMIN_A, *c\n");
- printf("Program terminated - 17\n");
- exit(0);
- }
- memcpy(c, (at+ *(ca+ *(mp+i))), 4+nspm*(1+adj)); /* adj terms from at-array */
-
- for (j=0; j<adj; j++) /* check for at least 1 adj term covered */
- {
- memcpy(temp, (c+4+nspm*(1+j)),nspm);
- test = exist(temp,b,mb);
- if (test == -1) /* adj term covered */
- break;
- }
-
- if (test == -1) /* adj term covered */
- break;
- else
- free(c); /* free pointer */
- }
-
- if (test == -1) /* adj term covered */
- pos = *(mp+i); /* position of minterm required */
- else /* none of adj terms covered */
- {
- adj = *(ad+ *mp); /* choose adj of 1st minterm */
- pos = *mp; /* position of 1st minterm */
-
- c = (unsigned char *) malloc(4+nspm*(1+adj)); /* space for adj terms */
- if (c == 0)
- {
- printf("Out of memory -- LOGMIN_A, *c\n");
- printf("Program terminated - 18\n");
- exit(0);
- }
- memcpy(c, (at+ *(ca+pos)), 4+nspm*(1+adj)); /* adj terms from at-array */
- }
-
- d = (unsigned char *) malloc(n+1); /* space for corresponding CPT */
- if (d == 0)
- {
- printf("Out of memory -- LOGMIN_A, *d\n");
- printf("Program terminated - 19\n");
- exit(0);
- }
- memcpy(d, (cp+n*pos), n); /* corresponding CPT from cp-array */
- *(d+n) = '\0'; /* terminate with NULL string */
-
- e = ssm(d); /* generate SSM */
-
- free(d); /* free pointers */
- free(mp);
-
- /***
- *** KEEP SHRINKING THE CPT UNTIL THE SELECTED MINTERM IS COVERED BY THE FUNCTION
- ***/
-
- cover = 0; /* coverage status */
- while (!cover) /* do until shrinked CPT is covered */
- {
- /***
- *** SELECT THE 1ST ADJACENT TERM WITH THE LOWEST WI TO SHRINK AWAY
- *** WI IS THE NO. OF TERMS ADJACENT TO THE ADJACENT TERMS THAT ARE
- *** SSM, E-ARRAY BUT NOT IN THE FUNCTION, A-ARRAY
- ***/
-
- wo = -1; /* initial value */
- for (i=0; i<adj; i++) /* do for all adjacent terms */
- {
- memcpy(temp, (c+4+nspm*(i+1)), nspm); /* pick adjacent term */
-
- wi = adj_of_mi(temp,e,a); /* obtain wi */
- if (wi>wo)
- {
- wo = wi; /* new largest value */
- pos = i; /* position of adj terms */
- }
- }
- free(e); /* free pointer */
-
- adj--; /* decrement adjacency */
- *(c+1) = adj; /* update in c-array */
-
- memcpy((c+4+nspm*(1+pos)), (c+4+nspm*(2+pos)), nspm*(adj-pos)); /* shrink c-array */
-
- c = (unsigned char*) realloc(c, 4+nspm*(1+adj)); /* decrease space */
- if (c == 0)
- {
- printf("Out of memory -- LOGMIN_A, *c\n");
- printf("Program terminated - 20\n");
- exit(0);
- }
-
- d = cpt(c); /* generate CPT */
- e = ssm(d); /* generate SSM */
- m = topow(*(e+1)); /* no. of SSM terms */
-
- for (i=0; i<m; i++) /* check SSM coverage by function */
- {
- memcpy(temp, (e+4+nspm*i), nspm); /* pick SSM term */
- test = exist(temp,a,ma);
- if (test == -1) /* SSM not covered */
- break;
- }
-
- /***
- *** SHRINKED SSM COVERED BY FUNCTION, REDUCE B-ARRAY AND
- *** SELECT SHRINKED CPT AS PRODUCT TERM
- ***/
-
- if (test==0) /* SSM covered */
- {
- if (m > 65536) /* too many SSM terms */
- {
- printf("Product Term Too Huge \n");
- printf("Program terminated \n");
- exit(0);
- }
- *e = n; /* no. of variables */
- *(e+1) = (m-1) & mask8; /* no. of SSM terms minus 1 */
- *(e+2) = (m-1)>>8 & mask8;
- b = reduce(e, b, m); /* remove minterms covered from b-array */
- mb = *(b+2)<<8 | *(b+1); /* no. of minterms in b-array */
-
- count = mb; /* count of no. of minterms not covered */
-
- s = (unsigned char *) realloc(s, 4+n*(pterm+1)); /* more space */
- if (s == 0)
- {
- printf("Out of memory -- LOGMIN_A, *s\n");
- printf("Program terminated - 21\n");
- exit(0);
- }
- memcpy ((s+4+n*pterm), d, n); /* add shrinked CPT to soln array */
- pterm++; /* no. of product terms */
-
- cover = 1; /* coverage status */
-
- /***
- *** FLAG TERMS COVERED IN THE AD-ARRAY
- ***/
-
- for (i=0; i<m; i++) /* flag terms just covered */
- {
- for (j=0; j<count1; j++) /* do for all terms in mt-array */
- {
- test = memcmp((e+4+nspm*i), (mt+4+nspm*j), nspm);
- if (test==0)
- {
- *(ad+j) = 0; /* flag the adjacency to indicate coverage */
- break;
- }
- }
- }
- free(e); /* free pointer */
- }
- free (d); /* free pointer */
- }
- free(c); /* free pointer */
- }
-
- if (count1>0) /* some terms stored for phase II */
- {
- free(ad); /* free pointers */
- free(cp);
- free(mt);
- free(at);
- free(ca);
- }
-
- *s = n; /* no. of variables */
- *(s+1) = pterm & mask8; /* no. of product terms in 2 bytes */
- *(s+2) = pterm>>8 & mask8;
-
- free(temp); /* free pointer */
- free(a);
- free(b);
-
- return(s); /* return solution array */
- }
-
-