Initial commit.
This commit is contained in:
295
cnf.c
Normal file
295
cnf.c
Normal file
@@ -0,0 +1,295 @@
|
||||
#include "cnf.h"
|
||||
|
||||
cnf* readDIMACS(char* path) {
|
||||
cnf* c = malloc(sizeof(cnf));
|
||||
CHECK(c, "Failed to alloc CNF struct\n");
|
||||
|
||||
FILE* f = fopen(path, "r");
|
||||
CHECK(f, "Failed to open file\n");
|
||||
|
||||
u32 bufsize = 1000;
|
||||
char* buf = malloc(sizeof(char) * bufsize);
|
||||
CHECK(buf, "Failed to alloc read buffer\n");
|
||||
|
||||
CHECK(fgets(buf, sizeof(char) * bufsize, f), "Failed to read file\n");
|
||||
|
||||
while (buf[0] == 'c') {
|
||||
CHECK(fgets(buf, sizeof(char) * bufsize, f), "Failed to read file\n");
|
||||
}
|
||||
|
||||
char* temp = buf;
|
||||
while (*temp == ' ' || *temp == 'p' || *temp == 'c' || *temp == 'n' || *temp == 'f') {
|
||||
temp++;
|
||||
}
|
||||
|
||||
c->varcnt = 0;
|
||||
while (((u8) (*temp - '0')) < 10) {
|
||||
c->varcnt *= 10;
|
||||
c->varcnt += (*temp - '0');
|
||||
temp++;
|
||||
}
|
||||
|
||||
while (*temp == ' ') temp++;
|
||||
|
||||
c->clausecnt = 0;
|
||||
while (((u8) (*temp - '0')) < 10) {
|
||||
c->clausecnt *= 10;
|
||||
c->clausecnt += (*temp - '0');
|
||||
temp++;
|
||||
}
|
||||
|
||||
u32 nsize = sizeof(char) * (c->varcnt * 12LU) + 10;
|
||||
char* nbuf = realloc(buf, nsize);
|
||||
CHECK(nbuf, "Failed to realloc read buffer\n");
|
||||
|
||||
buf = nbuf;
|
||||
|
||||
u32 cnt = 0;
|
||||
u32 cap = 32;
|
||||
|
||||
c->variables = calloc( cap, sizeof(u32));
|
||||
CHECK(c->variables, "Failed to allocate literal variables\n");
|
||||
c->clauses = calloc( cap, sizeof(u32));
|
||||
CHECK(c->clauses, "Failed to allocate literal clauses\n");
|
||||
c->pars = calloc( cap, sizeof(u8));
|
||||
CHECK(c->pars, "Failed to allocate literal parities\n");
|
||||
c->lastvars = calloc( c->clausecnt, sizeof(u32));
|
||||
CHECK(c->lastvars, "Failed to allocate clause lastvars\n");
|
||||
|
||||
|
||||
for (u32 i = 0; i < c->clausecnt; ++i) {
|
||||
CHECK(fgets(buf, nsize, f), "Failed to read clause\n");
|
||||
|
||||
|
||||
|
||||
temp = buf;
|
||||
while (*temp == ' ') temp++;
|
||||
|
||||
bool empty = true;
|
||||
bool tr = true;
|
||||
while (*temp != '\n') {
|
||||
if (cnt == cap) {
|
||||
u32 ncap = cap << 1U;
|
||||
c->variables = realloc(c->variables, sizeof(u32) * ncap);
|
||||
memset(c->variables + cap, 0, sizeof(u32) * cap);
|
||||
CHECK(c->variables, "Failed to realloc variable array\n");
|
||||
c->clauses = realloc(c->clauses, sizeof(u32) * ncap);
|
||||
memset(c->clauses + cap, 0, sizeof(u32) * cap);
|
||||
CHECK(c->clauses, "Failed to realloc clause array\n");
|
||||
c->pars = realloc(c->pars, sizeof(u8) * ncap);
|
||||
memset(c->pars + cap, 0, sizeof(u8) * cap);
|
||||
CHECK(c->pars, "Failed to realloc parity array\n");
|
||||
cap = ncap;
|
||||
}
|
||||
|
||||
if (*temp == '-') {
|
||||
tr = false;
|
||||
} else if (((u8) (*temp - '0')) < 10) {
|
||||
c->variables[cnt] *= 10;
|
||||
c->variables[cnt] += (*temp - '0');
|
||||
} else {
|
||||
while (temp[1] == ' ') temp++;
|
||||
c->pars[cnt] = tr;
|
||||
c->clauses[cnt] = i;
|
||||
c->variables[cnt] -= 1;
|
||||
if (c->lastvars[i] < c->variables[cnt]) c->lastvars[i] = c->variables[cnt];
|
||||
empty = false;
|
||||
tr = true;
|
||||
cnt++;
|
||||
if (temp[1] == '0') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
temp++;
|
||||
}
|
||||
|
||||
if (empty) {
|
||||
printf("UNSAT: Empty clause %u\n", i);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
for (u32 i = 0; i < c->clausecnt; ++i) {
|
||||
c->lastvars[i] += 1U;
|
||||
c->lastvars[i] = c->varcnt - c->lastvars[i];
|
||||
}
|
||||
|
||||
c->litcnt = cnt;
|
||||
|
||||
c->variables = realloc(c->variables, sizeof(u32) * c->litcnt);
|
||||
c->clauses = realloc(c->clauses, sizeof(u32) * c->litcnt);
|
||||
c->pars = realloc(c->pars, sizeof(u8) * c->litcnt);
|
||||
free(buf);
|
||||
if (fclose(f)) {
|
||||
printf("Failed to close file\n");
|
||||
return NULL;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
void printcnf(cnf* c) {
|
||||
printf("p cnf %u %u\n", c->varcnt, c->clausecnt);
|
||||
u32 pclause = 0;
|
||||
for (u32 i = 0; i < c->litcnt; ++i) {
|
||||
if (c->clauses[i] != pclause) printf("0\n");
|
||||
if (c->pars[i] == 0) printf("-");
|
||||
printf("%u ", c->variables[i] + 1);
|
||||
pclause = c->clauses[i];
|
||||
}
|
||||
printf("0\n");
|
||||
}
|
||||
|
||||
void freecnf(cnf* c) {
|
||||
free(c->pars);
|
||||
free(c->clauses);
|
||||
free(c->variables);
|
||||
free(c->lastvars);
|
||||
free(c);
|
||||
}
|
||||
|
||||
const u64 RBITS = 8;
|
||||
const u64 RSIZE = 1LU << RBITS;
|
||||
const u64 RLVLS = (63LU / RBITS) + 1;
|
||||
const u64 RMASK = RSIZE - 1;
|
||||
|
||||
// Currently sorting array of program pointers by the score of the programs
|
||||
// I need to sort by lastvar, within that sort by clause
|
||||
|
||||
void sortlastnum(cnf* c, u64 N) {
|
||||
bool v = false;
|
||||
u32* d = malloc(sizeof(u32) * c->litcnt);
|
||||
u32* d2 = malloc(sizeof(u32) * c->litcnt);
|
||||
u8* d3 = malloc(sizeof(u8) * c->litcnt);
|
||||
|
||||
u64 qb[RLVLS * RSIZE];
|
||||
u64 qe[RLVLS * RSIZE];
|
||||
memset(qb, 0, sizeof(u64) * RLVLS * RSIZE);
|
||||
memset(qe, 0, sizeof(u64) * RLVLS * RSIZE);
|
||||
|
||||
for (u64 pass = 0; pass < RLVLS; ++pass) {
|
||||
u64 shift = pass * RBITS;
|
||||
|
||||
for (u64 i = 0; i < N; ++i) {
|
||||
u32 val = UINT32_MAX - c->lastvars[(c->clausecnt - 1) - c->clauses[i]];
|
||||
u64 ind = (val >> shift) & RMASK;
|
||||
qe[pass * RSIZE + ind]++;
|
||||
}
|
||||
|
||||
u64 uc = 0;
|
||||
for (u64 i = 0; i < RSIZE; ++i) if (qe[pass * RSIZE + i]) uc++;
|
||||
if (uc == 1) continue;
|
||||
|
||||
qb[pass * RSIZE] = 0;
|
||||
for (u64 i = 1; i < RSIZE; ++i) {
|
||||
qb[pass * RSIZE + i] = qb[pass * RSIZE + i - 1] + qe[pass * RSIZE + i - 1];
|
||||
}
|
||||
|
||||
for (u64 i = 0; i < N; ++i) {
|
||||
u32 val = UINT32_MAX - c->lastvars[(c->clausecnt - 1) - c->clauses[i]];
|
||||
u64 ind = (val >> shift) & RMASK;
|
||||
d[qb[pass * RSIZE + ind]] = c->variables[i];
|
||||
d2[qb[pass * RSIZE + ind]] = c->clauses[i];
|
||||
d3[qb[pass * RSIZE + ind]] = c->pars[i];
|
||||
qb[pass * RSIZE + ind]++;
|
||||
__builtin_prefetch(d + qb[pass * RSIZE + ind] + 1);
|
||||
__builtin_prefetch(d2 + qb[pass * RSIZE + ind] + 1);
|
||||
__builtin_prefetch(d3 + qb[pass * RSIZE + ind] + 1);
|
||||
}
|
||||
|
||||
u32* tptr = c->variables;
|
||||
c->variables = d;
|
||||
d = tptr;
|
||||
tptr = c->clauses;
|
||||
c->clauses = d2;
|
||||
d2 = tptr;
|
||||
u8* tptr2 = c->pars;
|
||||
c->pars = d3;
|
||||
d3 = tptr2;
|
||||
v = !v;
|
||||
}
|
||||
|
||||
if (v) {
|
||||
u32* tptr = c->variables;
|
||||
c->variables = d;
|
||||
d = tptr;
|
||||
tptr = c->clauses;
|
||||
c->clauses = d2;
|
||||
d2 = tptr;
|
||||
u8* tptr2 = c->pars;
|
||||
c->pars = d3;
|
||||
d3 = tptr2;
|
||||
memcpy(c->variables, d, N * sizeof(u32));
|
||||
memcpy(c->clauses, d2, N * sizeof(u32));
|
||||
memcpy(c->pars, d3, N * sizeof(u8));
|
||||
}
|
||||
free(d);
|
||||
free(d2);
|
||||
free(d3);
|
||||
|
||||
u32* swaparr = malloc(sizeof(u32) * c->clausecnt);
|
||||
for (u32 i = 0; i < c->clausecnt; ++i) {
|
||||
swaparr[i] = i;
|
||||
}
|
||||
|
||||
v = false;
|
||||
d = malloc(sizeof(u32) * c->clausecnt);
|
||||
|
||||
memset(qb, 0, sizeof(u64) * RLVLS * RSIZE);
|
||||
memset(qe, 0, sizeof(u64) * RLVLS * RSIZE);
|
||||
|
||||
for (u64 pass = 0; pass < RLVLS; ++pass) {
|
||||
u64 shift = pass * RBITS;
|
||||
|
||||
for (u64 i = 0; i < c->clausecnt; ++i) {
|
||||
u32 val = UINT32_MAX - c->lastvars[swaparr[i]];
|
||||
u64 ind = (val >> shift) & RMASK;
|
||||
qe[pass * RSIZE + ind]++;
|
||||
}
|
||||
|
||||
u64 uc = 0;
|
||||
for (u64 i = 0; i < RSIZE; ++i) if (qe[pass * RSIZE + i]) uc++;
|
||||
if (uc == 1) continue;
|
||||
|
||||
qb[pass * RSIZE] = 0;
|
||||
for (u64 i = 1; i < RSIZE; ++i) {
|
||||
qb[pass * RSIZE + i] = qb[pass * RSIZE + i - 1] + qe[pass * RSIZE + i - 1];
|
||||
}
|
||||
|
||||
for (u64 i = 0; i < c->clausecnt; ++i) {
|
||||
u32 val = UINT32_MAX - c->lastvars[swaparr[i]];
|
||||
u64 ind = (val >> shift) & RMASK;
|
||||
d[qb[pass * RSIZE + ind]] = swaparr[i];
|
||||
qb[pass * RSIZE + ind]++;
|
||||
__builtin_prefetch(d + qb[pass * RSIZE + ind] + 1);
|
||||
}
|
||||
|
||||
u32* tptr = swaparr;
|
||||
swaparr = d;
|
||||
d = tptr;
|
||||
v = !v;
|
||||
}
|
||||
|
||||
if (v) {
|
||||
u32* tptr = swaparr;
|
||||
swaparr = d;
|
||||
d = tptr;
|
||||
memcpy(swaparr, d, c->clausecnt * sizeof(u32));
|
||||
}
|
||||
//free(d);
|
||||
|
||||
for (uint i = 0; i < c->clausecnt; ++i) {
|
||||
d[swaparr[i]] = i;
|
||||
}
|
||||
|
||||
for (uint i = 0; i < c->litcnt; ++i) {
|
||||
c->clauses[i] = d[c->clauses[i]];
|
||||
}
|
||||
|
||||
for (uint i = 0; i < c->clausecnt; ++i) {
|
||||
swaparr[d[i]] = c->lastvars[i];
|
||||
}
|
||||
|
||||
memcpy(c->lastvars, swaparr, sizeof(u32) * c->clausecnt);
|
||||
free(swaparr);
|
||||
free(d);
|
||||
}
|
||||
Reference in New Issue
Block a user