Espresso.mod
作者:互联网
Espresso功能强大。处理16 in 40 out时不仅速度很快,而且只用了494x359的矩阵。集合则多到了用set family的程度,所占空间我没数,想必不会太多,因为494x359它就用稀疏矩阵来存了,row和column都是排序的双链表。那个时代内存好贵。
一个简单的例子: 输入: i 2 o 3 00 000 01 001 10 011 11 111 计算2**n - 1的真值表。输入为2位ab,输出为3位xyz. Espresso处理后: 11 100 -1 001 1- 011 11代表a&b, -1代表b,1-代表a。100, 001和011中只有100的x为1,对应的是11,即x=a&b. 然后y=a, c等于b|a. 真值表正确。
gcc -w *.c即可编译,a.out或a.exe filename处理。*.txt是测试文件。博客园下载 101KB 含a.exe. -w 是忽略所有警告。
int main(int argc, char* argv[]) { puts("A simplified version of Espresso V2.3 (Released by UC Berkeley on 01/31/1988)"); if (argc != 2) fatal("Usage: %s file", argv[0]); // F: on-set, R: off-set, D: don't case-set PLA_t* p = pla_load(argv[1]); // PLA: Programmable Logic Array pset_family F = sf_save(p->F); // sf: set_family p->F = espresso(p->F, p->D, p->R); // returns a set_family* if (verify(p->F, F, p->D)) fatal("Verification failed"); sf_free(F); pla_print(p); pla_free(p); cube_cleanup(); sf_cleanup(); extern int max_row, max_col, irred; printf("matrix: max_row=%d, max_col=%d irred=%d\n", max_row, max_col, irred); }
main很好懂,如果把espresso看作黑盒子的话。不支持复杂格式的pla_load一点都不mess:
static PLA_t* pla_load(const char* fname) { FILE* fp = fopen(fname, "rt"); if (!fp) fatal("Unable to open file"); char s[256], _[64]; int n_i, n_o; fgets(s, sizeof(s), fp); sscanf(s, "%s%d%s%d", _, &n_i, _, &n_o); printf("%d inputs and %d outputs\n", n_i, n_o); PLA_t* p = (PLA_t*)calloc(1, sizeof(PLA_t)); cube.num_vars = (cube.num_binary_vars = n_i) + 1; cube.part_size = ALLOC(int, n_i + 1); cube.part_size[n_i] = n_o; cube_setup(); p->F = new_cover(10); p->D = new_cover(10); while (fgets(s, sizeof(s), fp)) { const char* ss = s; pcube cf = cube.temp[0], cd = cube.temp[1]; int savef = 0, saved = 0; set_clear(cf, cube.size); for(int var = 0; var < n_i; var++) { switch(*ss++) { case '0': set_insert(cf, var * 2); break; case '1': case '-': set_insert(cf, var * 2 + 1); break; default: fatal("Error: %s", s); } } while (*ss++ == ' '); --ss; set_copy(cd, cf); for(int i = cube.first_part[n_i]; i <= cube.last_part[n_i]; i++) { switch(*ss++) { case '0': break; case '1': set_insert(cf, i); savef = TRUE; break; case '-': set_insert(cd, i); saved = TRUE;break; default: fatal("Error: %s", s); } } if (savef) p->F = sf_addset(p->F, cf); if (saved) p->D = sf_addset(p->D, cd); } fclose(fp); p->R = complement(cube2list(p->F, p->D)); pla_print_cost(p); return p; }
然后我实在整不动了。我倒是知道数一个32-bit-int里的1的个数的方法,一本叫"Hacker's Delight"的书里讲过,ffmpeg的源码里也有类似的。可他们是怎么想出来的?Espresso好像也不能解决这个问题: 它倒是能给出逻辑表达式,但一串not, and, or,不是shift, xor等。数1的话,把int分成4个byte来数也不慢,事实上Espresso有个bit_count[256].
标签:set,int,Espresso,cf,cube,pla,mod 来源: https://www.cnblogs.com/funwithwords/p/15748971.html