CSFLOC rewrite

Signed-off-by: gothictomato <gothictomato@pm.me>
This commit is contained in:
gothictomato
2022-09-04 10:52:28 -04:00
parent e2b633c802
commit 53a580d0ec
9 changed files with 761 additions and 228 deletions

View File

@@ -1 +1,664 @@
#include "cpusolver.h"
#include "csflocref.h"
static inline void stateaddpow(uint wcnt, uint* state, uint pow) {
uint corpow = pow & 0b11111U;
uint startind = pow >> 5U;
uint tr = 1U << corpow;
uint tval = state[startind] + tr;
bool carry = tval < state[startind];
state[startind] = tval;
if (carry) {
uint i = startind + 1;
for ( ; i < wcnt; ++i) {
state[i]++;
if (state[i]) break;
}
}
}
#define DEBUGSAT
#define ADD (0)
#define CMP (1)
#define BCT (2)
#define CHK (3)
void ctrthings3(cnf* c, u32* state, u32* ctr, const u32* max) {
u32 varcnt = c->cnts[0];
u32 clausecnt = c->cnts[1];
u32 wcnt = 1U + (varcnt >> 5U);
u32* mode = state;
u32* index = state + 1;
u32* addval = state + 2;
// printf("> %u %u %u %u %u\n", *mode, *index, *addval, *ctr, *max);
u8 addmode = (*mode == ADD);
u8 cmpmode = (*mode == CMP);
u8 bctmode = (*mode == BCT);
u8 submode = (*mode == CHK);
// 1 mask for if in subcheck mode, 1 for if not
u32 submask = 0xFFFFFFFFU * submode;
u32 nsubmask = ~submask;
u32 addmask = 0xFFFFFFFFU * addmode;
u32 naddmask = ~addmask;
/* subcheck */
// used to find correct ctr index
u32 varcor = varcnt - 1;
// Mask to prevent oob accesses for when (varcnt / 32) > clausecnt (or smth like that)
u32 currclause = *index & submask;
// clausedat records are 3 words long, multiply index by 3
u32 currclauseshifted = currclause * 3U;
// Retrieve beginning index of clause, add current var index
u32 currvarind = c->clausedat[currclauseshifted] + (*addval & submask);
// Retrieve current var & parity
u32 currvar = c->variables[currvarind];
u8 corrpar = c->parities[currvarind];
// Calculate index in ctr
u32 currvarcorr = (varcor - currvar);
u32 currvarword = currvarcorr >> 5U;
u32 currvarbit = currvarcorr & 0b11111U;
/* Can we make there be 1 ctr read per iteration? */
// If in sub mode, retrieve current var's bit, else return ctr[*index]
u32 ctrind = (currvarword & submask) | (*index & nsubmask);
u32 ctrval = ctr[ctrind];
u32 maxval = max[*index & nsubmask];
// Extract parity bit from ctr
u32 currpar = (ctrval >> currvarbit) & 1U;
// Check if assignment parity matches clause parity
u8 subvalid = currpar == corrpar;
// Don't mask addval because it's not being used for a lookup
u8 islvar = c->clausedat[currclauseshifted + 1U] == (*addval + 1);
u32 jval = c->clausedat[currclauseshifted + 2U];
u32 jword = jval >> 5U;
u32 jbit = 1U << (jval & 0b11111U);
u8 islclause = (clausecnt - 1) <= *index;
u8 endOfCtr = (ctrind == (wcnt - 1));
u8 begOfCtr = (ctrind == 0);
/* add */
u32 nctr = ctrval + *addval;
u8 addoverflow = (nctr < ctrval);
/* cmp */
u8 cmpresult = -(ctrval < maxval);
cmpresult += (ctrval > maxval);
u8 cmpnores = cmpresult == 0;
u8 cmpisless = cmpresult == 255U;
/* bitcnt */
u32 bitcntval = (ctrval & -ctrval);
u32 bitcnt = ((bitcntval & 0x0000FFFFU) != 0) << 4U;
bitcnt |= ((bitcntval & 0x00FF00FF) != 0) << 3U;
bitcnt |= ((bitcntval & 0x0F0F0F0F) != 0) << 2U;
bitcnt |= ((bitcntval & 0x33333333) != 0) << 1U;
bitcnt |= (bitcntval & 0x55555555) != 0;
bitcnt += bitcntval != 0;
bitcntval = 32 - bitcnt;
u8 ctrWordIsZero = ctrval == 0;
// Set current ctr word
// If in add mode, update ctr val, otherwise leave unchanged
ctr[ctrind] = (nctr & addmask) | (ctr[ctrind] & naddmask);
// Set current index
/*
* jword : (subcheck & valid & lastvar)
* index : (subcheck & valid & !lastvar) | (add & (!addoverflow | endOfCtr))
* index + 1 : (subcheck & !valid) | (add & (addoverflow & !endOfCtr)) | (bitcnt & ctrWordIsZero & !endOfCtr)
* index - 1 : (cmp & cmpnores & !begOfCtr)
* 0 : (cmp & (!cmpnores | begOfCtr))
* index[addoverflow + bitcntval] : (bitcnt & (!ctrWordIsZero | endOfCtr)
*/
u32 tempA = submode & (subvalid & islvar);
// if (submode & (subvalid & islvar)) fprintf(iofile, "j: %u\n", jval);
u32 tempB = (submode & (subvalid & !islvar));
u32 tempC = (submode & !subvalid) | (addmode & (addoverflow & !endOfCtr)) | (bctmode & (ctrWordIsZero & !endOfCtr));
u32 tempD = (cmpmode & (cmpnores & !begOfCtr));
u32 tempE = (addmode & (!addoverflow | endOfCtr));
u32 tempF = (bctmode & (!ctrWordIsZero | endOfCtr));
tempA *= jword;
tempB *= *index;
tempC *= (*index + 1);
tempD *= (*index - 1);
tempE *= (wcnt - 1);
u32 indexval = (*addval + bitcntval);
u8 indexcmp = indexval < varcnt;
indexval = indexval * indexcmp + (varcnt - 1) * (!indexcmp);
tempF *= c->index[((indexval) * bctmode)];
// if (bctmode & (!ctrWordIsZero | endOfCtr)) fprintf(iofile,"z: %u %u\n", (indexval), c->index[((indexval) * bctmode)]);
*index = tempA | tempB | tempC | tempD | tempE | tempF;
tempA = submode & (subvalid & islvar);
tempB = (submode & (subvalid & !islvar));
tempC = (addmode & (addoverflow & !endOfCtr));
tempD = (bctmode & (ctrWordIsZero & !endOfCtr));
tempA *= (jbit);
tempB *= (*addval + 1);
tempC *= (addoverflow);
tempD *= (*addval + 32);
*addval = tempA | tempB | tempC | tempD;
/*
* 1 << jbit : (subcheck & valid & lastvar)
* addval + 1 : (subcheck & valid & !lastvar)
* 0 : (subcheck & !valid) | (add & (!addoverflow | endOfCtr)) | (cmp) | (bitcnt & (!ctrWordIsZero | endOfCtr)
* addoverflow : (add & (addoverflow & !endOfCtr))
* addoverflow + 32 : (bitcnt & ctrWordIsZero & !endOfCtr)
*
*/
/*
* SAT : (subcheck & !valid & lastclause)
* UNSAT : (cmp & (!cmpnores | begOfCtr)) & !cmpisless
*/
u8 issat = (submode & ((!subvalid) & islclause));
u8 isusat = (cmpmode & ((!cmpnores) | begOfCtr)) & (!cmpisless);
u8 isdone = issat | isusat;
*mode += isdone << 2U;
*index ^= (*index * isdone);
*index += issat;
/*
if (isdone) {
*mode = 9;
*index = issat;
// printf("%u\n", issat);
}
*/
/*
* ADD : (add & (!addoverflow | endOfCtr))
* CMP : (cmp & (!cmpnores | begOfCtr))
* BCT : (bitcnt & (!ctrWordIsZero | endOfCtr))
* CHK : (subcheck & valid & lastvar)
*/
tempA = (addmode & (!addoverflow | endOfCtr));
tempB = (cmpmode & (!cmpnores | begOfCtr));
tempC = (bctmode & (!ctrWordIsZero | endOfCtr));
tempD = (submode & (subvalid & islvar));
*mode += tempA | tempB | tempC;
*mode -= (tempD * 3);
}
void ctrthings4(cnf* c, u32* state, u32* ctr, const u32* max, FILE* iofile) {
u32 varcnt = c->cnts[0];
u32 clausecnt = c->cnts[1];
u32 wcnt = 1U + (varcnt >> 5U);
u32* mode = state;
u32* index = state + 1;
u32* addval = state + 2;
// printf("> %u %u %u %u %u\n", *mode, *index, *addval, *ctr, *max);
u8 addmode = (*mode == ADD);
u8 cmpmode = (*mode == CMP);
u8 bctmode = (*mode == BCT);
u8 submode = (*mode == CHK);
// 1 mask for if in subcheck mode, 1 for if not
u32 submask = -submode;
u32 nsubmask = ~submask;
u32 addmask = -addmode;
u32 naddmask = ~addmask;
/* subcheck */
// used to find correct ctr index
u32 varcor = varcnt - 1;
// Mask to prevent oob accesses for when (varcnt / 32) > clausecnt (or smth like that)
u32 currclause = *index & submask;
// clausedat records are 3 words long, multiply index by 3
u32 currclauseshifted = currclause * 3U;
// Retrieve beginning index of clause, add current var index
u32 currvarind = c->clausedat[currclauseshifted] + (*addval & submask);
// Retrieve current var & parity
u32 currvar = c->variables[currvarind];
u8 corrpar = c->parities[currvarind];
// Calculate index in ctr
u32 currvarcorr = (varcor - currvar);
u32 currvarword = currvarcorr >> 5U;
u32 currvarbit = currvarcorr & 0b11111U;
/* Can we make there be 1 ctr read per iteration? */
// If in sub mode, retrieve current var's bit, else return ctr[*index]
u32 ctrind = (currvarword & submask) | (*index & nsubmask);
u32 ctrval = ctr[ctrind];
u32 maxval = max[*index & nsubmask];
// Extract parity bit from ctr
u32 currpar = (ctrval >> currvarbit) & 1U;
// Check if assignment parity matches clause parity
u8 subvalid = currpar == corrpar;
// Don't mask addval because it's not being used for a lookup
u8 islvar = c->clausedat[currclauseshifted + 1U] == (*addval + 1);
u32 jval = c->clausedat[currclauseshifted + 2U];
u32 jword = jval >> 5U;
u32 jbit = 1U << (jval & 0b11111U);
u8 islclause = (clausecnt - 1) <= *index;
u8 endOfCtr = (ctrind == (wcnt - 1));
u8 begOfCtr = (ctrind == 0);
/* add */
u32 nctr = ctrval + *addval;
u8 addoverflow = (nctr < ctrval);
/* cmp */
u8 cmpresult = -(ctrval < maxval);
cmpresult += (ctrval > maxval);
u8 cmpnores = cmpresult == 0;
u8 cmpisless = cmpresult == 255U;
/* bitcnt */
u32 bitcntval = (ctrval & -ctrval);
u32 bitcnt = ((bitcntval & 0x0000FFFFU) != 0) << 4U;
bitcnt |= ((bitcntval & 0x00FF00FF) != 0) << 3U;
bitcnt |= ((bitcntval & 0x0F0F0F0F) != 0) << 2U;
bitcnt |= ((bitcntval & 0x33333333) != 0) << 1U;
bitcnt |= (bitcntval & 0x55555555) != 0;
bitcnt += bitcntval != 0;
bitcntval = 32 - bitcnt;
u8 ctrWordIsZero = ctrval == 0;
// Set current ctr word
// If in add mode, update ctr val, otherwise leave unchanged
ctr[ctrind] = (nctr & addmask) | (ctr[ctrind] & naddmask);
// Set current index
/*
* jword : (subcheck & valid & lastvar)
* index : (subcheck & valid & !lastvar) | (add & (!addoverflow | endOfCtr))
* index + 1 : (subcheck & !valid) | (add & (addoverflow & !endOfCtr)) | (bitcnt & ctrWordIsZero & !endOfCtr)
* index - 1 : (cmp & cmpnores & !begOfCtr)
* 0 : (cmp & (!cmpnores | begOfCtr))
* index[addoverflow + bitcntval] : (bitcnt & (!ctrWordIsZero | endOfCtr)
*/
u32 tempA = -(submode & (subvalid & islvar));
if (submode & (subvalid & islvar)) fprintf(iofile, "j: %u\n", jval);
u32 tempB = -(submode & (subvalid & !islvar));
u32 tempC = -((submode & !subvalid) | (addmode & (addoverflow & !endOfCtr)) | (bctmode & (ctrWordIsZero & !endOfCtr)));
u32 tempD = -(cmpmode & (cmpnores & !begOfCtr));
u32 tempE = -(addmode & (!addoverflow | endOfCtr));
u32 tempF = -(bctmode & (!ctrWordIsZero | endOfCtr));
tempA &= jword;
tempB &= *index;
tempC &= (*index + 1);
tempD &= (*index - 1);
tempE &= (wcnt - 1);
u32 indexval = (*addval + bitcntval);
u32 indexcmp = -(indexval < varcnt);
indexval = (indexval & indexcmp) | ((varcnt - 1) & (~indexcmp));
tempF &= c->index[((indexval) * bctmode)];
if (bctmode & (!ctrWordIsZero | endOfCtr)) fprintf(iofile,"z: %u %u\n", (indexval), c->index[((indexval) * bctmode)]);
*index = tempA | tempB | tempC | tempD | tempE | tempF;
tempA = -(submode & (subvalid & islvar));
tempB = -(submode & (subvalid & !islvar));
tempC = -(addmode & (addoverflow & !endOfCtr));
tempD = -(bctmode & (ctrWordIsZero & !endOfCtr));
tempA &= (jbit);
tempB &= (*addval + 1);
tempC &= (addoverflow);
tempD &= (*addval + 32);
*addval = tempA | tempB | tempC | tempD;
/*
* 1 << jbit : (subcheck & valid & lastvar)
* addval + 1 : (subcheck & valid & !lastvar)
* 0 : (subcheck & !valid) | (add & (!addoverflow | endOfCtr)) | (cmp) | (bitcnt & (!ctrWordIsZero | endOfCtr)
* addoverflow : (add & (addoverflow & !endOfCtr))
* addoverflow + 32 : (bitcnt & ctrWordIsZero & !endOfCtr)
*
*/
/*
* SAT : (subcheck & !valid & lastclause)
* UNSAT : (cmp & (!cmpnores | begOfCtr)) & !cmpisless
*/
u8 issat = (submode & ((!subvalid) & islclause));
u8 isusat = (cmpmode & ((!cmpnores) | begOfCtr)) & (!cmpisless);
u32 isdone = -(issat | isusat);
*mode |= isdone;
*index ^= (*index & isdone);
*index += issat;
/*
if (isdone) {
*mode = 9;
*index = issat;
// printf("%u\n", issat);
}
*/
/*
* ADD : (add & (!addoverflow | endOfCtr))
* CMP : (cmp & (!cmpnores | begOfCtr))
* BCT : (bitcnt & (!ctrWordIsZero | endOfCtr))
* CHK : (subcheck & valid & lastvar)
*/
tempA = (addmode & (!addoverflow | endOfCtr));
tempB = (cmpmode & (!cmpnores | begOfCtr));
tempC = (bctmode & (!ctrWordIsZero | endOfCtr));
tempD = (submode & (subvalid & islvar));
*mode += tempA | tempB | tempC;
*mode -= (tempD * 3);
}
void ctrthings5(cnf* c, u32* state, u32* ctr, const u32* max) {
u32 varcnt = c->cnts[0];
u32 clausecnt = c->cnts[1];
u32 wcnt = 1U + (varcnt >> 5U);
u32* mode = state;
u32* index = state + 1;
u32* addval = state + 2;
// printf("> %u %u %u %u %u\n", *mode, *index, *addval, *ctr, *max);
u8 addmode = (*mode == ADD);
u8 cmpmode = (*mode == CMP);
u8 bctmode = (*mode == BCT);
u8 submode = (*mode == CHK);
// 1 mask for if in subcheck mode, 1 for if not
u32 submask = -submode;
u32 nsubmask = ~submask;
u32 addmask = -addmode;
u32 naddmask = ~addmask;
/* subcheck */
// used to find correct ctr index
u32 varcor = varcnt - 1;
// Mask to prevent oob accesses for when (varcnt / 32) > clausecnt (or smth like that)
u32 currclause = *index & submask;
// clausedat records are 3 words long, multiply index by 3
u32 currclauseshifted = currclause * 3U;
// Retrieve beginning index of clause, add current var index
u32 currvarind = c->clausedat[currclauseshifted] + (*addval & submask);
// Retrieve current var & parity
u32 currvar = c->variables[currvarind];
u8 corrpar = c->parities[currvarind];
// Calculate index in ctr
u32 currvarcorr = (varcor - currvar);
u32 currvarword = currvarcorr >> 5U;
u32 currvarbit = currvarcorr & 0b11111U;
/* Can we make there be 1 ctr read per iteration? */
// If in sub mode, retrieve current var's bit, else return ctr[*index]
u32 ctrind = (currvarword & submask) | (*index & nsubmask);
u32 ctrval = ctr[ctrind];
u32 maxval = max[*index & nsubmask];
// Extract parity bit from ctr
u32 currpar = (ctrval >> currvarbit) & 1U;
// Check if assignment parity matches clause parity
u8 subvalid = currpar == corrpar;
// Don't mask addval because it's not being used for a lookup
u8 islvar = c->clausedat[currclauseshifted + 1U] == (*addval + 1);
u32 jval = c->clausedat[currclauseshifted + 2U];
u32 jword = jval >> 5U;
u32 jbit = 1U << (jval & 0b11111U);
u8 islclause = (clausecnt - 1) <= *index;
u8 endOfCtr = (ctrind == (wcnt - 1));
u8 begOfCtr = (ctrind == 0);
/* add */
u32 nctr = ctrval + *addval;
u8 addoverflow = (nctr < ctrval);
/* cmp */
u8 cmpresult = -(ctrval < maxval);
cmpresult += (ctrval > maxval);
u8 cmpnores = cmpresult == 0;
u8 cmpisless = cmpresult == 255U;
/* bitcnt */
u32 bitcntval = (ctrval & -ctrval);
u32 bitcnt = ((bitcntval & 0x0000FFFFU) != 0) << 4U;
bitcnt |= ((bitcntval & 0x00FF00FF) != 0) << 3U;
bitcnt |= ((bitcntval & 0x0F0F0F0F) != 0) << 2U;
bitcnt |= ((bitcntval & 0x33333333) != 0) << 1U;
bitcnt |= (bitcntval & 0x55555555) != 0;
bitcnt += bitcntval != 0;
bitcntval = 32 - bitcnt;
u8 ctrWordIsZero = ctrval == 0;
// Set current ctr word
// If in add mode, update ctr val, otherwise leave unchanged
ctr[ctrind] = (nctr & addmask) | (ctr[ctrind] & naddmask);
// Set current index
u32 tempA = -(submode & (subvalid & islvar));
u32 tempB = -(submode & (subvalid & !islvar));
u32 tempC = -((submode & !subvalid) | (addmode & (addoverflow & !endOfCtr)) | (bctmode & (ctrWordIsZero & !endOfCtr)));
u32 tempD = -(cmpmode & (cmpnores & !begOfCtr));
u32 tempE = -(addmode & (!addoverflow | endOfCtr));
u32 tempF = -(bctmode & (!ctrWordIsZero | endOfCtr));
tempA &= jword;
tempB &= *index;
tempC &= (*index + 1);
tempD &= (*index - 1);
tempE &= (wcnt - 1);
u32 indexval = (*addval + bitcntval);
u32 indexcmp = -(indexval < varcnt);
indexval = (indexval & indexcmp) | ((varcnt - 1) & (~indexcmp));
tempF &= c->index[((indexval) * bctmode)];
*index = tempA | tempB | tempC | tempD | tempE | tempF;
tempA = -(submode & (subvalid & islvar));
tempB = -(submode & (subvalid & !islvar));
tempC = -(addmode & (addoverflow & !endOfCtr));
tempD = -(bctmode & (ctrWordIsZero & !endOfCtr));
tempA &= (jbit);
tempB &= (*addval + 1);
tempC &= (addoverflow);
tempD &= (*addval + 32);
*addval = tempA | tempB | tempC | tempD;
/* completion detection */
u8 issat = (submode & ((!subvalid) & islclause));
u8 isusat = (cmpmode & ((!cmpnores) | begOfCtr)) & (!cmpisless);
u32 isdone = -(issat | isusat);
/* exit */
*mode |= isdone;
*index ^= (*index & isdone);
*index += issat;
tempA = (addmode & (!addoverflow | endOfCtr));
tempB = (cmpmode & (!cmpnores | begOfCtr));
tempC = (bctmode & (!ctrWordIsZero | endOfCtr));
tempD = (submode & (subvalid & islvar));
*mode += tempA | tempB | tempC;
*mode -= (tempD * 3);
}
/** NOTES:
* First thing's first is indexing, let's get started with that.
*
*
*
*
*
*/
void ctrthings2(cnf* c, u32* state, u32* ctr, const u32* max, FILE* iofile) {
// Pre-actual work setup stuff
u32 wcnt = 1U + (c->cnts[0] >> 5U); // number of words we need (bitcnt + 1 ceiling divided by 32)
u32* mode = state; // Make pointers to array values for convenience so I don't need to refer to everything via array indices
u32* index = state + 1; // tbh the names aren't much better
u32* addval = state + 2;
u32 varcnt = c->cnts[0] - 1; // (varcnt - 1) - v gives us the bit index of variable v in the ctr
u32 chkmsk = 0xFFFFFFFFU * (*mode == (2)); // Create a mask that zeros anything if we aren't in subsumption-check mode, to prevent out of bounds accesses
u32 chkcls = *index & chkmsk; // Use said mask to zero the index if we're not in check mode
u32 chkind = c->clausedat[3 * chkcls] + (*addval & chkmsk); // potentially zeroed index to lookup clause start, add potentially zeroed variable index in that clause
u32 var = c->variables[chkind]; // Retrieve variable at that index
u8 par = c->parities[chkind]; // Retrieve the variable's CNF parity
u32 vword = (varcnt - var) >> 5U; // As mentioned in the varcnt line, compute word index of var in ctr
u32 vbit = (varcnt - var) & 0b11111U; // Compute bit index of var in above ctr word
u8 corpar = (ctr[vword] >> vbit) & 1U; // Extract correct parity
u8 isvalid = (par == corpar); // Check if CNF parity equals assignment parity from ctr
u8 islvar = ((*addval + 1) == c->clausedat[3 * chkcls + 1]); // Check if this is the last variable of the clause
u8 isbchk0 = (*mode == (2)); // If in check mode
u8 isbchk1 = isbchk0 & isvalid; // If in check mode & valid
u8 isbchk2 = isbchk1 & islvar; // If in check mode, valid, and on the last var
u32 j = c->clausedat[3 * chkcls + 2]; // retrieve j val for current clause
*mode -= 2 * isbchk2; // If isbchk2, move to add mode
#ifdef DEBUGSAT
if (isbchk2) fprintf(iofile,"j: %u\n", j);
#endif
*index = (j >> 5U) * isbchk2 + *index * (!isbchk2); // if isbchk2, set index for the jval to be added
*addval = (1U << (j & 0b11111U)) * isbchk2 + *addval * (!isbchk2); // if isbchk, set addval for the jval to be added;
*addval += ((isbchk1) & (!islvar)); // If in check mode, valid, and not on the last var, move to the next var
u8 isbchk3 = (isbchk0 & (!isvalid)); // if in check mode and not valid, move to the next clause
*addval *= (!isbchk3); // if moving to next clause, go to 0th var of that clause
*index += (isbchk3); // actually moving to the next clause
u8 issat = (*index == c->cnts[1]) * (isbchk3); // if we just passed the last clause, none were valid, so our assignment is SAT
u32 cmpaddind = *index * (*mode != (2)); // Zero index into ctr if in check mode, to prevent out of bounds accesses
u32 nval = ctr[cmpaddind] + *addval; // Find the result of the current step if it was addition
*addval = (nval < ctr[cmpaddind]) * (*mode == (0)) + (*addval) * (*mode == (2)); // If in add mode, set addval to carry. If in cmp mode, set to 0. If in check mode, leave alone.
ctr[cmpaddind] = nval * ((*mode == (0)) & !issat) + ctr[cmpaddind] * ((*mode != (0)) | issat); // If in add mode, set new ctr val, otherwise leave unchanged
*addval -= (ctr[cmpaddind] < max[cmpaddind]) * (*mode == (1)); // If in comparison mode, decrement addval if less than
*addval += (ctr[cmpaddind] > max[cmpaddind]) * (*mode == (1)); // If in comparison mode, increment addval if greater than
u8 addcond = (*addval == 0) | (cmpaddind == (wcnt - 1)); // Exit condition for the ADD state: If addval is zero (no carry) or we're at the last word
u8 cmpcond = (*addval != 0) | (cmpaddind == 0); // Exit condition for the CMP state: if addval is nonzero (lt or gt) or we're at the least significant word
u8 exittime = (*mode == (1)) & cmpcond & (*addval != -1);
exittime |= issat;
if (exittime) { // If in cmpmode and the comparison result is not less than, unsat
printf("%u\n", issat);
*mode = 3;
return;
}
u8 cmpdone = cmpcond & (*mode == (1)); // if comparison completion conditions are satisfied and in CMP mode
u32 addindex = (cmpaddind + 1) * !addcond + (cmpaddind) * addcond; // if add completion is satisfied, set index to most significant word, else increment by 1
*index = addindex * (*mode == (0)) + (*index - (*mode == (1))) * (*mode != (0)); // If in add mode, use addindex; if in cmp mode, decrement index by 1
*index *= !cmpdone;
*addval *= !(((addcond) & (*mode == (0))) | cmpdone); // If add is complete, or cmp is complete, zero. Else leave unchanged.
*mode += addcond * (*mode == (0)) + cmpdone; // If in add mode and add completion is reached, increment mode. If in cmp mode and cmp completion reached, increment mode.
}
i32 cpusolve(cnf* c) {
u32 state[3];
u32 wcnt = 1 + (c->cnts[0] >> 5U);
u32* ctr = calloc((wcnt), sizeof(u32));
if (ctr == NULL) {
printf("Failed to allocate solution buffer\n");
exit(1);
}
u32* max = calloc((wcnt), sizeof(u32));
if (max == NULL) {
printf("Failed to allocate solution buffer\n");
exit(1);
}
stateaddpow(wcnt, max, c->cnts[0]);
state[0] = 2;
state[1] = state[2] = 0;
while (state[0] < 4) {
ctrthings5(c, state, ctr, max);
}
free(ctr);
free(max);
return state[1];
}
i32 compareFiles(FILE *file1, FILE *file2){
char ch1 = getc(file1);
char ch2 = getc(file2);
int error = 0, pos = 0, line = 1;
while (ch1 != EOF && ch2 != EOF){
pos++;
if (ch1 == '\n' && ch2 == '\n'){
line++;
pos = 0;
}
if (ch1 != ch2){
error++;
printf("Line Number : %d \tError"
" Position : %d \n", line, pos);
}
ch1 = getc(file1);
ch2 = getc(file2);
}
if (ch1 != EOF || ch2 != EOF) error += 1;
printf("Total Errors : %d\t\n", error);
return error;
}
void debugsolve(char* path) {
FILE* reffile = fopen("temp.txt", "w");
FILE* cmpfile = fopen("temp2.txt", "w");
runcsfloc(path, reffile);
cnf* c = readDIMACS(path);
sortlastnum(c);
u32* state = malloc(sizeof(u32) * 3);
u32 wcnt = 1 + (c->cnts[0] >> 5U);
u32* ctr = calloc((wcnt), sizeof(u32));
if (ctr == NULL) {
printf("Failed to allocate solution buffer\n");
exit(1);
}
u32* max = calloc((wcnt), sizeof(u32));
if (max == NULL) {
printf("Failed to allocate solution buffer\n");
exit(1);
}
stateaddpow(wcnt, max, c->cnts[0]);
state[0] = 2;
state[1] = state[2] = 0;
while (state[0] < 4) {
ctrthings4(c, state, ctr, max, cmpfile);
}
free(ctr);
free(max);
freecnf(c);
fclose(reffile);
fclose(cmpfile);
reffile = fopen("temp.txt", "r");
cmpfile = fopen("temp2.txt", "r");
i32 res = compareFiles(reffile, cmpfile);
if (res != 0) {
printf("%s\n", path);
exit(1);
}
fclose(reffile);
fclose(cmpfile);
free(state);
}